こんにちは。AWS事業本部トクヤマシュンです。
今回のエントリではChatGPTを用いて、AWS CloudFormationで使われるテンプレート(以下CFnテンプレート)をTerraformで使われるHashiCorp Configulation Language(以下HCL)コードに変換してみました。
動機
私はよくTerraformを用いてリソースを構築します。 一方で、AWS公式から提供されるさまざまなソリューションやサンプルはCFnテンプレートの形で提供されることが多いと感じます。
これらをTerraformで構築できたら良いのにと思うことが何度かあったので、ChatGPTを使って簡単にCFnテンプレートをHCLコードに変換できたら色々と捗りそう、と思ったのが今回の動機です。
環境
利用環境は以下の通りです。
- ChatGPTのバージョン:GPT-4
変換してみた①
まずはシンプルなCFnテンプレートのサンプルを変換してみました。 AWS CloudFormation ユーザーガイドで提供されるテンプレートスニペットのうち、 Amazon EC2 Insance リソース を構築する次のCFnテンプレートを変換してみます。
下記のように質問します。
次のCFnテンプレートをHCLに変換して
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"MyInstance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"AvailabilityZone": "us-east-1a",
"ImageId": "ami-0ff8a91507f77f867"
}
}
}
}
回答は次のとおりでした。
次のCloudFormationテンプレートをHCL(HashiCorp Configuration Language)に変換しました。これはTerraform構成ファイルとして使用できます。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "MyInstance" {
ami = "ami-0ff8a91507f77f867"
instance_type = "t2.micro" # インスタンスタイプが指定されていないため、デフォルト値としてt2.microを選択しました
availability_zone = "us-east-1a"
tags = {
Name = "MyInstance"
}
}
このTerraform構成ファイルは、元のCloudFormationテンプレートと同じリソースを作成します。ただし、インスタンスタイプが指定されていなかったため、デフォルトのt2.microを選択しました。必要に応じてインスタンスタイプを変更してください。
おお!ほぼ同じ内容のHCLコードが生成されました。 ご丁寧にterraformブロックまでつけてくれています。
CFnテンプレートとHCLコードのそれぞれでリソースを構築して確認したところ、差分は下記でした。
- インスタンスタイプが異なる
- CFnテンプレートではm1.small、HCLコードではt2.micro
- CFnテンプレートではインスタンスタイプが省略された場合、デフォルトでm1.smallが指定される
- HCLコードではインスタンスタイプを省略するとエラーとなるため、t2.microが自動で設定された
- この差分はChatGPTからの返答にあったところから予想できました
- CFnテンプレートではm1.small、HCLコードではt2.micro
- リソースタグが異なる
- CFnテンプレートでは CloudFormationが自動で作成する次のタグが付与される
- aws:cloudformation:logical-id = "MyInstance"
- aws:cloudformation:stack-id= "スタックID"
- aws:cloudformation:stack-name = "スタック名"
- HCLコードでは次の1つのタグが付与される
- Name = "MyInstance"タグが付与される
- CFnテンプレートでは CloudFormationが自動で作成する次のタグが付与される
上記のように、CloudFormationとTerraformのデフォルト動作に起因する差分が発生してしまいました。
そのため変換されたHCLコードをそのまま使うわけにはいかないと思います。
ただ、0から準備するより短時間でHCLコードを作成できそう**と感じました。
変換してみた②
続いて、もう少し長いCFnテンプレートをHCLコードに変換してみます。
AWS CloudFormation ユーザーガイドで提供されるテンプレートスニペットのうち、 Amazon EC2 VolumeAttachment リソース を構築する次のCFnテンプレートを変換してみます。
下記のように質問します。
次のCFnテンプレートをHCLに変換して
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"Ec2Instance": {
"Type": "AWS::EC2::Instance",
"Properties": {
"SecurityGroups": [
{
"Ref": "InstanceSecurityGroup"
}
],
"ImageId": "ami-0ff8a91507f77f867"
}
},
"InstanceSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "Enable SSH access via port 22",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"CidrIp": "0.0.0.0/0"
}
]
}
},
"NewVolume": {
"Type": "AWS::EC2::Volume",
"Properties": {
"Size": "100",
"AvailabilityZone": {
"Fn::GetAtt": [
"Ec2Instance",
"AvailabilityZone"
]
}
}
},
"MountPoint": {
"Type": "AWS::EC2::VolumeAttachment",
"Properties": {
"InstanceId": {
"Ref": "Ec2Instance"
},
"VolumeId": {
"Ref": "NewVolume"
},
"Device": "/dev/sdh"
}
}
}
}
次の回答が来ました。
次のCloudFormationテンプレートをHCL(HashiCorp Configuration Language)に変換しました。これはTerraform構成ファイルとして使用できます。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_security_group" "InstanceSecurityGroup" {
name = "InstanceSecurityGroup"
description = "Enable SSH access via port 22"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "Ec2Instance" {
ami = "ami-0ff8a91507f77f867"
instance_type = "t2.micro" # インスタンスタイプが指定されていないため、デフォルト値としてt2.microを選択しました
vpc_security_group_ids = [aws_security_group.InstanceSecurityGroup.id]
tags = {
Name = "Ec2Instance"
}
}
resource "aws_ebs_volume" "NewVolume" {
availability_zone = aws_instance.Ec2Instance.availability_zone
size = 100
}
resource "aws_volume_attachment" "MountPoint" {
device_name = "/dev/sdh"
volume_id = aws_ebs_volume.NewVolume.id
instance_id = aws_instance.Ec2Instance.id
}
このTerraform構成ファイルは、元のCloudFormationテンプレートと同じリソースを作成します。ただし、インスタンスタイプが指定されていなかったため、デフォルトの`t2.micro`を選択しました。必要に応じてインスタンスタイプを変更してください。
今回もCFnテンプレートとHCLコードのそれぞれでリソースを構築して確認したところ、差分は下記でした。
- インスタンスタイプおよびリソースタグが異なる
- 変換してみた①と同等の差分
- SecurityGroupのアウトバウンドルールの有無が異なる
- CloudFormationでは全許可のアウトバウンドルール作成
- CloudFormationの
AWS::EC2::SecurityGroup
タイプのリソースはアウトバウンドルールの記述がない場合、デフォルトで全許可のアウトバウンドルールを作成する
- CloudFormationの
- Terraformではアウトバウンドルールなし
- Terraformの
aws_security_group
リソースはアウトバウンドルールの記述がなければ作成しない
- Terraformの
- CloudFormationでは全許可のアウトバウンドルール作成
上記のように、今回もCloudFormationとTerraformのデフォルト動作に起因する差分が発生してしまっていました。
しかし、それなりに長いCFnテンプレートもほぼ同様のリソースを作成できることがわかりました。
感想
上記2つの例から、CloudFormationとTerraformのデフォルト動作に起因する差分は発生してしまうものの、 ChatGPTを使うことでCFnテンプレートから近い設定を持ったリソースを作成するHCLコードに変換できそうだということが分かりました。
個人的には次のような感想を持ちました。
- 差分の発生を完全に避けることは難しそう。変換したHCLコードをそのまま利用するのは怖い
- ただし、0からHCLコードを記載していくよりは早くHCLコードを作成できそう
- 変換の際、省略されているパラメータを可能な限り記載することで、HCLコードへの変換時の差分を減らすのが良さそう
本編は以上です。
趣味のスパイスカレー 改め 副業のスパイスカレー
これまで私は趣味のスパイスカレー作りをときどきブログに投稿していましたが、
このたび趣味が高じて、兵庫県明石市に毎週土曜日のみオープンのカレー屋をオープンしました。
その名も、CURRY HOUSE Babbulkund(カレーハウス バブルクンド)といいます。
各種リンクです。
- Google Maps:CURRY HOUSE Babbulkund
- Instagram: @babbulkund
- Twitter: @babbulkund
店舗の詳細情報です。
CURRY HOUSE Babbulkund(バブルクンド)
OPEN:毎週土曜日 11:30-17:30(LO17:00)
※営業日、営業時間は変更の可能性あり
〒673-0033
兵庫県明石市林崎町3-550-8
山陽電鉄 林崎松江海岸駅から徒歩5分
現在は、平日の月〜木はクラスメソッドでエンジニア、週末はカレー屋、という二足の草鞋生活を送っています。
数年前にはこんな生活は夢にも思っていなかったので、人生何が起こるか分からないものです。
勤務日数の調整など、柔軟な働き方ができるクラスメソッドは本当に良い会社だな、と手前味噌ながら思いつつ、とても感謝しています。
カレー屋オープンについてのアレコレは、いずれ別のブログなど書ければと考えています。 本日はここまでといたします。
最後に
今回のエントリではChatGPTを用いて、CFnテンプレートをHCLコードに変換してみました。
変換したコードをそのまま利用するのは怖いものの、うまく使えば一からコードを書くのにくらべてかなりの省力化ができると思うので、
よければ試してみてください。
本ブログがどなたかのお役にたてば幸いです。