インフラエンジニアがChatGPTを触ってみた

インフラエンジニアがChatGPTを触ってみた

この記事は 弥生 Advent Calender 2023 の19日目の記事です。

こんにちは。弥生のインフラチームでエンジニアをしているツジノです。いつもはクラウド環境のインフラをメインで担当しており、たまにオンプレ環境も触っていたりします。

さて、最近技術系のトレンドによくAIに関するワードが多いですよね。

その注目度はあのビル・ゲイツもAIはグラフィカルユーザーインターフェース以来の革命的な進歩といったコメントを残しているぐらいです。

今回はその話題なAI関連の中からChatGPTをインフラエンジニアが触れてみた記事となります。

チーム内のMTGでも『これはAIを活用できないか』といった会話が増えて来ており、一度触れてみたいと思っていたところにAdvent Calenderの時期となったため、それなら記事にしちゃえ!と思ったのがきっかけです。

よければ最後までお付き合いください。

ChatGPTでIaC

AzureやAWSにはIaC*1に使用できるARMテンプレートやCloudFormationがありますが、今回は私が良く使用する環境であるAzureのARMテンプレートで試そうと思います。

まずは簡単なAzureStorageAccountを作成できるか試してみます。

入力情報:Azure上でAzureStorageAcountを作成するARMテンプレートを作成してください。

出力情報

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "family": "A",
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    }
  ],
  "parameters": {
    "storageAccountName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Azure Storage Account."
      }
    },
    "resourceGroupName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Azure Resource Group."
      }
    }
  },
  "outputs": {
    "storageAccountId": {
      "type": "string",
      "value": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    }
  }
}

単一リソースの作成だったので問題なくリソース作成することができました!

storage-001

次は複数リソースを必要とする指示を出してみます。

内容としては、以下を試してみます。

VnetとSubNetを新規作成し、そのサブネットにプライベートエンドポイントを持つAzureStorageAccount

入力情報

Azure上で以下リソースを新規作成するARMテンプレートを作成してください。
・リソース
Vnet:vnet001
Subnet:subnet001
StorageAccount:acstorageaccount001
PrivateEndPoint:pep001(subnet001に属し、acstorageaccount001に紐づけるリソースとする)

出力情報

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    // 1. Virtual Network (VNet)
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2021-05-01",
      "name": "[parameters('vnetName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": ["10.0.0.0/16"]
        }
      }
    },
   
    // 2. Subnet in the Virtual Network
    {
      "type": "Microsoft.Network/virtualNetworks/subnets",
      "apiVersion": "2021-05-01",
      "name": "[concat(parameters('vnetName'), '/subnet001')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
      ],
      "properties": {
        "addressPrefix": "10.0.1.0/24"
      }
    },

    // 3. Storage Account
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "family": "A",
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    },

    // 4. Private Endpoint
    {
      "type": "Microsoft.Network/privateEndpoints",
      "apiVersion": "2021-05-01",
      "name": "[parameters('privateEndpointName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), 'subnet001')]",
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
      ],
      "properties": {
        "subnet": {
          "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), 'subnet001')]"
        },
        "privateLinkServiceConnections": [
          {
            "name": "[parameters('privateEndpointConnectionName')]",
            "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
            "groupIds": ["blob"]
          }
        ]
      }
    }
  ],
  "parameters": {
    "vnetName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Virtual Network."
      }
    },
    "storageAccountName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Storage Account."
      }
    },
    "privateEndpointName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Private Endpoint."
      }
    },
    "privateEndpointConnectionName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Private Endpoint Connection."
      }
    }
  }
}

PrivateEndpointの所でエラーになりましたね。

error-001

エラー箇所を調べてみるとが学習元と思われるMSのドキュメントが見つかりました。

StorageAccountのPrivateEndpointのドキュメントを見てみると構文が異なるようです。

