先日の記事で、Terraformで利用するために、最新のAMI IDをAWS CLIで取得する方法を調べたが、Terraformだけで完結できそうだと気付いたためやってみる。
はじめに結論
このtfファイルを実行することで、先日の記事と同じ結果が得られる。
作成するtfファイル
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.42" } } } provider "aws" { region = "ap-northeast-1" } # ↓ここから data "aws_ami" "latest" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["al2023-ami-2*"] } } output "latest_ami_id" { value = data.aws_ami.latest.id } # ↑ここが大事
terraform planの結果
Changes to Outputs: + latest_ami_id = "ami-031134f7a79b6e424"
(なお、先日の記事から数日しか経っていないが、すでに無料利用対象の最新AMIが更新されているようで、得られたAMI IDは異なっていた。)
やってみた
Terraformドキュメントに、AMIに関するData Sourceであるaws_amiが存在したので参考にする。
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami
aws_amiで利用できる引数は以下の通り。AWS CLIのdescribe-imagesコマンドで見たことのあるものが揃っているが、「most_recent」と「name_regrex」はTerraform独自の引数となる。
most_recent
most_recentがtrueの場合、返却対象のAMIが複数あったときに最新のAMI1つのみを返却する。なお、返却されるIDが1つでないとTerraformは失敗する。
先日の記事でいうと、AWS CLIでqueryオプションを使ってJMESPathでごにょごにょ書いていた箇所に相当する。
name_regex
name_regexは、AWSが返却するAMI IDのリストに対して正規表現で絞り込みを行う。
自由度の高い絞り込みができる一方で、一応の注意点としてはローカルで絞り込みを行うという点。対象となるAMI IDの量やTerraform実行環境のスペック次第では少し重い処理になる。そのため、他の引数で返却されるIDを絞って減らしておくことが推奨されている。
脇道にそれるが、name_regex使うとどれだけパフォーマンスに影響が出るのか、ちょっとやってみた。
以下2パターンで、返却時間をtimeコマンドで確認してみた。
data "aws_ami" "filter" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["al2023-ami-2*"] } }
→ user 0m7.279s
data "aws_ami" "regex" { most_recent = true owners = ["amazon"] name_regex = "^al2023-ami-2.*" }
→ user 0m12.970s
確かにパフォーマンスに少し影響が出た。大量のEC2を異なるAMIで起動するようなときなどはちょっと気を使っても良いかもしれない。
AWS CLIコマンドとの紐づけて整理
先日の記事のコマンドaws ec2 describe-images --owners amazon --filters 'Name=name,Values=al2023-ami-2*' --query 'sort_by(Images,&CreationDate)[-1].[ImageId]' --output text
と紐づけて整理してみる。
AWS CLIの--owners amazon
は、
Terraformではowners = ["amazon"]
となり、
AWS CLIの--filters 'Name=name,Values=al2023-ami-2*'
は、
Terraformでは
filter { name = "name" values = ["al2023-ami-2*"] }
となり、
AWS CLIの--query 'sort_by(Images,&CreationDate)[-1].[ImageId]'
は、
Terraformではmost_recent = true
となった。
残課題
先日の記事に同じ。
残課題
今回のように近しい命名規則のAMIが追加された場合や、AWS側でNameの命名規則を変えた>場合に、期待通りの出力結果が得られなくなる可能性がある。無料利用対象という条件で絞り込むような、スマートな方法があるのかもしれない。