[新サービス]自然言語からインフラ構成コード(IaC)を自動作成するPulumi AIを試してみた

AWS環境下で「CloudFront + S3」の構成を作成するため、Pulumi AIを使い自然言語からインフラ構成コードの自動作成を試してみました。
2023.04.24

はじめに

自然言語からインフラ構成コードを自動生成する Pulumi AIを含む、AIを活用した新サービス群「Pulumi Insights」が発表されました

Pulumi AIでは、Pulumiが学習させたChatGPT大規模言語モデル(LLM)を使用して、自然言語のプロンプトに基づき、PythonやTypeScriptなどのプログラミング言語で、AWSなどのパブリッククラウドのインフラ構成コードを自動生成します。

今回は、AWSで「CloudFront + S3」 のインフラ構成コードをエラーなく自動生成してくれるか試してみました。

以下の流れで進めます。

  1. Pulumi AIでコードを自動生成する
  2. Pulumiのプロジェクトを作成
  3. 自動作成されたコードを修正
  4. デプロイ

Pulumi AIでコードを自動生成する

こちらのサイトにアクセスします。

日本語に対応していないので、Static site using CloudFront and S3 (runtime is yaml)(CloudFrontとS3を使って静的サイト)と入力すると、以下のように、自動生成されたコードとコードの概要文が生成されました。

ランタイムを指定していない場合、node.jsやpythonを指定されることがあるため、yamlを指定します

今回のPulumiプログラムでは、AWS CloudFrontとAmazon S3を使って静的なウェブサイトを作成します。

説明:

静的なウェブサイトのファイルを保存するためのAmazon S3バケットを作成します。 S3バケットをオリジンとするAWS CloudFrontディストリビューションを構成する。 S3バケットにpublic read permissionを設定します。 CloudFrontのWebドメインとS3バケット名をエクスポートします。

Pulumi AIで自動生成されたコード(クリックすると展開します)
name: static-website
runtime: python
description: A static website using AWS CloudFront and Amazon S3

resources:
  - name: s3_bucket
    type: aws:s3/bucket:Bucket
    properties:
      acl: "public-read"
      website:
        indexDocument: "index.html"
        errorDocument: "error.html"

  - name: origin_access_identity
    type: aws:cloudfront/originAccessIdentity:OriginAccessIdentity

  - name: cloudfront_distribution
    type: aws:cloudfront/distribution:Distribution
    properties:
      enabled: true
      defaultRootObject: "index.html"
      origins:
        - domainName: $s3_bucket.website_endpoint.apply
          originId: "S3Origin"
          s3OriginConfig:
            originAccessIdentityId: $origin_access_identity.iam_arn.apply
            originAccessIdentityPath: $origin_access_identity.cloudfront_access_identity_path.apply
      defaultCacheBehavior:
        targetOriginId: "S3Origin"
        forwardedValues:
          queryString: false
          cookies:
            forward: "none"
        viewerProtocolPolicy: "redirect-to-https"
        minTtl: 0
        defaultTtl: 3600
        maxTtl: 86400
      viewerCertificate:
        cloudFrontDefaultCertificate: true

outputs:
  - name: cloudfront_web_domain
    value: $cloudfront_distribution.domain_name
  - name: s3_bucket_name
    value: $s3_bucket.id

ランタイムは、yamlを指定したのですが、pythonになっていますね。。

プロジェクトを作成

Pulumiを一度も触ったことがない方は、チュートリアルを試すことをおすすめします。

Pulumiでプロジェクトを作成します。

$ mkdir pulumi-s3-cf && cd pulumi-s3-cf
pulumi-s3-cf/ $ pulumi new aws-yaml
project name: (pulumi-s3-cf) 
project description: (A minimal AWS Pulumi YAML program) Static site using CloudFront and S3

stack name: (dev) 
Created stack 'dev'

aws:region: The AWS region to deploy into: (us-east-1) ap-northeast-1

Pulumi.yamlPulumi.dev.yamlが作成されます。

自動作成されたコードを修正

以下の通りに、コードを修正します。

Pulumi.yamlは、Pulumi AIで自動生成されたコードをコピペしますが、nameruntimeのみ修正します。(1~2行目を修正)

それぞれ、pulumi-s3-cfyamlに変えています。