修正しデプロイしてみます。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    // 1. Virtual Network (VNet)
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2021-05-01",
      "name": "[parameters('vnetName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": ["10.0.0.0/16"]
        }
      }
    },
   
    // 2. Subnet in the Virtual Network
    {
      "type": "Microsoft.Network/virtualNetworks/subnets",
      "apiVersion": "2021-05-01",
      "name": "[concat(parameters('vnetName'), '/subnet001')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnetName'))]"
      ],
      "properties": {
        "addressPrefix": "10.0.1.0/24"
      }
    },

    // 3. Storage Account
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2019-06-01",
      "name": "[parameters('storageAccountName')]",
      "location": "[resourceGroup().location]",
      "sku": {
        "family": "A",
        "name": "Standard_LRS"
      },
      "kind": "StorageV2",
      "properties": {
        "accessTier": "Hot"
      }
    },

    // 4. Private Endpoint
    {
    "type": "Microsoft.Network/privateEndpoints",
    "apiVersion": "2023-06-01",
    "name": "[parameters('privateEndpointName')]",
    "location": "japaneast",
    "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnetName'), 'subnet001')]",
        "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"
    ],
    "properties": {
        "privateLinkServiceConnections": [
            {
                "name": "[parameters('privateEndpointName')]",
                "id": "[concat(resourceId('Microsoft.Network/privateEndpoints', parameters('privateEndpointName')), concat('/privateLinkServiceConnections/', parameters('privateEndpointName')))]",
                "properties": {
                    "privateLinkServiceId": "[extensionResourceId(resourceGroup().Id , 'Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
                    "groupIds": [
                        "blob"
                    ],
                    "privateLinkServiceConnectionState": {
                        "status": "Approved",
                        "description": "Auto-Approved",
                        "actionsRequired": "None"
                    }
                }
            }
        ],
        "manualPrivateLinkServiceConnections": [],
        "subnet": {
            "id": "[concat(extensionResourceId(resourceGroup().Id , 'Microsoft.Network/virtualNetworks', parameters('vnetName')), '/subnets/subnet001')]"
        },
        "ipConfigurations": [],
        "customDnsConfigs": []
    }
   }
  ],
  "parameters": {
    "vnetName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Virtual Network."
      }
    },
    "storageAccountName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Storage Account."
      }
    },
    "privateEndpointName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Private Endpoint."
      }
    },
    "privateEndpointConnectionName": {
      "type": "string",
      "metadata": {
        "description": "Name of the Private Endpoint Connection."
      }
    }
  }
}

デプロイ成功しました!(StorageAccountはリソースを作り直している際に削除しても001、002が既に使用されてしまったため003となっています)

storage-002

StorageAccountを見てみるとちゃんとプライベートエンドポイントが紐づいており、プライベートエンドポイントもVnet/Subnetと紐づいています。

storage-003

結果

簡単な指示でも単一リソースならば出力結果をそのままデプロイしても問題なくリソースを作成できましたが、複数リソースとなると簡単な指示では手直しが必要となりました。

実際にサービスが稼働する環境を作ろうとした場合、今回の作成したリソースの数倍はリソースが必要となる事が普通です。

そのためまだ簡単な指示だけではサービスを稼働させられるような環境を構築する出力は難しそうです。

しかし、今回のような簡単な指示で手直しが必要とは言え複数リソースの作成とその紐づけをデプロイできるということは、作成・削除が頻繁に行われる検証環境作成などには十分活用できると思いました。

おわりに

今回はChatGPTでIaCができないか簡単に触ってみました。

最新版ではない無償版のChatGPT3.5を使用してみましたが、思ったより精度の高い出力結果が出てきて驚きました。

本記事ではIaCを試しましたが、構築だけでなく監視や分析など他の仕事でも活用できる場所がないか探っていきたいと思います。

一緒に働く仲間を募集しています

弥生のエンジニアとして一緒に働いてみませんか?

herp.careers

*1:IaC(Infrastructure as Code)とは、サーバーなどのシステムインフラの構築を、コードを用いて行うことです。