ChatGPTにCloudformationのテンプレート作成を手伝ってもらった

711
ChatGPTにCloudformationのテンプレート作成を手伝ってもらった

最近話題のChatGPTがどれぐらい便利なのか試してみようと思った矢先、丁度良さそうな題材が見つかったので試してみた。(注:ChatGPT Plus未使用)

要件

  • Cloudformationに2つのパラメーターを持たせる
  • どちらも指定されていなければエラーとする

AWSのCloudformation関係のドキュメントを読んでいけば確実にわかるとは思うものの、こういった既知の情報だが調べるのが手間といったものには力を発揮しそうなので、試しにChatGPTに質問を投げてみた。

ChatGPTとの対話(1回目)

私:「Cloudformationで、パラメーターAとBどちらかを必ず指定しなければいけないという制約を持たせるための書き方。」

ChatGPT:

CloudFormationでパラメーターAとBのどちらかを必ず指定するようにするには、ConditionsセクションとFn::And関数を使用することができます。
以下は、パラメーターAとBのどちらかが指定されていない場合にエラーを発生させる例です。

Parameters:
  ParameterA:
    Type: String
    Default: ''
  ParameterB:
    Type: String
    Default: ''

Conditions:
  EitherParameterAOrB:
    Fn::Or:
      - !Not [!Equals [!Ref ParameterA, '']]
      - !Not [!Equals [!Ref ParameterB, '']]

Resources:
  MyResource:
    Type: AWS::SomeResourceType
    Properties:
      ...

  MyConstraint:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/cloudformation-templates-us-east-1/...
      Parameters:
        ParameterA: !If [EitherParameterAOrB, !Ref ParameterA, '']
        ParameterB: !If [EitherParameterAOrB, !Ref ParameterB, '']
Parameters:
  ParameterA:
    Type: String
    Default: ''
  ParameterB:
    Type: String
    Default: ''
Conditions:
  EitherParameterAOrB:
    Fn::Or:
      - !Not [!Equals [!Ref ParameterA, '']]
      - !Not [!Equals [!Ref ParameterB, '']]

Resources:
  MyResource:
    Type: AWS::SomeResourceType
    Properties:
      ...

  MyConstraint:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: https://s3.amazonaws.com/cloudformation-templates-us-east-1/...
      Parameters:
        ParameterA: !If [EitherParameterAOrB, !Ref ParameterA, '']
        ParameterB: !If [EitherParameterAOrB, !Ref ParameterB, '']

この例では、ConditionsセクションにEitherParameterAOrBという条件を定義し、Fn::Or関数を使用して、パラメーターAまたはBが指定されているかどうかを確認しています。

MyConstraintという名前のスタックを定義しています。このスタックは、TemplateURLパラメーターで指定されたテンプレートに基づいて作成されます。Parametersセクションで、パラメーターAとBを定義しています。!If関数を使用して、EitherParameterAOrB条件が真である場合には、!Ref関数を使用してパラメーターAまたはBの値を取得し、条件が偽である場合には空文字列を渡します。これにより、パラメーターAとBのどちらかが指定されていない場合にエラーが発生します。

うーむ、質問が大雑把すぎたのか、「確かに合ってるかもしれないが、そうじゃない」答えが返ってきてしまった。

回答の再生成ができるようなので、もう一回だけ試してみる。(これでだめなら質問を変える。)

ChatGPTとの対話(2回目)

ChatGPT:

CloudFormationでパラメーターAとBのうち少なくとも1つが必要であるという制約を定義するには、次のように書くことができます。

"Parameters": {
  "A": {
    "Type": "String",
    "Description": "Parameter A"
  },
  "B": {
    "Type": "String",
    "Description": "Parameter B"
  }
},
"Conditions": {
  "AtLeastOneParameter": {
    "Fn::Or": [
      {"Fn::Not": [{"Fn::Equals": [{"Ref": "A"}, ""]} ]},
      {"Fn::Not": [{"Fn::Equals": [{"Ref": "B"}, ""]} ]}
    ]
  }
},
"Rules": {
  "AtLeastOneRule": {
    "Assertions": [
      {
        "Assert": {
          "Fn::Equals": [
            {"Fn::Length": [{"Fn::Join": ["", [{"Ref": "A"}, {"Ref": "B"}]]}]},
            {"Fn::If": ["AtLeastOneParameter", {"Fn::ValueOf": "true"}, "0"]}
          ]
        }
      }
    ]
  }
}