Pulumi AIで自動生成されたコード(1~2行目を修正)(クリックすると展開します)
name: pulumi-s3-cf
runtime: yaml
description: A static website using AWS CloudFront and Amazon S3

resources:
  - name: s3_bucket
    type: aws:s3/bucket:Bucket
    properties:
      acl: "public-read"
      website:
        indexDocument: "index.html"
        errorDocument: "error.html"

  - name: origin_access_identity
    type: aws:cloudfront/originAccessIdentity:OriginAccessIdentity

  - name: cloudfront_distribution
    type: aws:cloudfront/distribution:Distribution
    properties:
      enabled: true
      defaultRootObject: "index.html"
      origins:
        - domainName: $s3_bucket.website_endpoint.apply
          originId: "S3Origin"
          s3OriginConfig:
            originAccessIdentityId: $origin_access_identity.iam_arn.apply
            originAccessIdentityPath: $origin_access_identity.cloudfront_access_identity_path.apply
      defaultCacheBehavior:
        targetOriginId: "S3Origin"
        forwardedValues:
          queryString: false
          cookies:
            forward: "none"
        viewerProtocolPolicy: "redirect-to-https"
        minTtl: 0
        defaultTtl: 3600
        maxTtl: 86400
      viewerCertificate:
        cloudFrontDefaultCertificate: true

outputs:
  - name: cloudfront_web_domain
    value: $cloudfront_distribution.domain_name
  - name: s3_bucket_name
    value: $s3_bucket.id

デプロイ

デプロイしてみます。

pulumi-s3-cf/ $ pulumi up

error: failed to discover plugin requirements: 
-error: Pulumi.yaml:6,3-39,43: resources must be an object; 
-error: Pulumi.yaml:42,3-45,25: outputs must be an object;

エラーになりました。

エラー文をそのままペーストして、[Update program]をクリックしますと、エラー文から、修正したコードが自動生成されます。

お詫び文を頂きました。

前回の回答の構文エラーについてお詫び申し上げます。 AWS CloudFront と Amazon S3 を使用して静的ウェブサイトを作成するための修正済み Pulumi YAML プログラムを次に示します。

説明:

静的ウェブサイト ファイルを保存するための Amazon S3 バケットを作成します。 S3 バケットをオリジンとして AWS CloudFront ディストリビューションを設定します。 S3 バケットにパブリック読み取り権限を設定します。 CloudFront ウェブドメインと S3 バケット名をエクスポートします。

Pulumi AIで自動生成されたコード(1~2行目のみ修正)(クリックすると展開します)
name: pulumi-s3-cf
runtime: yaml
description: A static website using AWS CloudFront and Amazon S3

resources:
  s3_bucket:
    type: aws:s3/bucket:Bucket
    properties:
      acl: "public-read"
      website:
        indexDocument: "index.html"
        errorDocument: "error.html"

  origin_access_identity:
    type: aws:cloudfront/originAccessIdentity:OriginAccessIdentity

  cloudfront_distribution:
    type: aws:cloudfront/distribution:Distribution
    properties:
      enabled: true
      defaultRootObject: "index.html"
      origins:
        - domainName: $s3_bucket.website_endpoint.apply
          originId: "S3Origin"
          s3OriginConfig:
            originAccessIdentityId: $origin_access_identity.iam_arn.apply
            originAccessIdentityPath: $origin_access_identity.cloudfront_access_identity_path.apply
      defaultCacheBehavior:
        targetOriginId: "S3Origin"
        forwardedValues:
          queryString: false
          cookies:
            forward: "none"
        viewerProtocolPolicy: "redirect-to-https"
        minTtl: 0
        defaultTtl: 3600
        maxTtl: 86400
      viewerCertificate:
        cloudFrontDefaultCertificate: true

outputs:
  cloudfront_web_domain:
    value: $cloudfront_distribution.domain_name
  s3_bucket_name:
    value: $s3_bucket.id

再度デプロイすると、またエラーが出ました。

