AWSマルチAZリソースのタグ付け戦略をTerraformで実装する方法|default_tags・モジュール設計

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > AWS(Amazon Linux) > AWSマルチAZリソースのタグ付け戦略をTerraformで実装する方法|default_tags・モジュール設計
「Terraformでインフラを管理しているのに、AWSリソースのタグが担当者によってバラバラになる」「環境タグの表記ゆれで、Cost Explorerのコスト集計が正確に出ない」

タグ付けの問題は設計より先に「付ける仕組みがない」ことに原因があります。TerraformのProviderにはdefault_tagsというブロックがあり、一箇所に定義するだけで管理下のすべてのAWSリソースに共通タグを自動付与できます。手動のタグ漏れや表記ゆれを構造的に防ぐ方法です。

この記事では、Terraform v1.5以降を想定して、default_tagsを使ったAWSリソースのタグ付け一元管理の手順を解説します。マルチAZ構成のVPC・Subnet・EC2インスタンスへの適用を例に、環境・システム・コスト配分の3軸タグ体系の設計からモジュールを横断したタグ継承の実装まで説明します。

この記事のポイント

・aws providerのdefault_tagsで全リソースに共通タグを自動付与できる
・環境・システム・コスト配分の3軸タグ体系でCost Explorer精度が向上する
・variablesとtfvarsを組み合わせてAZ別リソースのタグを一貫管理できる
・tags = {}上書きによってdefault_tagsが消えるトラブルへの対処法も解説する


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜAWSのタグ付けはチームで統一しづらいのか

AWSのタグ付けは任意機能ですが、コスト配分・リソース検索・セキュリティポリシー適用のためには実質必須です。しかし次のような理由でチーム内での統一が難しくなりがちです。

・手動作業のばらつき:マネジメントコンソールから個別にリソースを作ると、担当者ごとにタグキーの大文字小文字や値の表記が異なります(例:「env」と「Env」、「prod」と「production」)
・Terraform管理でも漏れる:resource定義にtags = {}ブロックを各自で書くスタイルでは、新しいリソースを追加するたびに書き忘れが起きます
・タグ後付けのコスト:設計後にタグを追加しようとすると、既存リソースへの一括適用が必要になり、作業量が増えます

Terraformのdefault_tagsはこの問題を「書かなくてもタグが付く」構造に変えます。

TerraformのProvider default_tagsで全リソースにタグを付ける

default_tagsはTerraform AWS Providerのv3.38.0から利用できる機能です。Providerブロックに一度設定すれば、そのProvider設定を使うすべてのAWSリソースにタグが自動付与されます。

1. provider設定でdefault_tagsブロックを定義する

Providerの設定ファイル(通常はprovider.tf)に次のように書きます。

# provider.tf(設定例) terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = var.aws_region default_tags { tags = { Project = var.project_name Environment = var.environment ManagedBy = "Terraform" CostCenter = var.cost_center } } }

このProviderを使うすべてのリソース(VPC・Subnet・EC2・RDS等)に、Project・Environment・ManagedBy・CostCenterの4タグが自動付与されます。変数ファイルでproject_nameとenvironmentを環境ごとに切り替えれば、dev/stg/prodで別々のタグを付けられます。

2. リソース側でタグを追加・上書きする

default_tagsはリソース側のtagsブロックとマージされます。リソース固有のタグを追加したい場合は、resource側にそのタグだけを書きます。同じキーを書いた場合はリソース側の値が優先されます(上書き)。

# aws_vpc定義例(設定例) resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_support = true enable_dns_hostnames = true tags = { Name = "${var.project_name}-vpc" Tier = "network" } # default_tagsのProject/Environment/ManagedBy/CostCenterが自動マージされる }

tags = {}と空にするとdefault_tagsが消えるため、リソース固有タグが不要でもこのブロックは省略するかNameタグだけを書く方針にします(後述のトラブルシュートも参照)。

マルチAZ構成の3軸タグ体系を設計する

タグ体系を決めずにdefault_tagsだけ設定しても、コスト集計や検索の精度は上がりません。マルチAZ構成では次の3軸を基本に設計します。

1. 環境・システム・コスト配分の3軸を定義する

・環境軸(Environment):dev / stg / prod。Cost Explorerでの環境別コスト分析の基軸になります
・システム軸(Project / Service):システム名またはサービス名。複数サービスが同一AWSアカウントに共存する場合の分離に使います
・コスト配分軸(CostCenter / Owner):部門コードや担当チームの識別子。Cost Allocation Tagsとして登録しておくことでコスト配分レポートに反映されます

AWS Cost Allocation Tagsを有効化するには、マネジメントコンソールの「Billing and Cost Management」→「Cost allocation tags」でタグキーをアクティベートする必要があります(Terraform外の設定です)。

2. variablesとtfvarsで環境別にタグ値を切り替える

環境ごとにタグ値を切り替えるには、変数ファイルとtfvarsを組み合わせます。

# variables.tf(設定例) variable "aws_region" { description = "AWSリージョン" type = string default = "ap-northeast-1" } variable "project_name" { description = "プロジェクト名(タグに使用)" type = string } variable "environment" { description = "環境名 (dev/stg/prod)" type = string validation { condition = contains(["dev", "stg", "prod"], var.environment) error_message = "environmentはdev・stg・prodのいずれかを指定してください。" } } variable "cost_center" { description = "コスト配分コード" type = string }

