ChatGPTでCFnテンプレートをHCLコードに変換してみた

こんにちは。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テンプレートでは CloudFormationが自動で作成する次のタグが付与される
      • aws:cloudformation:logical-id = "MyInstance"
      • aws:cloudformation:stack-id= "スタックID"
      • aws:cloudformation:stack-name = "スタック名"
    • HCLコードでは次の1つのタグが付与される
      • Name = "MyInstance"タグが付与される

上記のように、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タイプのリソースはアウトバウンドルールの記述がない場合、デフォルトで全許可のアウトバウンドルールを作成する
    • Terraformではアウトバウンドルールなし
      • Terraformのaws_security_groupリソースはアウトバウンドルールの記述がなければ作成しない

上記のように、今回もCloudFormationとTerraformのデフォルト動作に起因する差分が発生してしまっていました。
しかし、それなりに長いCFnテンプレートもほぼ同様のリソースを作成できることがわかりました。

感想

上記2つの例から、CloudFormationとTerraformのデフォルト動作に起因する差分は発生してしまうものの、 ChatGPTを使うことでCFnテンプレートから近い設定を持ったリソースを作成するHCLコードに変換できそうだということが分かりました。

個人的には次のような感想を持ちました。

  • 差分の発生を完全に避けることは難しそう。変換したHCLコードをそのまま利用するのは怖い
  • ただし、0からHCLコードを記載していくよりは早くHCLコードを作成できそう
  • 変換の際、省略されているパラメータを可能な限り記載することで、HCLコードへの変換時の差分を減らすのが良さそう

本編は以上です。

趣味のスパイスカレー 改め 副業のスパイスカレー

これまで私は趣味のスパイスカレー作りをときどきブログに投稿していましたが、
このたび趣味が高じて、兵庫県明石市に毎週土曜日のみオープンのカレー屋をオープンしました

その名も、CURRY HOUSE Babbulkund(カレーハウス バブルクンド)といいます。

各種リンクです。

店舗の詳細情報です。

CURRY HOUSE Babbulkund(バブルクンド)
OPEN:毎週土曜日 11:30-17:30(LO17:00)
※営業日、営業時間は変更の可能性あり

〒673-0033
兵庫県明石市林崎町3-550-8
山陽電鉄 林崎松江海岸駅から徒歩5分

現在は、平日の月〜木はクラスメソッドでエンジニア、週末はカレー屋、という二足の草鞋生活を送っています。
数年前にはこんな生活は夢にも思っていなかったので、人生何が起こるか分からないものです。
勤務日数の調整など、柔軟な働き方ができるクラスメソッドは本当に良い会社だな、と手前味噌ながら思いつつ、とても感謝しています。

カレー屋オープンについてのアレコレは、いずれ別のブログなど書ければと考えています。 本日はここまでといたします。

最後に

今回のエントリではChatGPTを用いて、CFnテンプレートをHCLコードに変換してみました。
変換したコードをそのまま利用するのは怖いものの、うまく使えば一からコードを書くのにくらべてかなりの省力化ができると思うので、 よければ試してみてください。

本ブログがどなたかのお役にたてば幸いです。