自由気ままに書いちゃおう

好きなことをつらつらと・・・

【Terraform】(初心者向け)別リージョンにAWSリソースを作成したい

AWSリソースを作成する際、「デフォルトリージョンは東京リージョンにしておいて、DR対策とかで大阪リージョン使おう」みたいな話がよくあります。

そんなとき、「あれ?大阪リージョンへのAWSリソースの作成どうやるんだっけ?」ってことが私は何回もあったので、

備忘を兼ね記載したいなというところが発端です。

はじめに

はじめにというか間違ってたらごめんなさいという自己防衛です。

おそらく他の方法やベストプラクティスもあると思うのですが、私のTerraformディレクトリ構成上、このやり方がやりやすかったという内容を記事にしております。

ベースとなる書き方

AWSの東京リージョンをデフォルトで使用し、必要に応じて大阪リージョンも使用するためのTerraform定義は以下のようになります。

デフォルトリージョンのリージョンを設定する際は特に何も意識することはないです。

大阪リージョンの場合には、alias を使う必要があります。

# Default Region (Tokyo)
provider "aws" {
  region = "ap-northeast-1"
}

# Alias for Osaka Region
provider "aws" {
  alias  = "osaka"
  region = "ap-northeast-3"
}

# Example resource in Tokyo Region
resource "aws_instance" "tokyo_instance" {
  # ... other configuration ...
}

# Example resource in Osaka Region
resource "aws_instance" "osaka_instance" {
  provider = aws.osaka
  # ... other configuration ...
}

上記の例では、provider "aws"ブロックを用いてAWSの東京リージョン(ap-northeast-1)をデフォルトリージョンとして設定しています。

さらに、大阪リージョン(ap-northeast-3)に対してプロバイダエイリアス(osaka)を設定しています。

これにより、大阪リージョンで作成したいAWSリソースは、

terraformリソース定義の中でprovider属性を使用することで目的のリージョンでAWSリソースが作成されます。

module配下のTerraformリソースをすべて大阪リージョンで作成する場合

Terraformモジュール内のすべてのterraformリソースを特定のリージョン(この場合は大阪リージョン)で作成するためには、 モジュール定義にprovidersブロックを追加し、その中で特定のプロバイダエイリアスを指定します。(今回は、エイリアス名はaws.osaka) これにより、モジュール内のすべてのリソースはaws.osakaを使用することになります。

以下に例を示します:

# Default Region (Tokyo)
provider "aws" {
  region = "ap-northeast-1"
}

# Alias for Osaka Region
provider "aws" {
  alias  = "osaka"
  region = "ap-northeast-3"
}

# Example module using Osaka Region
module "osaka_module" {
  source    = "./osaka_module"
  providers = {
    aws = aws.osaka
  }
}

この例では、osaka_moduleというモジュールがあり、その中のすべてのリソースは大阪リージョン(ap-northeast-3)を使用します。 モジュール定義にprovidersブロックを追加し、その中でawsプロバイダをaws.osaka(大阪リージョンのプロバイダエイリアス)にマッピングしています。 これにより、osaka_module内のすべてのリソースは大阪リージョンを使用します。

ただ、これだけでは不十分であり、以下の対応も必要です。

osaka_moduleディレクトリのsource 属性で指定したディレクトリ配下のファイル(ここではmain.tf)にrequired_providersブロックを追加します。

例えば、以下のような形になり、resource内ではprovider指定する必要はありません。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

# ... other resource definitions ...
# 大阪リージョンを明示的に指定するための provider が存在しないが、大阪リージョンに作成することができる。 

resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"  # 適当なAMI-ID
  instance_type = "t3.micro"

  tags = {
    Name = "example-instance"
  }
}

osaka_moduleディレクトリ内のメインTerraformファイル(ここではmain.tf)にrequired_providersブロックを追加しない場合、terraform init 時に以下のWarningが出力されます。

Module module.osaka_module does not declare a provider named aws.

If you wish to specify a provider configuration for the module, add an entry for aws in the required_providers block within the module.

補足

既に記載した内容の抜粋になりますが、

# Example module using Osaka Region
module "osaka_module" {
  source    = "./osaka_module"
  providers = {
    aws = aws.osaka  # ★ ここの左辺
  }
}

aws という文言は自由に記述可能です。なので hogehoge とかでも大丈夫です。 ただし、以下の★印箇所の文言と合わせる必要があります。

terraform {
  required_providers {
    aws = {  # ★ ここの左辺
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

具体的には、hogehogeにするのであれば、以下のような記述になります。(本来は分割した記載になりますが、体裁都合上で一緒に記載しています。

# Example module using Osaka Region
module "osaka_module" {
  source    = "./osaka_module"
  providers = {
    hogehoge = aws.osaka  # ★ ここの左辺と
  }
}

terraform {
  required_providers {
    hogehoge = {  # ★ ここの左辺
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

以上です。