# prod.tfvars(本番環境設定例) aws_region = "ap-northeast-1" project_name = "webservice" environment = "prod" cost_center = "cc-infra-01"

変数ファイルを環境ごとに用意(dev.tfvars・prod.tfvars)し、terraform plan -var-file=prod.tfvarsのように切り替えることで、同じTerraformコードベースから環境別のタグを持つリソースを作成できます。

VPC・Subnet・EC2へのタグ付け実装例

1. VPCとSubnetにAZ識別タグを付ける

マルチAZ構成では、Subnetがどのアベイラビリティゾーンに属するかをNameタグとAZタグの両方で明示します。

# network.tf(設定例) resource "aws_vpc" "main" { cidr_block = var.vpc_cidr enable_dns_support = true enable_dns_hostnames = true tags = { Name = "${var.project_name}-vpc" Tier = "network" } } resource "aws_subnet" "public_a" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" availability_zone = "${var.aws_region}a" tags = { Name = "${var.project_name}-public-subnet-1a" Tier = "public" AZ = "${var.aws_region}a" } } resource "aws_subnet" "public_c" { vpc_id = aws_vpc.main.id cidr_block = "10.0.2.0/24" availability_zone = "${var.aws_region}c" tags = { Name = "${var.project_name}-public-subnet-1c" Tier = "public" AZ = "${var.aws_region}c" } }

AZタグを付けておくと、EC2インスタンスのAZ障害時に影響範囲を即座に特定できます。SubnetとAZの対応を目視で確認するだけでなく、AWSリソースグループのタグフィルタでも絞り込めます。

2. EC2インスタンスに役割タグを付ける

EC2インスタンスには、アプリケーション層でのロール(web/api/batch等)をタグで識別できるようにします。Amazon Linux 2023を使ったWebサーバー構築の具体的な手順についてはAWSのAmazon Linuxで構築するWebサーバー入門も参照してください。

# ec2.tf(設定例) data "aws_ami" "amazon_linux_2023" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["al2023-ami-*-x86_64"] } } resource "aws_instance" "web_1a" { ami = data.aws_ami.amazon_linux_2023.id instance_type = "t3.micro" subnet_id = aws_subnet.public_a.id tags = { Name = "${var.project_name}-web-1a" Role = "web" AZ = "${var.aws_region}a" } # default_tagsのProject/Environment/ManagedBy/CostCenterが自動付与される } resource "aws_instance" "web_1c" { ami = data.aws_ami.amazon_linux_2023.id instance_type = "t3.micro" subnet_id = aws_subnet.public_c.id tags = { Name = "${var.project_name}-web-1c" Role = "web" AZ = "${var.aws_region}c" } }

マルチAZ構成の冗長設計の全体像についてはAWSマルチAZ冗長設計の上級編で詳しく解説しています。

トラブルシュート|タグが反映されない・消える原因

1. default_tagsが一部リソースに反映されない

default_tagsはAWS Providerが管理するリソースにのみ適用されます。次のケースでは反映されません。

・aliasされた別リージョンのProviderを使う場合:aliasを持つProviderには別途default_tagsを定義する必要があります
・Terraform管理外のリソース:マネジメントコンソールやAWS CLIで作成したリソースには影響しません

# 別リージョンのprovider aliasにもdefault_tagsを設定する例 provider "aws" { alias = "us_east_1" region = "us-east-1" default_tags { tags = { Project = var.project_name Environment = var.environment ManagedBy = "Terraform" CostCenter = var.cost_center } } }

2. リソース側のtags = {}でdefault_tagsが消える

Terraform AWS Providerの挙動として、リソース側でtags = {}(空のマップ)を明示的に書くと、default_tagsのタグがそのリソースに付与されません。モジュール変数のデフォルト値を{}にしている場合に起きやすいです。

# NGパターン(default_tagsが消えるケース) variable "extra_tags" { type = map(string) default = {} # デフォルト{}はNG } # OKパターン(nullを使う) variable "extra_tags" { type = map(string) default = null # nullにするとtagsを省略した扱いになる }

対処としては、モジュール変数のデフォルト値をnullにするか、tags変数を渡す側で必ず非空のマップを渡すように設計します。

まとめ

TerraformのProvider default_tagsを使うと、すべてのAWSリソースへのタグ付け漏れを構造的に防げます。

やりたいこと Terraform設定・対応方法
全リソースに共通タグを付ける provider "aws" { default_tags { tags = {...} } }
リソース固有タグを追加する resource側のtagsブロックに追加タグを書く(マージされる)
環境ごとにタグ値を切り替える variablesとtfvarsファイルを環境別に用意する
AZ別リソースを識別する SubnetとEC2のtagsにAZキーを付与する
default_tagsが消えるのを防ぐ モジュール変数のtagsデフォルト値はnullにする
タグ体系は環境・システム・コスト配分の3軸を軸に設計し、Cost Allocation Tagsとして登録することでコスト可視化精度が向上します。まずはProvider設定のdefault_tagsから導入し、チームの表記ゆれをゼロにする土台を作りましょう。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、AWSでAmazon Linuxを使ったWebサーバー構築の入門はこちら>>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。