Azure OpenAI Service（GPT-4o）で構成図からBicepのコードを生成

今回、Azure OpenAI Service（GPT-4o）で構成図からBicepのコードを生成してみましたので、その内容を投稿します。

## 概要
### 試したこと
以下の構成図を生成AIにインプットして、Bicepのコードを生成させることを試してみました。  
Azure Container Appsを作成して、ログをBlob Storageに出力する構成です。
Container Appsはフロントエンド用とバックエンド用の2つを作成します。

![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/9c3a1d32-23c2-39af-dfaa-4047f742936e.png)

### 検証環境
- Azure OpenAI Service(GPT-4o)
- Azure AI Studio

## 試したこと その１（単純に指示）
### GPT-4oへの指示
Azure AI Studioのチャットプレイグラウンドを利用して試しました。  
以下のように、ユーザプロンプトで、構成図を添付して単純な指示をしてみました。
> この構成をAzureにデプロイするAzure Bicepのコードを作成してください。  

実際の入力画面は以下の通りです。
![chat1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/30af4cb2-96c5-5076-35e7-65a5a657c20e.png)

### 生成されたBicepのコード
結果として以下のBicepのコードが生成されました。  
※ このコードは、生成AIが作成したもので、誤りがあります。なお、毎回同じコードが生成されるとは限りません。
<details><summary>生成されたBicepのコード</summary>

```bicep  
param location string = resourceGroup().location  
param containerAppEnvName string = 'containerappenv0603'  
param frontendAppName string = 'frontendapp0603'  
param backendAppName string = 'backendapp0603'  
param storageAccountName string = 'logblob0603'  
   
resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-01-01-preview' = {  
  name: containerAppEnvName  
  location: location  
  properties: {  
    appLogsConfiguration: {  
      logAnalyticsConfiguration: {  
        customerId: '<log-analytics-workspace-id>'  
        sharedKey: '<log-analytics-key>'  
      }  
    }  
  }  
}  
   
resource frontendApp 'Microsoft.App/containerApps@2022-01-01-preview' = {  
  name: frontendAppName  
  location: location  
  properties: {  
    managedEnvironmentId: containerAppEnv.id  
    configuration: {  
      ingress: {  
        external: true  
        targetPort: 80  
        transport: 'auto'  
      }  
    }  
    template: {  
      containers: [  
        {  
          name: frontendAppName  
          image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'  
          resources: {  
            cpu: 0.25  
            memory: '0.5Gi'  
          }  
        }  
      ]  
    }  
  }  
}  
   
resource backendApp 'Microsoft.App/containerApps@2022-01-01-preview' = {  
  name: backendAppName  
  location: location  
  properties: {  
    managedEnvironmentId: containerAppEnv.id  
    configuration: {  
      ingress: {  
        external: false  
        targetPort: 80  
        transport: 'auto'  
      }  
    }  
    template: {  
      containers: [  
        {  
          name: backendAppName  
          image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'  
          resources: {  
            cpu: 0.25  
            memory: '0.5Gi'  
          }  
        }  
      ]  
    }  
  }  
}  
   
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {  
  name: storageAccountName  
  location: location  
  sku: {  
    name: 'Standard_LRS'  
  }  
  kind: 'StorageV2'  
  properties: {}  
}  
```  
</details>
<br>

上記のBicepのコードは、なんとなく構成図を読み取って生成されているようですが、以下のような誤りがありました。
毎回同じコードが生成されるわけではない＆色々指示を変えてみましたが、このあたりはどうしても間違ってしまうようです。
- Container Apps環境のログが、LogAnalyticsに出力されるようになっている。  
appLogsConfiguration.destinationをazure-monitorに指定し、別途ログをBlob Storageに出力する設定が必要。  
参考：<cite>https://learn.microsoft.com/ja-jp/azure/templates/microsoft.app/managedenvironments?pivots=deployment-language-bicep#applogsconfiguration</cite>

- Container Appsのcpuで10 進数の値を指定する場合、 json() 関数の利用が必要。  
参考：<cite>https://learn.microsoft.com/ja-jp/azure/templates/microsoft.app/containerapps?pivots=deployment-language-bicep#containerresources</cite>

- 2022-01-01-previewは、japaneastでサポートされていない。


## 試したこと その２
### GPT-4oへの指示
システムプロンプト（システムメッセージ）に以下を追加しました。
> あなたはAzure Bicepのコードを記述するエンジニアです。Bicepのコードにはできるだけ新しいバージョンの仕様を利用します。誤りがないか慎重に確認して作成します。

また、ユーザプロンプトでは、以下のように間違いやすい部分を明示的に注意するように指示しました。
> この構成図の構成をAzureにデプロイするBicepのコードを作ってください。
その際、以下としてください。  
・リソースグループはデプロイコマンドで指定するように作成すること。  
・"AppLogsConfiguration.Destination"は、azure-monitorにすること。  
・Container Appsのcpuで10 進数の値を指定する場合、 json() 関数を使用すること。  
・APIのバージョンがサポートされているバージョンか確認すること。  
・特に指定がない場合は、Container Appsは既定のイメージを利用して作成すること。  
・Container Apps環境の診断設定（リソースログの設定）でログをストレージに出力するように設定すること。  

