Terraformで全てのリソースにタグを打つ

インフラ担当の柴田です。

皆さんTerraformは使っていますか。

私は主にAWS CloudFormationを使うので、普段はTerraformを使わないのですが、 たまたまTerraformでリソースを作る機会があり、これは神機能と思ったのでブログを書いてみました。

全てのリソースにタグを付けるのは面倒くさい

AWSを利用しているとコスト配分タグのように、全てのリソースに同じタグを付けたいというシチュエーションは多くあります。

しかし、この同じタグを全てのリソースに付けるという作業はなかなか面倒くさく、時々抜けが発生します。

以前のブログでは、CloudFormationのスタックオプションを使えばこの面倒くさいが一気に解決することを紹介しました。

engineers.fenrir-inc.com

しかし、当然この方法はTerraformでは使えないため、Terraformを書く時は面倒くさいと思いながらひたすらタグをコピーしていました。 今回、たまたまドキュメントを読み返しているときに、この面倒くさいを一気に解消する機能が追加されていることに気づきました。

Propagating Tags to All Resources

TerraformのAWSプロバイダーのバージョン3.38.0以降のバージョンでプロバイダーレベルのタグ付けが利用できるようになっています。

詳細は、ドキュメントのPropagating Tags to All Resourcesの項目を読んで頂きたいのですが、providerブロックの中でdefault_tagsブロックを使いタグを定義することで、作成した全てのリソースに同じタグを付けることができます。(一部だけ例外があります。)

試してみる

手元のTerraformが0.12.29だったのですが、その場合AWSプロバイダーの3.38.0が利用できなかったので、まずはTerraform自体のバージョンを1.0.8に更新しました。

後は、下記のテンプレートでVPCとサブネットを作成します。

terraform {
  required_version = "~> 1.0.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.38.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
  default_tags {
    tags = {
      cost  = "tag-test"
      Owner = "a.shibata"
    }
  }
}

resource "aws_vpc" "tagtest" {
  cidr_block           = "192.168.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true
  instance_tenancy     = "default"
  tags = {
    Name = "tag-test-vpc"
  }
}

resource "aws_subnet" "private-a1" {
  vpc_id            = aws_vpc.tagtest.id
  cidr_block        = cidrsubnet(aws_vpc.tagtest.cidr_block, 8, 0)
  availability_zone = "us-east-1a"
  tags = {
    Name = "tag-test-subnet-private-a1"
  }
}
resource "aws_subnet" "public-a1" {
  vpc_id            = aws_vpc.tagtest.id
  cidr_block        = cidrsubnet(aws_vpc.tagtest.cidr_block, 8, 1)
  availability_zone = "us-east-1a"
  tags = {
    Name = "tag-test-subnet-public-a1"
    cost  = "tag-test-2" # costタグの上書き
  }
}

テンプレートをもとにterraform applyを実行すると以下の画像のように、VPCとサブネット両方に共通のOwnercostのタグが設定されていることが確認できました。

f:id:a-shibata_fenrir:20211015172832p:plain
VPCにOwnerとcostタグがセットされた
f:id:a-shibata_fenrir:20211015172829p:plain
サブネットにOwnerとcostタグがセットされた

また、resourceブロックでcostタグに別の値を設定したtag-test-subnet-public-a1では、以下の画像のようにcostタグの値が、resourceブロックで指定したtag-test-2となることが確認できました。

f:id:a-shibata_fenrir:20211015172826p:plain
サブネットのcostタグが上書きされた

まとめ

TerraformのAWSプロバイダーのバージョン3.38.0以降のバージョンでは、providerブロックでdefault_tagsを設定することで、全てのリソースに共通したタグを付けることができます。 特定のリソースだけ別の値にしたい場合は、resourceブロックでタグを指定することでproviderブロックで定義したタグを上書きすることも可能です。