複数の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