実際の入力画面は以下の通りです。
![chat2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/2e156ebb-fb6d-99b9-9bc6-ee71949d7338.png)

### 生成されたBicepのコード
結果として以下のコードが生成されました。  
※ このコードは生成AIが作成したものです。なお、毎回同じコードが生成されるとは限りません。

<details><summary>生成されたBicepのコード</summary>

```bicep  
param location string = resourceGroup().location  
param logStorageAccountName string = 'logblob0603'  
param containerAppEnvName string = 'containerAppEnv0603'  
param frontendAppName string = 'frontendapp0603'  
param backendAppName string = 'backendapp0603'  
  
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {  
  name: logStorageAccountName  
  location: location  
  sku: {  
    name: 'Standard_LRS'  
  }  
  kind: 'StorageV2'  
}  
  
resource containerAppEnv 'Microsoft.App/managedEnvironments@2022-10-01' = {  
  name: containerAppEnvName  
  location: location  
  properties: {  
    appLogsConfiguration: {  
      destination: 'azure-monitor'  
    }  
  }  
}  
  
resource frontendApp 'Microsoft.App/containerApps@2022-10-01' = {  
  name: frontendAppName  
  location: location  
  properties: {  
    managedEnvironmentId: containerAppEnv.id  
    configuration: {  
      ingress: {  
        external: true  
        targetPort: 80  
      }  
    }  
    template: {  
      containers: [  
        {  
          name: frontendAppName  
          image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'  
          resources: {  
            cpu: json('0.5')  
            memory: '1.0Gi'  
          }  
        }  
      ]  
    }  
  }  
}  
  
resource backendApp 'Microsoft.App/containerApps@2022-10-01' = {  
  name: backendAppName  
  location: location  
  properties: {  
    managedEnvironmentId: containerAppEnv.id  
    configuration: {  
      ingress: {  
        external: false  
        targetPort: 80  
      }  
    }  
    template: {  
      containers: [  
        {  
          name: backendAppName  
          image: 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'  
          resources: {  
            cpu: json('0.5')  
            memory: '1.0Gi'  
          }  
        }  
      ]  
    }  
  }  
}  
  
resource diagSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {  
  name: 'diagSettings'  
  scope: containerAppEnv  
  properties: {  
    logs: [  
      {  
        category: 'ContainerAppConsoleLogs'  
        enabled: true  
        retentionPolicy: {  
          enabled: false  
          days: 0  
        }  
      }  
    ]  
    storageAccountId: storageAccount.id  
  }  
}  
```  
</details>
<br>

### デプロイ結果
上記のコードをそのままデプロイしたところ、エラーなくデプロイできました。
- 以下の通り、構成図にある4つのリソースが作成されました。  
リソース名は特に指示していませんが、図に記載したリソース名がそのまま利用されています。  
Container Apps環境については、構成図にも名称を記載していませんでしたが、他のリソースに合わせて、0603というサフィックスが勝手についています！
![resouce01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/724293fd-7046-dac1-57c7-72cbac1c1cf9.png)

- Container Apps環境のログもBlob Storageに出力するように設定してくれています！
![log01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/82b27c7c-dfd3-3c5a-41c7-b0160cc9d033.png)
![log02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/90adcb55-3db8-80e2-4232-e15ba359486d.png)

- フロントエンドとして想定したContaier Appsは以下の通り、イングレスの設定でインターネットからアクセスできるようになっています！
![containerapp01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/c47b736e-52aa-ac70-df11-c07bfb1a7a9c.png)
インターネット経由でアプリにアクセスできます。
![containerapp02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/677c3203-ee41-bdca-a731-57394f4df595.png)

- バックエンドとして想定したContaier Appsは以下の通り、イングレスの設定でContainer Apps環境内からのアクセスのみに制限されています！
![containerapp03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/42674a75-a4ee-a4e3-cb8f-e0237ae12308.png)
意図した通り、インターネット経由ではアプリにアクセスできません。
![containerapp04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835827/4906992b-7eb4-86f0-f650-77f8811d313a.png)

## まとめ
今回は、Azure OpenAI Service（GPT-4o）で構成図からBicepのコードを生成しました。  
対象は、Azure Container Appsで、ログをBlob Storageに出力するような構成図でしたが、注意すべき点を明示的に指示することでそのままデプロイできるコードが生成できました（毎回、正しいコードが生成できるわけではありませんが）。  

なかなか思うようなコードが生成されない反面、特に指示せず、矢印だけで示していたフロントエンドとバックエンドが認識ができたのはすごいなと思いました。  
※ ただ、もしかしたら、名称をfrontendapp、backendappとしていたので、そこからも情報を読み取っていたのかもしれません。

細かな指示をユーザプロンプトで毎回指示するのは面倒なため、RAG等を使ってもう少し何とかならないかを確認し、次回投稿したいと思います。