複数のAWSリージョンを使うケース
ほとんどのクラウドプロバイダは世界中のデータセンタ(リージョン)に対してデプロイができます。
Terraformプロバイダを設定する際には、通常はどれか一つのリージョンを選択します。
例えば、通常は日本のAWSを利用するプロジェクトでは、ap-northeast-1
という一つのAWSリージョンにデプロイするよう設定します。
ですが、複数のリージョンにまたがってプロバイダをデプロイしなければならないケースもあります。
例えば、AWSのCloudfrontサービスを使用する際、Cloudfrontをどこのリージョンで使うかに関わらず、証明書を us-eas-1
でリージョンで作る必要があります。
複数のリージョンを使用するのは比較的稀なケースで、通常は各環境は完全に分離し、各リージョンを別々のモジュールで管理する状態にするべきです。
複数のAWSリージョンで、複数のリソースを作成する
複数のリージョンでデプロイするためには、provider
ブロックでエイリアスを設定します。
provider "aws" { region = "us-east-2" #デプロイ先のリージョン alias = "region_1" #Terraformで使う際の別名 } provider "aws" { region = "us-east-1" #デプロイ先のリージョン alias = "region_2" #Terraformで使う際の別名 } resource "aws_instance" "region_1" { provider = aws.region_1 ami = "ami-0822295a729d2a28e" instance_type = "t2.micro" } resource "aws_instance" "region_2" { provider = aws.region_2 ami = "ami-0dd97ebb907cf9366" instance_type = "t2.micro" }
それぞれのリソースが provider パラメータをどのように設定しているかに注意してください。
provider
パラメーターを設定することによって、 特定のリージョンにサービスをデプロイすることができます。
このコードを保存した後、 terraform init
でプロバイダーをインストールし、 terraform apply
で実際に二つのリージョンにEC2を設置できます。
Note:それぞれリージョンが異なることについて
また、それぞのれリージョンで AMIが異なることも注意が必要です。 例えば、 ap-northeast-1のUbuntuと ap-northeast-2のUbuntuは同じバージョンでも amiは異なります。
参考 : https://cloud-images.ubuntu.com/locator/ec2/
補足 : 特定リージョンのAMI ID を自動取得する方法
複数のリージョンを使用する方法から話がそれますが、 AMIをベタ張するのではなく、データソースを使用してAMIIDを検索する方法もあります。
provider "aws" { region = "us-east-2" alias = "region_1" } provider "aws" { region = "us-east-1" alias = "region_2" } data "aws_ami" "ubuntu_region_1" { provider = aws.region_1 most_recent = true owners = ["099720109477"] filter { name = "name" values = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" } } data "aws_ami" "ubuntu_region_2" { provider = aws.region_2 most_recent = true owners = ["099720109477"] filter { name = "name" values = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*" } } resource "aws_instance" "region_1" { provider = aws.region_1 ami = data.aws_ami.ubuntu_region_1.id #変更点 instance_type = "t2.micro" } resource "aws_instance" "region_2" { provider = aws.region_2 ami = data.aws_ami.ubuntu_region_2.id #変更点 instance_type = "t2.micro" }
owners
oweners
の値は 各リージョンで共通である上に、OSごとにほとんど固定です。
OS, Distribution | 所有者 ID |
---|---|
RockyLinux | 792107900819 |
RedHat | 309956199498 |
Fedora | 125523088429 |
CentOS Stream | 125523088429 |
CentOS | 125523088429 |
AlmaLinux | 764336703387 |
OracleLinux | 131827586825 |
Ubuntu | 099720109477 |
Debian | 136693071363 |
openSUSE | 679593333241 |
WindowsServer | 801119661308 |
参考 : https://qiita.com/NaoyaOgura/items/4d8aeeb64963d0eb4831
複数のAWSリージョンで、複数のモジュールを使用する
一つのリージョンに、Aurora RDSのMySQLデータベースを立てるときは、以下のようなterraformリソースを使えます。
provider "aws" { region = "us-east-2" } variable "db_username" { type = string default = null } variable "db_password" { type = string default = null } resource "aws_db_instance" "example" { identifier_prefix = "minegishi-test" engine = "mysql" allocated_storage = 10 instance_classes = "db.t2.micro" skip_final_snapshot = true username = var.db_username password = var.db_password }
これを一つのリージョン("us-east-2")だけでなく、別のリージョンにDBの内容をレプリケーションすることで、より強固になります。 では、ステージング環境用のMySQLコードをマルチリージョンにレプリケーションをサポートしたコードに変えてみます。
## variables.tf variable "backup_retenion_period" { type = number default = null } variable "replicate_source_db" { type = string default = null } variable "db_username" { type = string default = null } variable "db_password" { type = string default = null }
main.tf
//provider "aws" { // region = "us-east-2" //} terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } } resource "aws_db_instance" "example" { identifier_prefix = "minegishi-test" allocated_storage = 10 instance_classes = "db.t2.micro" skip_final_snapshot = true # バックアップを有効化 backup_retention_period = var.backup_retention_period # 設定されているときはこのデータベースはレプリカ replicate_source_db = var.replicate_source_db # replicate_source_dbが設定されていない時だけ、これらのパラメーターを設定 engine = var.replicate_source_db == null ? "mysql" : null username = var.replicate_source_db == null ? var.db_username : null password = var.replicate_source_db == null ? var.db_password : null }
outputs.tf
output "arn" { value = aws_db_instance.example.arn }
このモジュールを呼び出す側(environment/dev/main.tf
)は以下のように設定します。
(ただし、この指定だと同じリージョンにデプロイされてしまいます)
module "mysql_primary" { source = "../../../../modules/data-stores/mysql" db_name = "prod_db" db_username = var.db_username db_password = var.db_password backup_retention_period = 1 } module "mysql_replica" { source = "../../../../modules/data-stores/mysql" replicate_source_db = module.mysql_primary.arn }
上記の構成では、同一リージョンにRDSがレプリケートされてしまいますが、ここでproviderブロックを複数追加し、
それぞれのproviders
引数に当てはめることで、 それぞれのリージョンにデプロイすることができます。
provider "aws" { region = "us-east-2" alias = "primary" } provider "aws" { region = "us-west-1" alias = "replica" } module "mysql_primary" { source = "../../../../modules/data-stores/mysql" providers = { aws = aws.primary } db_name = "prod_db" db_username = var.db_username db_password = var.db_password backup_retention_period = 1 } module "mysql_replica" { source = "../../../../modules/data-stores/mysql" providers = { aws = aws.replica } replicate_source_db = module.mysql_primary.arn }
これらのモジュールを呼ぶ引数の providers
はマップであり、
provider
パラメータは一つの値であることに注意してください。
これは、各リソースとデータソースは一つのプロバイダのみにデプロイされる一方、
モジュールは複数のデータソースやリソースを含んで複数のプロバイダを使う必要があるためです。
モジュールに渡すproviders
のキーは、モジュール内のrequired_providers
で明示的に定義する必要があります。
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } }
page:https://minegishirei.hatenablog.com/entry/2025/01/12/151623