【Terraform】AWS Provider v6 からはリソースレベルでリージョンを設定できる
Terraform AWS Provider v6 の beta 版がリリースされました! 🎉 🎉
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "6.0.0-beta1"
}
}
}
AWS Provider v6 の目玉はなんといってもリソースレベルのリージョン設定です。
今まで : 複数のリージョンを扱うのは面倒だった
AWS Provider v5 以前では、異なるリージョンにリソースを作成するためにはリージョンごとに provider を定義して、リソースの provider
属性に明示的に指定する必要がありました。
# ap-northeast-1 用の provider をデフォルトとして使う
provider "aws" {
region = "ap-northeast-1"
}
# us-east-1 用の provider を定義 (めんどくさい)
provider "aws" {
alias = "virginia"
region = "us-east-1"
}
# ap-northeast-1 にリソースを作成
resource "aws_cloudfront_distribution" "main" {
# ...
}
# us-east-1 にリソースを作成
resource "aws_acm_certificate" "main" {
provider = aws.virginia # us-east-1 用の provider を指定
# ...
}
また、 Terraform では provider に対して for_each
を使用できないという制約もあり、複数リージョンにまとめてリソースを作成したいときもなかなか大変でした。
provider "aws" {
region = "ap-northeast-1"
}
provider "aws" {
alias = "virginia"
region = "us-east-1"
}
resource "aws_s3_bucket" "main" {
# これはエラーになる
for_each = toset([aws, aws.virginia])
provider = each.value
bucket_prefix = "bucket-"
}
variable "regions" {
type = list(string)
default = ["ap-northeast-1", "us-east-1"]
}
provider "aws" {
# これもエラーになる
for_each = toset(var.regions)
region = each.value
}
resource "aws_s3_bucket" "main" {
# こういうこともできない
for_each = toset(var.regions)
provider = aws[each.key]
bucket_prefix = "bucket-"
}
そんな感じで、 AWS Provider で複数のリージョンを扱うのは結構面倒でした。
region
属性の登場
AWS Provider v6 : AWS Provider v6 では リソースに対して region
属性を設定するだけでリソースレベルでリージョンを指定できるようになり、複数の provider を定義する必要がなくなりました。
region
属性を省略した場合は ( 今まで通り ) provider に設定されたリージョンが適用されます。
provider "aws" {
region = "ap-northeast-1" # デフォルトのリージョン
}
-provider "aws" {
- alias = "virginia"
- region = "us-east-1"
-}
# ap-northeast-1 にリソースを作成
resource "aws_cloudfront_distribution" "main" {
# ...
}
# us-east-1 にリソースを作成
resource "aws_acm_certificate" "main" {
- provider = aws.virginia
+ region = "us-east-1" # リソースレベルでリージョンを指定
# ...
}
この region
属性はあくまでもただの属性なので、 for_each
と組み合わせて使用することで複数リージョンにまとめてリソースを作成したりすることもできます。
provider "aws" {
# ...
}
resource "aws_s3_bucket" "main" {
# 複数リージョンにまとめてリソースを作成
for_each = toset(["ap-northeast-1", "ap-northeast-2", "us-east-1"])
region = each.value
bucket = "bucket-${each.value}"
}
例えば複数リージョンでの GuardDuty 一括有効化などのユースケースもかなり楽になりそうですね。
Data Source / Ephemeral Resource
resource
ブロックだけじゃなく、 Data Source や Ephemeral Resource などでも同様に region
属性を設定できます。
provider "aws" {
region = "ap-northeast-1"
}
data "aws_s3_bucket" "virginia" {
region = "us-east-1" # これ
bucket = "virginia-bucket"
}
ephemeral "aws_ssm_parameter" "virginia" {
region = "us-east-1" # これ
arn = "arn:aws:ssm:us-east-1:012345678910:parameter/virginia-parameter"
}
import
import 実行時には import id の末尾に @<region>
を追加することでリージョンを指定できます。
$ terraform import aws_vpc.example vpc-00000000@us-east-1
import {
to = aws_vpc.example
id = "vpc-00000000@us-east-1"
}
region
属性を設定できないリソース
一部のリソース ( 例えばメタデータリソースやグローバルリソースなど ) には region
属性を設定できません。
region
属性を設定できないリソースの一覧については以下をご参照ください。
v6 へのアップグレードガイドは以下のページで公開されています。
region
属性以外にも色々と破壊的変更が含まれているので、一度確認しておくといいかもしれません。
( もちろん現在はまだ beta 版なので、今後さらに変更が加わる可能性もあることにご注意ください。 )
まとめ
リソースレベルでリージョンを指定できるようになることで provider の定義をひとつにまとめることができるようになり、且つ複数のリージョンを動的に扱うことも容易になります。
複数リージョンを動的に扱うために provider に対して for_each
を使えるようにするのではなく、あくまでも単一の provider 定義だけで済む設計に持っていったのは非常に納得感があります。
Currently, each provider configuration in Terraform targets a single AWS Region, leading to increased memory consumption and complexity when managing multi-Region deployments. The new approach leverages an injected region attribute at the resource level, reducing memory overhead and simplifying configuration.
Key Highlights:
- Single Provider Configuration: Reduces the need to load multiple instances of the AWS provider, lowering memory usage.
...
AWS Provider v6 はまずは 6 週間の beta 期間が設けられ、その間にフィードバックを集めつつ正式リリースへ向けて改善が進められていくようです。
There will be a 6 week beta period in which we will ask the community for feedback, to better understand the impact of the upgrade experience, to assess the implementation of multi-region and other enhancements and to resolve any issues found.
楽しみ〜
Discussion