pulumi-s3-cf/ $ pulumi up
    Error: aws:cloudfront/distribution:Distribution is not assignable from {enabled: boolean, defaultRootObject: string, origins: List<{domainName: string, originId: string, s3OriginConfig: {originAccessIdentityId: string, originAccessIdentityPath: string}}>, defaultCacheBehavior: {targetOriginId: string, forwardedValues: {queryString: boolean, cookies: {forward: string}}, viewerProtocolPolicy: string, minTtl: number, defaultTtl: number, maxTtl: number}, viewerCertificate: {cloudFrontDefaultCertificate: boolean}}
    Cannot assign '{enabled: boolean, defaultRootObject: string, origins: List<{domainName: string, originId: string, s3OriginConfig: {originAccessIdentityId: string, originAccessIdentityPath: string}}>, defaultCacheBehavior: {targetOriginId: string, forwardedValues: {queryString: boolean, cookies: {forward: string}}, viewerProtocolPolicy: string, minTtl: number, defaultTtl: number, maxTtl: number}, viewerCertificate: {cloudFrontDefaultCertificate: boolean}}' to 'aws:cloudfront/distribution:Distribution':
      defaultCacheBehavior: Cannot assign '{targetOriginId: string, forwardedValues: {queryString: boolean, cookies: {forward: string}}, viewerProtocolPolicy: string, minTtl: number, defaultTtl: number, maxTtl: number}' to 'aws:cloudfront/DistributionDefaultCacheBehavior:DistributionDefaultCacheBehavior':
        allowedMethods: Missing required property 'allowedMethods'
        cachedMethods: Missing required property 'cachedMethods'
      origins: Cannot assign 'List<{domainName: string, originId: string, s3OriginConfig: {originAccessIdentityId: string, originAccessIdentityPath: string}}>' to 'List<aws:cloudfront/DistributionOrigin:DistributionOrigin>':
        Cannot assign '{domainName: string, originId: string, s3OriginConfig: {originAccessIdentityId: string, originAccessIdentityPath: string}}' to 'aws:cloudfront/DistributionOrigin:DistributionOrigin':
          s3OriginConfig: Cannot assign '{originAccessIdentityId: string, originAccessIdentityPath: string}' to 'aws:cloudfront/DistributionOriginS3OriginConfig:DistributionOriginS3OriginConfig':
            originAccessIdentity: Missing required property 'originAccessIdentity'
            Existing properties are: originAccessIdentity
            Existing properties are: originAccessIdentity
      restrictions: Missing required property 'restrictions'
      viewerCertificate: Cannot assign '{cloudFrontDefaultCertificate: boolean}' to 'aws:cloudfront/DistributionViewerCertificate:DistributionViewerCertificate':
        Existing properties are: cloudfrontDefaultCertificate, iamCertificateId, acmCertificateArn, minimumProtocolVersion, sslSupportMethod

「エラー文を入力し、コードを自動生成し、デプロイする」、を繰り返しましたが、結局、自動生成のみでうまくでデプロイは、できませんでした。

自動生成されたコードを確認し、人が一部修正する必要があるようです。

自動生成のコードでデプロイできた例

自動生成のコードのみでうまくデプロイできた内容は、以下です。

Create one s3 bucket. Lifecycle policy to expire objects after 1 week. (1 つの s3 バケットを作成します。 1 週間後にオブジェクトを期限切れにするライフサイクル ポリシー)

シンプルな構成の場合、「再度エラー文を入力し、コードを自動生成」、を繰り返すとデプロイできました。

Pulumi AIで自動生成されたコード(1~3行目は追加)(クリックすると展開します)
name: pulumi-s3-cf
runtime: yaml

resources:
  bucket:
    type: aws:s3:Bucket
    properties:
      acl: private
      lifecycleRules:
        - enabled: true
          id: expire-rule
          expiration:
            days: 7

注意点

下記の画像の通り、Connected中は、エラー文を入力し、[UPdate program]で、コードを修正してもらえますが、言って時間が過ぎると、Disconnectedとなり、聞き返すことができなくなるのが、注意点です。

最後に

今回、Pulumi AIで自然言語からインフラ構成コードの自動生成を試してみましたが、複雑な構成は、人での修正が必要でした。

自然言語での伝え方や、他のプログラミング言語、他のクラウドサービスだと結果が異なったかもしれません。

ユーザーが使えば使うほど賢くなりますので、将来的には、複雑な構成もエラーなく作成されるクオリティになってくれることに期待しましょう。

参考