🗂

RDSが起動したら止めるCfnをChatGPTに作ってもらう

2023/10/17に公開

先に感想

  • ChatGPT4を使って、図からIaCにしてみたかったが手動部分が多かった
  • とにかく説明は丁寧にしたほうがよい。instanceだけでは通じない可能性あり
    • ChatGPT4のデビュー時はもっとプロンプトの意図を読んでくれたのに劣化?していて使いにくい

やりたいこと

以下のイメージでCloudFormationテンプレートを作りたい

    1. RDSが起動イベントを
    1. EventBridgeが検知してLambdaを呼ぶ
    1. LambdaはRDSを停止する

ChatGPTのレスポンスが意図通りでなかったこと、説明が足りなかったこと

項目 対応
InstanceがRDSでなくEC2だと間違う 明記する(図にRDSから矢印を引いてinstanceと書いただけでは間違うらしい。。)
Lambdaの中身を書いてくれない inlineで書くように指示。RDSインスタンス名はLambda環境変数に
イベントが間違っている'StartDBInstanceCompleted'とは? "detail": { "EventID": ["RDS-EVENT-0088"] } を使うよう指示
RDSは別途 説明追加、RDSインスタンス名をパラメタで受け取る

できたコード

stop-rds-lambda-eventbridge.yaml
Parameters:
  RDSInstanceName:
    Description: 'Name of the existing RDS instance to monitor and stop'
    Type: String
    ConstraintDescription: 'Must be a valid RDS instance name.'

Resources:

  MyEventBridgeRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Description: 'Event rule for triggering Lambda on RDS start'
      EventPattern:
        source:
          - 'aws.rds'
        "detail-type":
          - 'RDS DB Instance Event'
        detail:
          EventID:
            - 'RDS-EVENT-0088'
          SourceIdentifier:
            - !Ref RDSInstanceName
      State: 'ENABLED'
      Targets:
        -
          Arn: !GetAtt MyLambdaFunction.Arn
          Id: 'MyLambdaTarget'

  MyLambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Handler: 'index.handler'
      Role: !GetAtt LambdaExecutionRole.Arn
      FunctionName: 'StopRDSFunction'
      Code:
        ZipFile: |
          import boto3
          import os

          def handler(event, context):
              rds = boto3.client('rds')
              db_instance_name = os.environ['DB_INSTANCE_NAME']
              rds.stop_db_instance(
                  DBInstanceIdentifier=db_instance_name
              )

      Runtime: 'python3.11'
      Timeout: '15'
      Environment:
        Variables:
          DB_INSTANCE_NAME: !Ref RDSInstanceName

  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: 'Allow'
            Principal:
              Service: 'lambda.amazonaws.com'
            Action: 'sts:AssumeRole'
      Policies:
        -
          PolicyName: 'MyPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              -
                Effect: 'Allow'
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: '*'
              -
                Effect: 'Allow'
                Action:
                  - 'rds:StopDBInstance'
                Resource: '*'

  LambdaPermissionForEvents:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: 'lambda:InvokeFunction'
      FunctionName: !Ref MyLambdaFunction
      Principal: 'events.amazonaws.com'
      SourceArn: !GetAtt MyEventBridgeRule.Arn

RDSを作る

create-rds.yaml
Parameters:
  RDSInstanceName:
    Description: "Name of the RDS instance to stop"
    Type: String
    ConstraintDescription: "Must be a valid RDS instance name."

Resources:
  MyDBInstance:
    Type: "AWS::RDS::DBInstance"
    Properties:
      DBInstanceIdentifier: !Ref RDSInstanceName
      AllocatedStorage: "5"
      DBInstanceClass: "db.t2.micro"
      Engine: "mysql"
      MasterUsername: "admin"
      MasterUserPassword: "password"

おまけ:絵をつかった会話はシェアできないらしい

プロンプトをシェアしようと思ったらできなかったです。

Apeendix

自分で使っているLambdaのコードです。
RDSでもClusterでも、availableになるまで待つ、、などとしています。

Discussion