上記のテンプレートでは、Parameters でパラメーター A と B を定義し、Conditions で少なくとも1つのパラメーターが入力されているかどうかをチェックする AtLeastOneParameter 条件を定義します。Rules で、AtLeastOneRule ルールを定義し、AtLeastOneParameter 条件が true である場合、A と B の合計の長さが 0 より大きくなければならないことをアサートします。

このテンプレートを使用すると、パラメーター A と B のうちどちらかを必ず指定するように、CloudFormation スタックを作成することができます。

おお、これはかなり希望した答えに近くなった。Cloudformationでパラメーターへの制約などをどうやって実現するのかこれまでやった事がなかったが、AWSのドキュメントと突き合わせるとRulesセクションを利用すればよいようだ。

ただ出力がYAMLではないのが少々惜しいので、YAML版をお願いしてみよう。

ChatGPTとの対話(3回目)

私:上記の出力のYAML形式

ChatGPT:

上記のCloudFormationテンプレートの出力をYAML形式で表現すると、以下のようになります。

Parameters:
  A:
    Type: String
    Description: Parameter A
  B:
    Type: String
    Description: Parameter B

Condtions:
  AtLeastOneParameter:
    Fn::Or:
      - Fn::Not:
          - Fn::Equals:
              - - Ref: A
              - ''
      - Fn::Not:
          - Fn::Equals:
              - - Ref: B
              - ''

Rules:
  AtLeastOneRule:
    Assertions:
      - Assert:
          Fn::Equals:
            - Fn::Length:
                - Fn::Join:
                    - ''
                    - - Ref: A
                      - Ref: B
            - Fn::If:
                - AtLeastOneParameter
                - Fn::ValueOf: 'true'
                - '0'

上記のように、CloudFormationのテンプレートは、JSONまたはYAML形式で記述することができます。ただし、どちらの形式でも、構文が正しくなければスタックを作成できないため、記述する際には注意が必要です。

ChatGPT自体はステートレスらしいが、一連のチャットの流れは(制限こそあるようだが)保持して解析する事で、状態をもって対話しているように見えるようだ。

手直し

とはいえ上記のスニペットをそのまま使っても上手い事動作してくれないというか構文エラーになったので、最終的には以下のような形に書き換える事になった。

Rules:
  AtLeastOneRule:
    Assertions:
      - Assert:
          Fn::Or:
            - Fn::Not:
                - Fn::Equals:
                    - !Ref A
                    - ''
            - Fn::Not:
                - Fn::Equals:
                    - !Ref B
                    - ''

そもそもConditionsで条件を持っておかずとも、Rulesで1回アサーションをかけられれば要件は満たせるので、これで良しとする。

感想

  • 出力結果は直接使えなかったが、それでも公式のドキュメントと突き合わせることでやりたかった事に手早く辿り着けた。
  • 自力で最初から書いてもトライアンドエラーなのは同じなので、その手間を大きく軽減できるだけでも優れものに思える。

余談、あるいはお遊び

私:What scale is used in classic death metal?(古典的なデスメタルで使われるスケールは何?)

ChatGPT

In classic death metal, the most commonly used scale is the Phrygian dominant scale. This scale is characterized by its dark and menacing sound, which is well-suited to the aggressive and extreme style of classic death metal. The Phrygian dominant scale is a seven-note scale that is similar to the natural minor scale, but with a raised third and a lowered sixth. It is often used to create dissonant and unsettling harmonies that contribute to the intense and chaotic sound of classic death metal. Other scales, such as the harmonic minor and diminished scales, are also sometimes used in death metal music to create a similar effect.

古典的なデスメタルでは、最も一般的に使用されるスケールはフリジアン・ドミナント・スケールです。このスケールは暗く脅威的なサウンドで特徴付けられ、クラシックデスメタルの攻撃的で極端なスタイルに適しています。フリジアン・ドミナント・スケールは7つの音から成るスケールで、ナチュラルマイナースケールに似ていますが、3度が上がり、6度が下がっています。古典的なデスメタルの激しいカオティックなサウンドに貢献する不協和音や不安定なハーモニーを作り出すためによく使われます。同様の効果を作り出すために、ハーモニックマイナーやディミニッシュスケールなどの他のスケールもデスメタル音楽で時々使用されます。

残念、コンビネーション・オブ・ディミニッシュとクロマチックが言及されていない。数回回答を生成し直したものの、コンビネーション・オブ・ディミニッシュへの言及は終ぞなかった。このように明らかな間違いあるいは欠落を平然と提示してくるので、やはり利用者には出力の真偽や良し悪しを見定める能力が必要という事で良さそうだ。