★ 初級

01. プロバイダと認証

AWS を Terraform で扱う最初の一歩は プロバイダ宣言認証。ここを正しく設定すれば、以降の章のリソース定義はすべて動きます。

最小構成

# Terraform 自身の設定: CLI バージョンと使う provider を宣言
terraform {
  required_version = ">= 1.6"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.80"
    }
  }
}

# AWS プロバイダの基本設定(最小はリージョン指定だけ)
provider "aws" {
  region = "ap-northeast-1"
}

# ここから resource を書ける
resource "aws_s3_bucket" "example" {
  bucket = "my-tf-test-bucket-20260510"
}

terraform / required_providers

terraform ブロックは「Terraform 自身に対する設定」です。CLI のバージョン縛り(required_version)と、使う provider の名前・バージョン縛り(required_providers)を書きます。

# terraform ブロックの詳細例: CLI とプロバイダの version 制約を厳密化
# 複数 provider を required_providers の中に並べると、それらが自動でダウンロードされる
terraform {
  required_version = ">= 1.6"          # CLI バージョンの下限
  required_providers {
    aws = {
      source  = "hashicorp/aws"          # Terraform Registry 上のパス
      version = "~> 5.80"                # 5.80 以上、6.0 未満
    }
    random = {
      source  = "hashicorp/random"       # パスワード生成用
      version = "~> 3.6"
    }
  }
}

バージョン制約の書き方

表記意味
5.80.0このバージョン丁度
>= 5.05.0 以上
~> 5.805.80 以上、6.0 未満
~> 5.80.05.80.0 以上、5.81.0 未満

初学者は ~> 5.80 のような「マイナーバージョン固定」が無難。terraform init.terraform.lock.hcl も自動生成され、こちらで完全固定されます(チームでバージョンを揃えるためにコミットする)。

provider "aws" の引数

# 実運用に近い provider 設定例
# region / profile に加え、default_tags と assume_role を併用
provider "aws" {
  region  = "ap-northeast-1"
  profile = "default"   # ~/.aws/credentials の [default] を使う

  # default_tags: このプロバイダで作る全リソースに自動で付くタグ
  # 個別 resource の tags とマージされる
  default_tags {
    tags = {
      Project   = "hcl-guide"
      ManagedBy = "Terraform"
    }
  }

  # assume_role: 別 AWS アカウントの IAM ロールに切り替えて操作
  # クロスアカウントデプロイで頻出(管理アカウントから本番アカウントを操作)
  assume_role {
    role_arn     = "arn:aws:iam::222222222222:role/cross-account-deploy"
    session_name = "tf-deploy"
  }
}
引数役割
region必須。デフォルトリージョン
profile~/.aws/credentials のプロファイル名
shared_credentials_filescredentials ファイルのパス(複数可)
assume_role別アカウント/ロールに切り替えて操作
default_tagsこのプロバイダで作る全リソースに付くタグ
endpointsテスト用に LocalStack 等を指す時

認証方法(4 通り)

Terraform の AWS provider は、AWS SDK と同じ 認証情報の検索順 に従います。上から順に探して、見つかったら止まります。

  1. 静的引数: provider ブロックに直接書く(推奨しない。コミットされやすい)
  2. 環境変数: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN
  3. 共有認証ファイル: ~/.aws/credentials + ~/.aws/config(プロファイル指定)
  4. EC2 / ECS / Lambda のインスタンスメタデータ: AWS で動かす CI ランナーや踏み台で自動取得

ローカル開発で使う形(推奨)

# SSO を使う(一番安全)
aws configure sso --profile myprofile
aws sso login --profile myprofile

# Terraform 側
export AWS_PROFILE=myprofile
terraform plan

CI(GitHub Actions)で使う形(推奨)

OIDC でロール assume → 一時クレデンシャルを環境変数に流す。GitHub 章 06 参照。

アクセスキーをコードに書かない provider "aws" { access_key = "AKIA..." } は禁止。.tfvars に書くのもダメ。1 度コミットしたら無効化するしかありません。

マルチリージョンと alias

1 つのスタックで複数リージョンを扱う時、provider をエイリアスで複数定義します。

# マルチリージョンの書き方: provider を「エイリアス」付きで複数定義する

# 1 つ目: alias なし = デフォルト provider(明示的に provider 指定しない resource はこちらを使う)
provider "aws" {
  region = "ap-northeast-1"
}

# 2 つ目: alias = "us_east_1" 付き → 必要なときだけ参照する
provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

# 普通のリソースはデフォルト provider (ap-northeast-1) で作られる
resource "aws_s3_bucket" "logs" {
  bucket = "my-logs"
}

# provider = aws.us_east_1 を指定すると、こちらだけ us-east-1 で作られる
# CloudFront 用 ACM 証明書は us-east-1 必須(AWS の仕様)
resource "aws_acm_certificate" "site" {
  provider          = aws.us_east_1
  domain_name       = "hcl-guide.com"
  validation_method = "DNS"
}

このサイト自身も同じ構造(CloudFront = AWS のグローバル CDN は ACM 証明書を必ず us-east-1 から取る必要がある)。AWS 章 08 で実践します。

default_tags ─ 全リソースに自動でタグを付ける

AWS で運用していると「どのチームが・どの環境で・なぜこのリソースを作ったか」をタグで識別したくなります。1 つひとつの resource に書くのは大変なので、provider レベルで 共通タグを 1 か所に 書ける機能。

# default_tags: provider レベルで「全リソースに付ける共通タグ」を定義
# 各 resource で tags = {} を書かなくても、自動で付与される
provider "aws" {
  region = "ap-northeast-1"

  default_tags {
    tags = {
      Project    = "hcl-guide"
      Env        = "prd"
      Owner      = "platform-team"
      ManagedBy  = "Terraform"
      CostCenter = "1234"
    }
  }
}

# このプロバイダで作る全リソースに上の 5 タグが自動付与される
resource "aws_s3_bucket" "site" {
  bucket = "hcl-guide-site"

  tags = {
    Name = "site"   # 個別タグも default_tags とマージされる(合計 6 タグ)
  }
}
タグ設計の指針 最低限ほしい: Project / Env / Owner / ManagedBy / CostCenterManagedBy=Terraform「これは IaC 管理。マネコンで触るな」のサイン として実用的。