📑

ChatGPT4にAWS CodePipelineのチュートリアルをCloudFormation化してもらった

2023/03/25に公開

TL;DR

  • ChatGPT-4にCodePipelineのチュートリアル文書からCfn YAMLを作ってもらった
  • かなりの部分は書いてもらったけど、手直しは必要

やったもの

こちらのチュートリアル

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/tutorials-simple-s3.html

絵で描くとこういう感じ。S3にzipファイルをアップロードするとその中身を使ってEC2(2つ)にデプロイするというもの。

作ったYAML

  • Parameterで自分のIPアドレスをSecurity Group用に設定
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template for creating resources as per the AWS document

Parameters:
  MyIpAddress:
    Description: The IP address to whitelist for access to the instances (e.g., 203.0.113.0/32)
    Type: String
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/\d{1,2}'
    ConstraintDescription: Must be a valid IP CIDR range (e.g., 203.0.113.0/32).

Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'awscodepipeline-demobucket-example-${AWS::Region}-${AWS::AccountId}'
      VersioningConfiguration:
        Status: Enabled

  EC2InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: EC2InstanceRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore


  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref EC2InstanceRole

  CodeDeployRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: CodeDeployRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codedeploy.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: CodePipelineS3AccessPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
                  - s3:GetBucketVersioning
                  - s3:GetBucketAcl
                  - s3:GetBucketLocation
                Effect: Allow
                Resource:
                  - !Sub 'arn:aws:s3:::awscodepipeline-demobucket-example-${AWS::Region}-${AWS::AccountId}/*'
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH and HTTP access
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIpAddress
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIpAddress

  EC2Instance1:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0ee87a1a729fecb57
      IamInstanceProfile: !Ref InstanceProfile
      Tags:
        - Key: Name
          Value: MyCodePipelineDemo
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup

  EC2Instance2:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0ee87a1a729fecb57
      IamInstanceProfile: !Ref InstanceProfile
      Tags:
        - Key: Name
          Value: MyCodePipelineDemo
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup

  CodePipelineRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: CodePipelineRole
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codepipeline.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: CodePipelinePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - s3:*
                Resource:
                  - !Sub 'arn:aws:s3:::awscodepipeline-demobucket-example-${AWS::Region}-${AWS::AccountId}'
                  - !Sub 'arn:aws:s3:::awscodepipeline-demobucket-example-${AWS::Region}-${AWS::AccountId}/*'
              - Effect: Allow
                Action:
                  - ec2:DescribeInstances
                  - ec2:DescribeInstanceStatus
                Resource: '*'
              - Effect: Allow
                Action:
                  - codedeploy:*
                Resource: '*'
              - Effect: Allow
                Action:
                  - cloudwatch:PutMetricData
                Resource: '*'
              - Effect: Allow
                Action:
                  - iam:PassRole
                Resource:
                  - !GetAtt EC2InstanceRole.Arn
                  - !GetAtt CodeDeployRole.Arn
                Condition:
                  StringEqualsIfExists:
                    iam:PassedToService:
                      - ec2.amazonaws.com
                      - codedeploy.amazonaws.com

  CodePipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: MyFirstPipeline
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: S3
                Version: 1
              Configuration:
                S3Bucket: !Ref S3Bucket
                S3ObjectKey: SampleApp_Windows.zip
                PollForSourceChanges: true
              OutputArtifacts:
                - Name: SourceArtifact
              RunOrder: 1
        - Name: Deploy
          Actions:
            - Name: DeployAction
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CodeDeploy
                Version: 1
              Configuration:
                ApplicationName: MyDemoApplication
                DeploymentGroupName: MyDemoDeploymentGroup
              InputArtifacts:
                - Name: SourceArtifact
              RunOrder: 1
      ArtifactStore:
        Type: S3
        Location: !Ref S3Bucket

Outputs:
  S3Bucket:
    Description: S3 Bucket for the application
    Value: !Ref S3Bucket
  EC2InstanceRole:
    Description: Instance Role for EC2 instances
    Value: !Ref EC2InstanceRole
  CodeDeployRole:
    Description: CodeDeploy Role for deployments
    Value: !Ref CodeDeployRole

CahtGPTで作ったときのメモ

  • やりとりは英語
  • 20回くらいChatGPTに入力
  • 出力が遅いので、YAML全部ではなく部分的に出してもらうほうがよい
    • 途中で止まるときがあり、「Continue」と言えば再開する
  • Description: AWS CloudFormation template for creating resources as per the AWS document の部分は、特に指定したわけでなくCahtGPTが書いてます。
  • 最初はチュートリアルの全部(Step1から4)を渡してYAML作って、としてみたものの、大きなものは難しいようで、かなり追加での命令が必要だった
  • 基本的にはコードは出力したものを使うが、修正が必要なときはGoogle検索などで調べた
    • AMIはリージョン関係なく存在しない番号を出してくるので、自分でConsoleから調べた
    • IPアドレスのValidationは間違っていたのでStackoverflowで調べた
    • 最小権限にして、と言ってもなかなかうまく行かないのでs3:*とした
    • 最後の1行が抜けているとかがあった
    • 「add XXXX section」や「Erorr says: XXXX . How to fix?」、「use xxx instead of yyy」 等、適宜修正を依頼した

削除

S3の中身をEmptyにしてからStackを消します。

ついでにこんなPythonスクリプト作りました。

https://zenn.dev/shimo_s3/articles/28b2124b3adac5

まとめ

  • ChatGPTを使って、CodePipelineのチュートリアルをドキュメントからCloudFormationテンプレートにしました
  • 自力で作るよりは疲労感は少ないかもしれないです。かかる時間は同じくらいの印象
  • こちらの正誤に関わらず修正をしてくれてしまうので(人間を肯定するようになっている?)、かなり注意が必要

余談:最初のYAML

一番最初に返ってきたのはこういうYAMLでした。あとからいろいろ足してもらった感じです。

私のお願い

Can you generate CloudFormation template from this document? This document is from AWS. 

(上のチュートリアルのページのStep1か4をそのまま全部貼る)

返ってきたYAML(エラーになる)

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation template for creating resources as per the AWS document
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'awscodepipeline-demobucket-example-${AWS::Region}-${AWS::AccountId}'
      VersioningConfiguration:
        Status: Enabled

  InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Path: /
      RoleName: EC2InstanceRole

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref InstanceRole

  CodeDeployRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codedeploy.amazonaws.com
            Action:
              - sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
      Path: /
      RoleName: CodeDeployRole

Outputs:
  S3Bucket:
    Description: S3 Bucket for the application
    Value: !Ref S3Bucket
  InstanceRole:
    Description: Instance Role for EC2 instances
    Value: !Ref InstanceRole
  CodeDeployRole:
    Description: CodeDeploy Role for deployments
    Value: !Ref CodeDeployRole

Discussion