🦔

【MS Learn】Azure Kubernetes Service のデプロイ パイプラインと GitHub Actions をやってみた

2023/10/10に公開

はじめに

やってみたシリーズです。

今日はこちら
https://learn.microsoft.com/ja-jp/training/modules/aks-deployment-pipeline-github-actions/

手を動かすところだけ記述していきます。
番号とかは飛び飛びになりますので、ご本家様と照らし合わせてみていただけると幸いです。

Azure Cloud Shellのbashで実行しています。

ユニット4: 演習 - プロジェクトを設定する

プロジェクトのセットアップ

  1. サンプル リポジトリを自分のアカウントにフォークします。

https://github.com/MicrosoftDocs/mslearn-aks-deployment-pipeline-github-actions
GitHub

以後、forkした自分のリポジトリに対して作業していきます。

  1. Azure Cloud Shell を開きます。
  2. フォークしたリポジトリをクローンします。
Azure Cloud Shell
$ git clone https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions.git
Cloning into 'mslearn-aks-deployment-pipeline-github-actions'...
remote: Enumerating objects: 116, done.
remote: Total 116 (delta 0), reused 0 (delta 0), pack-reused 116
Receiving objects: 100% (116/116), 221.87 KiB | 10.57 MiB/s, done.
Resolving deltas: 100% (44/44), done.

4-5. プロジェクトのルートにある init.sh ファイルを実行します。
以下のタスクが実行されるようです。

・環境変数 AKS_NAME、DNS_NAME、RESOURCE_GROUP_NAME、ACR_NAME を設定します。 これらの変数は、作成するリソースの名前です。
・新しいリソース グループを作成します。
・新しい AKS クラスターを作成し、それにアクセスするように Kubectl を設定します。
・新しい Container Registry リポジトリを作成し、それを AKS クラスターにリンクします。

Azure Cloud Shell
$ cd mslearn-aks-deployment-pipeline-github-actions/
$ ./init.sh 
Defining variables...
Searching for resource group...
{
  "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mslearn-gh-pipelines-31129",
  "location": "eastus",
  "managedBy": null,
  "name": "mslearn-gh-pipelines-31129",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}
Creating cluster...
{
  "aadProfile": null,
  "addonProfiles": {
    "httpApplicationRouting": {
      "config": {
        "HTTPApplicationRoutingZoneName": "d882b2f44982432e97cf.japaneast.aksapp.io"
      },
      "enabled": true,
      "identity": {
        "clientId": "a80d3475-6e3c-4b7b-a54c-1c4e2b5d101b",
        "objectId": "23062433-4a77-4d88-831a-fe7ffe76c6bb",
        "resourceId": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.ManagedIdentity/userAssignedIdentities/httpapplicationrouting-contoso-video"
      }
    }
  },
  "agentPoolProfiles": [
    {
      "availabilityZones": null,
      "count": 1,
      "creationData": null,
      "currentOrchestratorVersion": "1.26.6",
      "enableAutoScaling": false,
      "enableEncryptionAtHost": false,
      "enableFips": false,
      "enableNodePublicIp": false,
      "enableUltraSsd": false,
      "gpuInstanceProfile": null,
      "hostGroupId": null,
      "kubeletConfig": null,
      "kubeletDiskType": "OS",
      "linuxOsConfig": null,
      "maxCount": null,
      "maxPods": 110,
      "minCount": null,
      "mode": "System",
      "name": "nodepool1",
      "nodeImageVersion": "AKSUbuntu-2204gen2containerd-202309.06.0",
      "nodeLabels": null,
      "nodePublicIpPrefixId": null,
      "nodeTaints": null,
      "orchestratorVersion": "1.26.6",
      "osDiskSizeGb": 128,
      "osDiskType": "Managed",
      "osSku": "Ubuntu",
      "osType": "Linux",
      "podSubnetId": null,
      "powerState": {
        "code": "Running"
      },
      "provisioningState": "Succeeded",
      "proximityPlacementGroupId": null,
      "scaleDownMode": null,
      "scaleSetEvictionPolicy": null,
      "scaleSetPriority": null,
      "spotMaxPrice": null,
      "tags": null,
      "type": "VirtualMachineScaleSets",
      "upgradeSettings": {
        "drainTimeoutInMinutes": null,
        "maxSurge": null
      },
      "vmSize": "Standard_B2s",
      "vnetSubnetId": null,
      "workloadRuntime": null
    }
  ],
  "apiServerAccessProfile": null,
  "autoScalerProfile": null,
  "autoUpgradeProfile": {
    "nodeOsUpgradeChannel": "NodeImage",
    "upgradeChannel": null
  },
  "azureMonitorProfile": null,
  "azurePortalFqdn": "contoso-video-rsrf8qus.portal.hcp.japaneast.azmk8s.io",
  "currentKubernetesVersion": "1.26.6",
  "disableLocalAccounts": false,
  "diskEncryptionSetId": null,
  "dnsPrefix": "contoso-video",
  "enablePodSecurityPolicy": null,
  "enableRbac": true,
  "extendedLocation": null,
  "fqdn": "contoso-video-rsrf8qus.hcp.japaneast.azmk8s.io",
  "fqdnSubdomain": null,
  "httpProxyConfig": null,
  "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/mslearn-gh-pipelines-31129/providers/Microsoft.ContainerService/managedClusters/contoso-video",
  "identity": {
    "delegatedResources": null,
    "principalId": "018e7b66-62fe-43e6-bd87-d14f87ab1ec3",
    "tenantId": "cb9bb346-c037-4fb2-a3ff-dd23544753ea",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  },
  "identityProfile": {
    "kubeletidentity": {
      "clientId": "e4b5a7eb-08b4-47e5-b267-9ddd3b42fe33",
      "objectId": "ba2ecebd-f658-4dad-a349-42178b793e03",
      "resourceId": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.ManagedIdentity/userAssignedIdentities/contoso-video-agentpool"
    }
  },
  "kubernetesVersion": "1.26.6",
  "linuxProfile": {
    "adminUsername": "azureuser",
    "ssh": {
      "publicKeys": [
        {
          "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtlQI5JNtID9FT9ei748fLS8yiwL94XmBPoXsxv9UGFe3ZilBzAtPUara5AXKVHDiHcPyLuXTq6iLbbC1tvVidf1BsH/lwFFSjz/z7aSAS2I84dAu5E/+AYg6azipYYtWzcCwIPfhaP0FqgtEOb0+Cvf1DgZ2tmUfOlg2qY0PdfrTU7Pf5cpCK46+zLhqQL7HpZNi/CHQrtU5TiSU6gU2gUy0/tOvlvUh4T+ipR+yH51Y2XF5v0Szy8c1brSOJ4VpO8sdxLycSw2QYOMbuv0Pxjg8YIv5yKbGxjKVOCn6Mp8QwOgYj1BeEdpUr4Lz2/ZuFlJoTNcPQSkxCjVI0VtRF"
        }
      ]
    }
  },
  "location": "japaneast",
  "maxAgentPools": 100,
  "name": "contoso-video",
  "networkProfile": {
    "dnsServiceIp": "10.0.0.10",
    "ipFamilies": [
      "IPv4"
    ],
    "loadBalancerProfile": {
      "allocatedOutboundPorts": null,
      "effectiveOutboundIPs": [
        {
          "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.Network/publicIPAddresses/1a7b552e-3a6a-44ed-8b0e-b2930ac7d385",
          "resourceGroup": "MC_mslearn-gh-pipelines-31129_contoso-video_japaneast"
        }
      ],
      "enableMultipleStandardLoadBalancers": null,
      "idleTimeoutInMinutes": null,
      "managedOutboundIPs": {
        "count": 1,
        "countIpv6": null
      },
      "outboundIPs": null,
      "outboundIpPrefixes": null
    },
    "loadBalancerSku": "Standard",
    "natGatewayProfile": null,
    "networkDataplane": null,
    "networkMode": null,
    "networkPlugin": "kubenet",
    "networkPluginMode": null,
    "networkPolicy": null,
    "outboundType": "loadBalancer",
    "podCidr": "10.244.0.0/16",
    "podCidrs": [
      "10.244.0.0/16"
    ],
    "serviceCidr": "10.0.0.0/16",
    "serviceCidrs": [
      "10.0.0.0/16"
    ]
  },
  "nodeResourceGroup": "MC_mslearn-gh-pipelines-31129_contoso-video_japaneast",
  "oidcIssuerProfile": {
    "enabled": false,
    "issuerUrl": null
  },
  "podIdentityProfile": null,
  "powerState": {
    "code": "Running"
  },
  "privateFqdn": null,
  "privateLinkResources": null,
  "provisioningState": "Succeeded",
  "publicNetworkAccess": null,
  "resourceGroup": "mslearn-gh-pipelines-31129",
  "securityProfile": {
    "azureKeyVaultKms": null,
    "defender": null,
    "imageCleaner": null,
    "workloadIdentity": null
  },
  "servicePrincipalProfile": {
    "clientId": "msi",
    "secret": null
  },
  "sku": {
    "name": "Base",
    "tier": "Free"
  },
  "storageProfile": {
    "blobCsiDriver": null,
    "diskCsiDriver": {
      "enabled": true
    },
    "fileCsiDriver": {
      "enabled": true
    },
    "snapshotController": {
      "enabled": true
    }
  },
  "supportPlan": "KubernetesOfficial",
  "systemData": null,
  "tags": null,
  "type": "Microsoft.ContainerService/ManagedClusters",
  "upgradeSettings": null,
  "windowsProfile": null,
  "workloadAutoScalerProfile": {
    "keda": null,
    "verticalPodAutoscaler": null
  }
}
Obtaining credentials...
Merged "contoso-video" as current context in /home/user/.kube/config
Creating ACR...
{
  "adminUserEnabled": false,
  "anonymousPullEnabled": false,
  "creationDate": "2023-10-10T01:16:44.795541+00:00",
  "dataEndpointEnabled": false,
  "dataEndpointHostNames": [],
  "encryption": {
    "keyVaultProperties": null,
    "status": "disabled"
  },
  "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mslearn-gh-pipelines-31129/providers/Microsoft.ContainerRegistry/registries/contosocontainerregistry22312",
  "identity": null,
  "location": "japaneast",
  "loginServer": "contosocontainerregistry22312.azurecr.io",
  "name": "contosocontainerregistry22312",
  "networkRuleBypassOptions": "AzureServices",
  "networkRuleSet": null,
  "policies": {
    "azureAdAuthenticationAsArmPolicy": {
      "status": "enabled"
    },
    "exportPolicy": {
      "status": "enabled"
    },
    "quarantinePolicy": {
      "status": "disabled"
    },
    "retentionPolicy": {
      "days": 7,
      "lastUpdatedTime": "2023-10-10T01:16:52.848201+00:00",
      "status": "disabled"
    },
    "softDeletePolicy": {
      "lastUpdatedTime": "2023-10-10T01:16:52.848250+00:00",
      "retentionDays": 7,
      "status": "disabled"
    },
    "trustPolicy": {
      "status": "disabled",
      "type": "Notary"
    }
  },
  "privateEndpointConnections": [],
  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "resourceGroup": "mslearn-gh-pipelines-31129",
  "sku": {
    "name": "Basic",
    "tier": "Basic"
  },
  "status": null,
  "systemData": {
    "createdAt": "2023-10-10T01:16:44.795541+00:00",
    "createdBy": "************",
    "createdByType": "User",
    "lastModifiedAt": "2023-10-10T01:16:44.795541+00:00",
    "lastModifiedBy": "************",
    "lastModifiedByType": "User"
  },
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries",
  "zoneRedundancy": "Disabled"
}
{
  "adminUserEnabled": true,
  "anonymousPullEnabled": false,
  "creationDate": "2023-10-10T01:16:44.795541+00:00",
  "dataEndpointEnabled": false,
  "dataEndpointHostNames": [],
  "encryption": {
    "keyVaultProperties": null,
    "status": "disabled"
  },
  "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mslearn-gh-pipelines-31129/providers/Microsoft.ContainerRegistry/registries/contosocontainerregistry22312",
  "identity": null,
  "location": "japaneast",
  "loginServer": "contosocontainerregistry22312.azurecr.io",
  "name": "contosocontainerregistry22312",
  "networkRuleBypassOptions": "AzureServices",
  "networkRuleSet": null,
  "policies": {
    "azureAdAuthenticationAsArmPolicy": {
      "status": "enabled"
    },
    "exportPolicy": {
      "status": "enabled"
    },
    "quarantinePolicy": {
      "status": "disabled"
    },
    "retentionPolicy": {
      "days": 7,
      "lastUpdatedTime": "2023-10-10T01:16:52.848201+00:00",
      "status": "disabled"
    },
    "softDeletePolicy": {
      "lastUpdatedTime": "2023-10-10T01:16:52.848250+00:00",
      "retentionDays": 7,
      "status": "disabled"
    },
    "trustPolicy": {
      "status": "disabled",
      "type": "Notary"
    }
  },
  "privateEndpointConnections": [],
  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "resourceGroup": "mslearn-gh-pipelines-31129",
  "sku": {
    "name": "Basic",
    "tier": "Basic"
  },
  "status": null,
  "systemData": {
    "createdAt": "2023-10-10T01:16:44.795541+00:00",
    "createdBy": "************",
    "createdByType": "User",
    "lastModifiedAt": "2023-10-10T01:16:56.889744+00:00",
    "lastModifiedBy": "************",
    "lastModifiedByType": "User"
  },
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries",
  "zoneRedundancy": "Disabled"
}
AAD role propagation done[############################################]  100.0000%{
  "aadProfile": null,
  "addonProfiles": {
    "httpApplicationRouting": {
      "config": {
        "HTTPApplicationRoutingZoneName": "d882b2f44982432e97cf.japaneast.aksapp.io"
      },
      "enabled": true,
      "identity": {
        "clientId": "a80d3475-6e3c-4b7b-a54c-1c4e2b5d101b",
        "objectId": "23062433-4a77-4d88-831a-fe7ffe76c6bb",
        "resourceId": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.ManagedIdentity/userAssignedIdentities/httpapplicationrouting-contoso-video"
      }
    }
  },
  "agentPoolProfiles": [
    {
      "availabilityZones": null,
      "count": 1,
      "creationData": null,
      "currentOrchestratorVersion": "1.26.6",
      "enableAutoScaling": false,
      "enableEncryptionAtHost": false,
      "enableFips": false,
      "enableNodePublicIp": false,
      "enableUltraSsd": false,
      "gpuInstanceProfile": null,
      "hostGroupId": null,
      "kubeletConfig": null,
      "kubeletDiskType": "OS",
      "linuxOsConfig": null,
      "maxCount": null,
      "maxPods": 110,
      "minCount": null,
      "mode": "System",
      "name": "nodepool1",
      "nodeImageVersion": "AKSUbuntu-2204gen2containerd-202309.06.0",
      "nodeLabels": null,
      "nodePublicIpPrefixId": null,
      "nodeTaints": null,
      "orchestratorVersion": "1.26.6",
      "osDiskSizeGb": 128,
      "osDiskType": "Managed",
      "osSku": "Ubuntu",
      "osType": "Linux",
      "podSubnetId": null,
      "powerState": {
        "code": "Running"
      },
      "provisioningState": "Succeeded",
      "proximityPlacementGroupId": null,
      "scaleDownMode": null,
      "scaleSetEvictionPolicy": null,
      "scaleSetPriority": null,
      "spotMaxPrice": null,
      "tags": null,
      "type": "VirtualMachineScaleSets",
      "upgradeSettings": {
        "drainTimeoutInMinutes": null,
        "maxSurge": null
      },
      "vmSize": "Standard_B2s",
      "vnetSubnetId": null,
      "workloadRuntime": null
    }
  ],
  "apiServerAccessProfile": null,
  "autoScalerProfile": null,
  "autoUpgradeProfile": {
    "nodeOsUpgradeChannel": "NodeImage",
    "upgradeChannel": null
  },
  "azureMonitorProfile": null,
  "azurePortalFqdn": "contoso-video-rsrf8qus.portal.hcp.japaneast.azmk8s.io",
  "currentKubernetesVersion": "1.26.6",
  "disableLocalAccounts": false,
  "diskEncryptionSetId": null,
  "dnsPrefix": "contoso-video",
  "enablePodSecurityPolicy": null,
  "enableRbac": true,
  "extendedLocation": null,
  "fqdn": "contoso-video-rsrf8qus.hcp.japaneast.azmk8s.io",
  "fqdnSubdomain": null,
  "httpProxyConfig": null,
  "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/mslearn-gh-pipelines-31129/providers/Microsoft.ContainerService/managedClusters/contoso-video",
  "identity": {
    "delegatedResources": null,
    "principalId": "018e7b66-62fe-43e6-bd87-d14f87ab1ec3",
    "tenantId": "cb9bb346-c037-4fb2-a3ff-dd23544753ea",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  },
  "identityProfile": {
    "kubeletidentity": {
      "clientId": "e4b5a7eb-08b4-47e5-b267-9ddd3b42fe33",
      "objectId": "ba2ecebd-f658-4dad-a349-42178b793e03",
      "resourceId": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourcegroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.ManagedIdentity/userAssignedIdentities/contoso-video-agentpool"
    }
  },
  "kubernetesVersion": "1.26.6",
  "linuxProfile": {
    "adminUsername": "azureuser",
    "ssh": {
      "publicKeys": [
        {
          "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCtlQI5JNtID9FT9ei748fLS8yiwL94XmBPoXsxv9UGFe3ZilBzAtPUara5AXKVHDiHcPyLuXTq6iLbbC1tvVidf1BsH/lwFFSjz/z7aSAS2I84dAu5E/+AYg6azipYYtWzcCwIPfhaP0FqgtEOb0+Cvf1DgZ2tmUfOlg2qY0PdfrTU7Pf5cpCK46+zLhqQL7HpZNi/CHQrtU5TiSU6gU2gUy0/tOvlvUh4T+ipR+yH51Y2XF5v0Szy8c1brSOJ4VpO8sdxLycSw2QYOMbuv0Pxjg8YIv5yKbGxjKVOCn6Mp8QwOgYj1BeEdpUr4Lz2/ZuFlJoTNcPQSkxCjVI0VtRF"
        }
      ]
    }
  },
  "location": "japaneast",
  "maxAgentPools": 100,
  "name": "contoso-video",
  "networkProfile": {
    "dnsServiceIp": "10.0.0.10",
    "ipFamilies": [
      "IPv4"
    ],
    "loadBalancerProfile": {
      "allocatedOutboundPorts": null,
      "effectiveOutboundIPs": [
        {
          "id": "/subscriptions/xxxxxxxx-xxxxxxxxx-xxxx-xxxxxxxxxxxx/resourceGroups/MC_mslearn-gh-pipelines-31129_contoso-video_japaneast/providers/Microsoft.Network/publicIPAddresses/1a7b552e-3a6a-44ed-8b0e-b2930ac7d385",
          "resourceGroup": "MC_mslearn-gh-pipelines-31129_contoso-video_japaneast"
        }
      ],
      "enableMultipleStandardLoadBalancers": null,
      "idleTimeoutInMinutes": null,
      "managedOutboundIPs": {
        "count": 1,
        "countIpv6": null
      },
      "outboundIPs": null,
      "outboundIpPrefixes": null
    },
    "loadBalancerSku": "Standard",
    "natGatewayProfile": null,
    "networkDataplane": null,
    "networkMode": null,
    "networkPlugin": "kubenet",
    "networkPluginMode": null,
    "networkPolicy": null,
    "outboundType": "loadBalancer",
    "podCidr": "10.244.0.0/16",
    "podCidrs": [
      "10.244.0.0/16"
    ],
    "serviceCidr": "10.0.0.0/16",
    "serviceCidrs": [
      "10.0.0.0/16"
    ]
  },
  "nodeResourceGroup": "MC_mslearn-gh-pipelines-31129_contoso-video_japaneast",
  "oidcIssuerProfile": {
    "enabled": false,
    "issuerUrl": null
  },
  "podIdentityProfile": null,
  "powerState": {
    "code": "Running"
  },
  "privateFqdn": null,
  "privateLinkResources": null,
  "provisioningState": "Succeeded",
  "publicNetworkAccess": null,
  "resourceGroup": "mslearn-gh-pipelines-31129",
  "securityProfile": {
    "azureKeyVaultKms": null,
    "defender": null,
    "imageCleaner": null,
    "workloadIdentity": null
  },
  "servicePrincipalProfile": {
    "clientId": "msi",
    "secret": null
  },
  "sku": {
    "name": "Base",
    "tier": "Free"
  },
  "storageProfile": {
    "blobCsiDriver": null,
    "diskCsiDriver": {
      "enabled": true
    },
    "fileCsiDriver": {
      "enabled": true
    },
    "snapshotController": {
      "enabled": true
    }
  },
  "supportPlan": "KubernetesOfficial",
  "systemData": null,
  "tags": null,
  "type": "Microsoft.ContainerService/ManagedClusters",
  "upgradeSettings": null,
  "windowsProfile": null,
  "workloadAutoScalerProfile": {
    "keda": null,
    "verticalPodAutoscaler": null
  }
}
sed: can't read s+!IMAGE!+contosocontainerregistry22312/contoso-website+g: No such file or directory
sed: can't read s+!DNS!+d882b2f44982432e97cf.japaneast.aksapp.io+g: No such file or directory
Installation concluded, copy these values and store them, you'll use them later in this exercise:
-> Resource Group Name: mslearn-gh-pipelines-31129
-> ACR Name: contosocontainerregistry22312
-> ACR Login Username: contosocontainerregistry22312
-> ACR Password: jyR3eH1YVJqDOOWHS+v9aerOMF26r5XWnv9PHzxOF1+********
-> AKS Cluster Name: contosocontainerregistry22312
-> AKS DNS Zone Name: d882b2f44982432e97cf.japaneast.aksapp.io

スクリプトの実行が完了すると、変数の一覧が表示されます。 "変数名をコピーして保存します"。


sedコマンドが失敗してますね。

Azure Cloud Shell
sed: can't read s+!IMAGE!+contosocontainerregistry22312/contoso-website+g: No such file or directory
sed: can't read s+!DNS!+d882b2f44982432e97cf.japaneast.aksapp.io+g: No such file or directory

issue に上がってました。直ってないけど。
https://github.com/MicrosoftDocs/mslearn-aks-deployment-pipeline-github-actions/issues/19

変数のAKS_NAME は入っているので、そのままで大丈夫です。

Azure Cloud Shell
$ echo $AKS_NAME
contoso-video

sedコマンドは第2引数の空文字が余計なようで削除して実行します。

Azure Cloud Shell
$ sed -i 's+!IMAGE!+'"$ACR_NAME"'/contoso-website+g' kubernetes/deployment.yaml
$ sed -i 's+!DNS!+'"$DNS_NAME"'+g' kubernetes/ingress.yaml

コマンドを実行して以下のように修正されていればOKです。

kubernetes/deployment.yaml
    spec:
      containers:
        - image: contosocontainerregistry22312/contoso-website # ここ
kubernetes/ingress.yaml
spec:
  rules:
    - host: contoso.d882b2f44982432e97cf.japaneast.aksapp.io # ここ

修正版のinit.sh をここに置いておきます。
https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions/blob/main/init.sh

結果を確認する

すべてのリソースが作成されたことを確認します。

  1. スクリプトの出力で示されているリソース グループが一覧に表示されているかどうかを確認します。
Azure Cloud Shell
$ az group list -o table
Name                                                   Location    Status
-----------------------------------------------------  ----------  ---------
dev                                                    japaneast   Succeeded
NetworkWatcherRG                                       japaneast   Succeeded
tomcatchecker2426822468000                             japaneast   Succeeded
DefaultResourceGroup-EJP                               japaneast   Succeeded
AzureBackupRG_japaneast_1                              japaneast   Succeeded
MC_mslearn-gh-pipelines-31129_contoso-video_japaneast  japaneast   Succeeded
mslearn-gh-pipelines-31129                             eastus      Succeeded
  1. Container Registry インスタンスが一覧に表示されているかどうかを確認します。
Azure Cloud Shell
$ az acr list -o table
NAME                           RESOURCE GROUP              LOCATION    SKU    LOGIN SERVER                              CREATION DATE         ADMIN ENABLED
-----------------------------  --------------------------  ----------  -----  ----------------------------------------  --------------------  ---------------
contosocontainerregistry22312  mslearn-gh-pipelines-31129  japaneast   Basic  contosocontainerregistry22312.azurecr.io  2023-10-10T01:16:44Z  True

リソースはできてそうなので、次に進みます。

ユニット6: 演習 - ステージング アプリケーション イメージをビルドする

Actions ワークフローを構築する

  1. GitHub のfork したリポジトリの『Actions(アクション)』タブを選択します。
  2. ヘッダーのすぐ下にある 『set up a workflow yourself』(ワークフローを自分で設定する) を選択します。
  3. 書いてあるYAMLファイルをコピーして貼り付けます。
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo Hello, world!

      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.
  1. ファイルの名前を main.yml から build-staging.yml に変更します。
  2. ymlファイルのnameを 『CI』 から 『Build and push the latest build to staging』に変更します。

トリガーを作成する

on キーの2 番目のトリガーを削除し、push タグだけにします。

build-staging.yml
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  push:
    branches: [ main ]

イメージをビルドしてプッシュする

1-2. build キーの名前を build_push_image に変更し、steps の2つ目以降のコマンドを削除します。

build-staging.yml
jobs:
  build_push_image:
    runs-on: ubuntu-20.04
    
    steps:
      - uses: actions/checkout@v2
### これより下を削除する###
  1. 右のパネルのMarketplaceタブで『docker login』を検索して選択します。


    コピーアイコンをクリックして、ymlファイルの最後に貼り付けます。
build-staging.yml
    steps:
      - uses: actions/checkout@v2
      - name: Docker Login
        # You may pin to the exact commit or the version.
        # uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        uses: docker/login-action@v3.0.0
        with:
          # Server address of Docker registry. If not set then will default to Docker Hub
          registry: # optional
          # Username used to log against the Docker registry
          username: # optional
          # Password or personal access token used to log against the Docker registry
          password: # optional
          # Specifies whether the given registry is ECR (auto, true or false)
          ecr: # optional, default is auto
          # Log out from the Docker registry at the end of a job
          logout: # optional, default is true
  1. もう一度、右側のパネルの Marketplace で 『Build and push Docker images』を検索して選択します。


    コピーアイコンをクリックして、ymlファイルの最後に貼り付けます。
build-staging.yml
    steps:
      - uses: actions/checkout@v2
      - name: Docker Login
        # You may pin to the exact commit or the version.
        # uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        uses: docker/login-action@v3.0.0
        with:
          # Server address of Docker registry. If not set then will default to Docker Hub
          registry: # optional
          # Username used to log against the Docker registry
          username: # optional
          # Password or personal access token used to log against the Docker registry
          password: # optional
          # Specifies whether the given registry is ECR (auto, true or false)
          ecr: # optional, default is auto
          # Log out from the Docker registry at the end of a job
          logout: # optional, default is true
      - name: Build and push Docker images
        # You may pin to the exact commit or the version.
        # uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09
        uses: docker/build-push-action@v5.0.0
        with:
          # List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)
          add-hosts: # optional
          # List of extra privileged entitlement (e.g., network.host,security.insecure)
          allow: # optional
          # List of attestation parameters (e.g., type=sbom,generator=image)
          attests: # optional
          # List of build-time variables
          build-args: # optional
          # List of additional build contexts (e.g., name=path)
          build-contexts: # optional
          # Builder instance
          builder: # optional
          # List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)
          cache-from: # optional
          # List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)
          cache-to: # optional
          # Optional parent cgroup for the container used in the build
          cgroup-parent: # optional
          # Build's context is the set of files located in the specified PATH or URL
          context: # optional
          # Path to the Dockerfile
          file: # optional
          # List of metadata for an image
          labels: # optional
          # Load is a shorthand for --output=type=docker
          load: # optional, default is false
          # Set the networking mode for the RUN instructions during build
          network: # optional
          # Do not use cache when building the image
          no-cache: # optional, default is false
          # Do not cache specified stages
          no-cache-filters: # optional
          # List of output destinations (format: type=local,dest=path)
          outputs: # optional
          # List of target platforms for build
          platforms: # optional
          # Generate provenance attestation for the build (shorthand for --attest=type=provenance)
          provenance: # optional
          # Always attempt to pull all referenced images
          pull: # optional, default is false
          # Push is a shorthand for --output=type=registry
          push: # optional, default is false
          # Generate SBOM attestation for the build (shorthand for --attest=type=sbom)
          sbom: # optional
          # List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)
          secrets: # optional
          # List of secret files to expose to the build (e.g., key=filename, MY_SECRET=./secret.txt)
          secret-files: # optional
          # Size of /dev/shm (e.g., 2g)
          shm-size: # optional
          # List of SSH agent socket or keys to expose to the build
          ssh: # optional
          # List of tags
          tags: # optional
          # Sets the target stage to build
          target: # optional
          # Ulimit options (e.g., nofile=1024:1024)
          ulimit: # optional
          # GitHub Token used to authenticate against a repository for Git context
          github-token: # optional, default is ${{ github.token }}

たくさんオプションがありますが、このあとほとんど消されます。

  1. name キーの名前を Build and push Docker images から Build and push staging images に変更します。

  2. 次の表に従って値を追加します。

キー 対象のアクション
registry docker/login ${{ secrets.ACR_NAME }}
username docker/login ${{ secrets.ACR_LOGIN }}
password docker/login ${{ secrets.ACR_PASSWORD }}
context docker/build-and-push .
push docker/build-and-push true
tags docker/build-and-push ${{secrets.ACR_NAME}}/contoso-website:latest
他のすべてのキーは、削除します。
build-staging.yml
    steps:
      - uses: actions/checkout@v2

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}
          
      - name: Build and push staging images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest
  1. チェックアウト アクションとログイン アクションの間に別のアクションも追加します。
    uses: actions/checkout@v2 アクションの次に以下を貼り付けます。
- name: Set up Buildx
  uses: docker/setup-buildx-action@v1

build-staging.yml の全体はこんな感じ

build-staging.yml

# This is a basic workflow to help you get started with Actions

name: Build and push the latest build to staging

on:
  push:
    branches: [ main ]

jobs:
  build_push_image:
    runs-on: ubuntuで-20.04
    
    steps:
      - uses: actions/checkout@v2

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}
          
      - name: Build and push staging images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest
  1. build-staging.yml をコミットします。シークレットの設定をしていないのでビルドは失敗します。

シークレットを設定する

  1. リポジトリのスタート ページで、『Settings』 タブを選択します。『Security』 の下のメニューで、『Secrets and variables』 を選択し、『Action』 を選択します。

  2. 『New repository secret』を選択します。

  3. ACR_NAME シークレットを作成します。
    a. Name に 『ACR_NAME』 を入力
    b. 『Secret』 に 以下Cloud Shellで取得した結果を貼り付けます。

Azure Cloud Shell
$ az acr list --query "[?contains(resourceGroup, 'mslearn-gh-pipelines')].loginServer" -o table
Result
----------------------------------------
contosocontainerregistry22312.azurecr.io


c. 『Add secret』で追加します。

  1. ACR_LOGIN シークレットを作成します。
    3と手順は同じです。
    a. Name に 『ACR_LOGIN』
    b. 『Secret』 に 最初のセットアップで取得した『ACR Login Username』で表示された値か、以下Cloud Shellで取得した結果を貼り付けます。
Azure Cloud Shell
$ az acr credential show --name contosocontainerregistry22312 --query "username" -o table
Result
-----------------------------
contosocontainerregistry22312
``
![](https://storage.googleapis.com/zenn-user-upload/72c766247e43-20231010.png)
5. ACR_PASSWORD シークレットを作成します。
3と手順は同じです。
a. Name に 『ACR_PASSWORD』
b. 『Secret』 に 最初のセットアップで取得した『ACR Password』で表示された値か、以下Cloud Shellで取得した結果を貼り付けます。
```bash:Azure Cloud Shell
$ az acr credential show --name contosocontainerregistry22312 --query "passwords[0].value" -o table
Result
----------------------------------------------------
jyR3eH1YVJqDOOWHS+v9aerOMF26r5XWnv9PHzxOF1********

※一部variableでも良さそうですが、ここではsecretsのままにしておきます。

イメージをプッシュする

1-3. Actions タブから、先ほどは失敗していたジョブを選択してジョブの再実行をします。
『Re-run all jobs』を選択します。


成功しました

  1. Cloud Shell を開き、以下コマンドを実行して、結果に contoso-website という名前の付いたリポジトリが表示されることを確認します。
Azure Cloud Shell
$ az acr repository list --name contosocontainerregistry22312 -o table
Result
---------------
contoso-website

ユニット7: 演習 - 運用アプリケーション イメージをビルドする

Actions ワークフローを構築する

  1. GitHub の Actions タブから 『New workflow』を選択して新しいアクションを作成します。
  2. set up a workflow yourself を選択します。
    先ほどと同じく、基本的なフローをコピーして貼り付けます。
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Run a one-line script
        run: echo Hello, world!

      # Runs a set of commands using the runners shell
      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.
  1. ファイル名を 『build-production.yml』 に変更します。
  2. nameを変更します。
build-production.yml
name: Build and push the tagged build to production

トリガーを作成する

push だけにして、branchesではなく vから始まる tags にします。

build-production.yml
name: Build and push the tagged build to production

on:
  push:
    tags:
      - v*

イメージをビルドしてプッシュする

  1. build キーの名前を build_push_image に変更します。
  2. build-staging.yml のときと同じように、ubuntu-20.04 に修正し、最後の 2 つのコマンドを削除します。
build-production.yml
jobs:
  build_push_image:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2
  1. 必要なバージョン情報を収集する新しいステップを作成します。チェックアウト アクションの下に次の行を追加します。(Learnの書き方はちょっと古かったので書き換えました)
build-production.yml
    steps:
      - uses: actions/checkout@v2
      
      - name: Fetch latest version
        id: fetch_version
        run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
  1. build-staging.yml のときと同じように、右のパネルのMarketplaceタブで『docker login』を検索して選択します。Installation のコピーアイコンをクリックし、Fetch latest version の下に貼り付けます。
build-production.yml
    steps:
      - uses: actions/checkout@v2
      
      - name: Fetch latest version
        id: fetch_version
        run: echo ::set-output name=TAG::${GITHUB_REF#refs/tags/}

      - name: Docker Login
        # You may pin to the exact commit or the version.
        # uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        uses: docker/login-action@v3.0.0
        with:
          # Server address of Docker registry. If not set then will default to Docker Hub
          registry: # optional
          # Username used to log against the Docker registry
          username: # optional
          # Password or personal access token used to log against the Docker registry
          password: # optional
          # Specifies whether the given registry is ECR (auto, true or false)
          ecr: # optional, default is auto
          # Log out from the Docker registry at the end of a job
          logout: # optional, default is true
  1. Marketplace で 『Build and push Docker images』を検索します。Installation のコピーアイコンをクリックし、Fetch latest version の下に貼り付けます。
build-production.yml
    steps:
      - uses: actions/checkout@v2
      
      - name: Fetch latest version
        id: fetch_version
        run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"

      - name: Docker Login
        # You may pin to the exact commit or the version.
        # uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d
        uses: docker/login-action@v3.0.0
        with:
          # Server address of Docker registry. If not set then will default to Docker Hub
          registry: # optional
          # Username used to log against the Docker registry
          username: # optional
          # Password or personal access token used to log against the Docker registry
          password: # optional
          # Specifies whether the given registry is ECR (auto, true or false)
          ecr: # optional, default is auto
          # Log out from the Docker registry at the end of a job
          logout: # optional, default is true

      - name: Build and push Docker images
        # You may pin to the exact commit or the version.
        # uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09
        uses: docker/build-push-action@v5.0.0
        with:
          # List of a customs host-to-IP mapping (e.g., docker:10.180.0.1)
          add-hosts: # optional
          # List of extra privileged entitlement (e.g., network.host,security.insecure)
          allow: # optional
          # List of attestation parameters (e.g., type=sbom,generator=image)
          attests: # optional
          # List of build-time variables
          build-args: # optional
          # List of additional build contexts (e.g., name=path)
          build-contexts: # optional
          # Builder instance
          builder: # optional
          # List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)
          cache-from: # optional
          # List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)
          cache-to: # optional
          # Optional parent cgroup for the container used in the build
          cgroup-parent: # optional
          # Build's context is the set of files located in the specified PATH or URL
          context: # optional
          # Path to the Dockerfile
          file: # optional
          # List of metadata for an image
          labels: # optional
          # Load is a shorthand for --output=type=docker
          load: # optional, default is false
          # Set the networking mode for the RUN instructions during build
          network: # optional
          # Do not use cache when building the image
          no-cache: # optional, default is false
          # Do not cache specified stages
          no-cache-filters: # optional
          # List of output destinations (format: type=local,dest=path)
          outputs: # optional
          # List of target platforms for build
          platforms: # optional
          # Generate provenance attestation for the build (shorthand for --attest=type=provenance)
          provenance: # optional
          # Always attempt to pull all referenced images
          pull: # optional, default is false
          # Push is a shorthand for --output=type=registry
          push: # optional, default is false
          # Generate SBOM attestation for the build (shorthand for --attest=type=sbom)
          sbom: # optional
          # List of secrets to expose to the build (e.g., key=string, GIT_AUTH_TOKEN=mytoken)
          secrets: # optional
          # List of secret files to expose to the build (e.g., key=filename, MY_SECRET=./secret.txt)
          secret-files: # optional
          # Size of /dev/shm (e.g., 2g)
          shm-size: # optional
          # List of SSH agent socket or keys to expose to the build
          ssh: # optional
          # List of tags
          tags: # optional
          # Sets the target stage to build
          target: # optional
          # Ulimit options (e.g., nofile=1024:1024)
          ulimit: # optional
          # GitHub Token used to authenticate against a repository for Git context
          github-token: # optional, default is ${{ github.token }}

ここもあとで必要なキーのみ残して削除します。
6. name キーの名前を Build and push production images に変更します。
7. 次の表に従って値を追加します。

キー 対象のアクション
registry docker/login ${{ secrets.ACR_NAME }}
username docker/login ${{ secrets.ACR_LOGIN }}
password docker/login ${{ secrets.ACR_LOGIN }}
context docker/build-and-push .
push docker/build-and-push true
tags docker/build-and-push {{secrets.ACR_NAME}}/contoso-website:latest,{{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}
他のすべてのキーは、削除します。
build-production.yml
      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Build and push production images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest,${{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}
  1. Docker が使用するビルド エンジンを設定するために、チェックアウト アクションとログイン アクションの間に追加します。
build-production.yml
- name: Set up Buildx
  uses: docker/setup-buildx-action@v1

最終的なファイルは以下

build-production.yml
name: Build and push the tagged build to production

on:
  push:
    tags:
      - v*

jobs:
  build_push_image:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2
      
      - name: Fetch latest version
        id: fetch_version
        run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Build and push production images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest,${{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}
  1. コミットします。

個人用アクセス トークン (PAT) を作成する

Personal access tokensを発行します。スコープは『public_repo』のみ付与する。

Generate tokenでトークンを発行します。忘れずにコピー。

結果を確認する

  1. Cloud Shell でコマンドを実行する。
Azure Cloud Shell
$ cd mslearn-aks-deployment-pipeline-github-actions/
$ git pull origin main
$ git tag -a v2.0.0 -m 'First tag'

3-4. 次のコマンドを実行してpushします。GitHubのユーザ名とPATを入力します。

Azure Cloud Shell
$ git push --tags
Username for 'https://github.com': ************@gmail.com
Password for 'https://************@gmail.com@github.com': 
Enumerating objects: 117, done.
Counting objects: 100% (117/117), done.
Delta compression using up to 3 threads
Compressing objects: 100% (62/62), done.
Writing objects: 100% (117/117), 222.00 KiB | 74.00 MiB/s, done.
Total 117 (delta 44), reused 116 (delta 44), pack-reused 0
remote: Resolving deltas: 100% (44/44), done.
To https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions.git
 * [new tag]         v2.0.0 -> v2.0.0
  1. GitHubのアクションが終わるのを待ちます。
  2. Container Registry に2 つのタグが結果に表示されることを確認します。
Azure Cloud Shell
$ az acr repository show-tags --repository contoso-website --name contosocontainerregistry22312 -o table
Result
--------
latest
v2.0.0

できました!

ユニット9: デプロイ用の Helm グラフを作成して設定する

Helmは以前格闘しましたので参考までに。
https://zenn.dev/yukiko_bass/articles/7835a4864fa32f

Helm のインストールを確認する

  1. Helmのバージョンを確認します。version 3 以上であればOK。
Azure Cloud Shell
$ helm version
version.BuildInfo{Version:"v3.10.3", GitCommit:"", GitTreeState:"clean", GoVersion:"go1.18.8"}
  1. git pull をしておく
Azure Cloud Shell
$ git pull origin main
From https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions
 * branch            main       -> FETCH_HEAD
Already up to date.

グラフを作成する

1-2. cd を実行して kubernetes ディレクトリに移動し、helmのディレクトリを作成します。

Azure Cloud Shell
$ cd mslearn-aks-deployment-pipeline-github-actions/
$ cd kubernetes/
$ helm create contoso-website
Creating contoso-website
  1. 新しいディレクトリに移動します。 そのディレクトリから、charts フォルダーと templates フォルダーを削除します。
Azure Cloud Shell
$ cd contoso-website/
$ ls -ltr
total 16
-rw-r--r-- 1 user user 1882 Oct 10 07:32 values.yaml
drwxr-xr-x 3 user user 4096 Oct 10 07:32 templates
-rw-r--r-- 1 user user 1151 Oct 10 07:32 Chart.yaml
drwxr-xr-x 2 user user 4096 Oct 10 07:32 charts
$ rm -rf charts
$ rm -rf templates
  1. 新しい空の templates フォルダーを作成します。
Azure Cloud Shell
$ mkdir templates

5-6. contoso-website ディレクトリ内から、このコマンドを実行します。

Azure Cloud Shell
$ ls -ltr
total 12
-rw-r--r-- 1 user user 1882 Oct 10 07:32 values.yaml
-rw-r--r-- 1 user user 1151 Oct 10 07:32 Chart.yaml
drwxr-xr-x 2 user user 4096 Oct 10 07:45 templates

グラフを構成する

  1. リポジトリのルートに戻ります。
Azure Cloud Shell
$ cd ../../

2. code . を実行してエディタを開きます。
3. kubernetes/contoso-website/Chart.yaml を開きます。

このファイルを以下に書き換えます。

Chart.yaml
apiVersion: v2
name: contoso-website
description: Chart for the Contoso company website
version: 0.1.0
  1. ファイルを保存して閉じます。

デプロイの作成

  1. kubernetes/contoso-website/templates/deployment.yaml をエディタで開きます。
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: contoso-website
spec:
  selector:
    matchLabels:
      app: contoso-website
  template:
    metadata:
      labels:
        app: contoso-website
    spec:
      containers:
        - image: contosocontainerregistry22312/contoso-website
          name: contoso-website
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
          ports:
            - containerPort: 80
              name: http
  1. metadata セクションに、namespace という名前の新しいキーを追加します。
templates/deployment.yaml
metadata:
  name: contoso-website
  namespace: {{ default "staging" .Release.Namespace }}
  1. image を以下のように変更します。
templates/deployment.yaml
    spec:
      containers:
        - image: {{ .Values.image.registry }}.azurecr.io/{{ .Values.image.name }}:{{ default "latest" .Values.image.tag }}
          name: contoso-website

※最初のsedコマンドの失敗は放置しててもよかったですね。
4. ファイルを保存して閉じます。

空の YAML ファイルを作成する

  1. contoso-website ディレクトリのルートにある values.yaml ファイルを開きます。
  2. ファイルのすべての内容を削除し、YAML ファイルを空にします。

YAML ファイルに内容を追加する

  1. values.yaml ファイルに以下を追加します。
values.yaml
image:
  registry: contosocontainerregistry22312
  name: contoso-website
  tag: latest
  1. ファイルを保存して閉じます。

サービスの作成

  1. templates フォルダー内の service.yaml ファイルを見つけて開きます。
  2. metadata セクションに、namespace という名前の新しいキーを追加します。 deployment.yaml ファイルで使用したものと同じ値を使用します。
templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: contoso-website
  namespace: {{ default "staging" .Release.Namespace }}
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: http
      name: http
  selector:
    app: contoso-website
  type: ClusterIP
  1. ファイルを保存して閉じます。

イングレスを作成する

  1. ingress.yaml ファイルを見つけて開きます。
  2. metadata セクションに、namespace という名前の新しいキーを追加します。 deployment.yaml ファイルで使用したものと同じ値を使用します。
templates/ingress.yaml
metadata:
  name: contoso-website
  namespace: {{ default "staging" .Release.Namespace }}

3-4. host をstaging用に書きえます。

templates/ingress.yaml
spec:
  rules:
    - host: contoso-{{ default "staging" .Release.Namespace }}.d882b2f44982432e97cf.japaneast.aksapp.io
  1. DNS ゾーン名になる新しいテンプレート変数を追加します。
templates/ingress.yaml
spec:
  rules:
    - host: contoso-{{ default "staging" .Release.Namespace }}.{{ .Values.dns.name }}

全体は以下のようになります。

templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: contoso-website
  namespace: {{ default "staging" .Release.Namespace }}
  annotations:
    kubernetes.io/ingress.class: addon-http-application-routing
spec:
  rules:
    - host: contoso-{{ default "staging" .Release.Namespace }}.{{ .Values.dns.name }}
      http:
        paths:
          - backend:
              service:
                name: contoso-website
                port:
                  name: http
            path: /
            pathType: Prefix

DNS ゾーン名を作成する

  1. values.yaml ファイルを開きます。
  2. dns.name キーを追加します。
values.yaml
image:
  registry:contosocontainerregistry22312
  name: contoso-website
  tag: latest
dns:
  name: d882b2f44982432e97cf.japaneast.aksapp.io

DNSゾーン名は一番最初に作ったときに表示されたDNS_NAMEの値もしくは、以下のコマンドで取得したものを記述します。

Azure Cloud Shell
$ az aks show -g mslearn-gh-pipelines-31129 -n contoso-video -o tsv --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName
d882b2f44982432e97cf.japaneast.aksapp.io
  1. ファイルを保存して閉じます。
  2. すべての変更をコミットして、pushします。
Azure Cloud Shell
$ git add .
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   kubernetes/contoso-website/.helmignore
        new file:   kubernetes/contoso-website/Chart.yaml
        renamed:    kubernetes/deployment.yaml -> kubernetes/contoso-website/templates/deployment.yaml
        renamed:    kubernetes/ingress.yaml -> kubernetes/contoso-website/templates/ingress.yaml
        renamed:    kubernetes/service.yaml -> kubernetes/contoso-website/templates/service.yaml
        new file:   kubernetes/contoso-website/values.yaml
$ git commit -m "Add helm"
[main 80c4765] Add helm
 6 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 kubernetes/contoso-website/.helmignore
 create mode 100644 kubernetes/contoso-website/Chart.yaml
 rename kubernetes/{ => contoso-website/templates}/deployment.yaml (73%)
 rename kubernetes/{ => contoso-website/templates}/ingress.yaml (73%)
 rename kubernetes/{ => contoso-website/templates}/service.yaml (78%)
 create mode 100644 kubernetes/contoso-website/values.yaml
 $ git push -u origin main
Enumerating objects: 13, done.
Counting objects: 100% (13/13), done.
Delta compression using up to 3 threads
Compressing objects: 100% (10/10), done.
Writing objects: 100% (11/11), 1.75 KiB | 895.00 KiB/s, done.
Total 11 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions.git
   f36328b..80c4765  main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

デプロイ パイプラインを作成する

  1. GitHub のforkしたリポジトリを表示します。
  2. .github/workflows ディレクトリに移動し、build-staging.yml ファイルを開きます。
  3. build_push_image キーの下に、deploy という名前の新しいキーを作成します。
build-staging.yml
# This is a basic workflow to help you get started with Actions

name: Build and push the latest build to staging

on:
  push:
    branches: [ main ]

jobs:
  build_push_image:
    runs-on: ubuntu-20.04
    
    steps:
      - uses: actions/checkout@v2

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}
          
      - name: Build and push staging images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

4-5. 作業ブランチをチェックアウトするジョブを追加します。

build-staging.yml
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2

Helm のインストール

  1. Marketplace タブで Helm tool installer を検索し、選択します。

  2. コピーアイコンをクリックして、コピーした内容をcheckoutジョブの下に貼り付けます。
build-staging.yml
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2
      
      - name: Helm tool installer
        uses: Azure/setup-helm@v3
        with:
          # Version of helm
          version: # default is latest
          # GitHub token. Required only if 'version' == 'latest'
          token: # optional
  1. ステップの名前を Install Helm に変更し、version キーを v3.3.1 に固定します。
build-staging.yml
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2
      
      - name: Install Helm
        uses: Azure/setup-helm@v3
        with:
          version: v3.3.1
  1. Marketplace タブで azure set context を検索し、Azure Kubernetes set context を選択します。

  2. コピーアイコンをクリックして、コピーした内容をInstall Helm ステップの下に貼り付けます。
build-staging.yml
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2
      
      - name: Install Helm
        uses: Azure/setup-helm@v3
        with:
          version: v3.3.1
      - name: Azure Kubernetes set context
        uses: Azure/aks-set-context@v3
        with:
          # Resource Group Name
          resource-group: 
          # AKS Cluster Name
          cluster-name: 
          # AKS Cluster Subscription
          subscription: # optional
          # Get cluster admin credentials. Values: true or false
          admin: # optional
          # Enables kubelogin for non-admin user scenario. Values: true or false
          use-kubelogin: # optional

AKS の資格情報の取得

  1. name キーを Get AKS Credentials に変更します。
build-staging.yml
      - name: Get AKS Credentials
        uses: Azure/aks-set-context@v3
        with:
  1. resource-group キーを、AKS リソースが含まれるリソース グループの名前に変更します。
build-staging.yml
          resource-group: mslearn-gh-pipelines-31129
  1. cluster-name キーにクラスター名を入力します。
build-staging.yml
          cluster-name: contoso-video

ここから creds に設定するAZURE_CREDENTIALS を取得するように書いてますが、Azure Kubernetes set context のバージョンがv3になっているため、このcredsキーはなくなり、代わりにazure/login アクションを使って Azure にログインする必要があります。

https://github.com/marketplace/actions/azure-login
以下のジョブをGet AKS Credentialsの前で実行するようにします。

      - uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Get AKS Credentials
        uses: Azure/aks-set-context@v3

最終的なymlは以下のようになります。

build-staging.yml
# This is a basic workflow to help you get started with Actions

name: Build and push the latest build to staging

on:
  push:
    branches: [ main ]

jobs:
  build_push_image:
    runs-on: ubuntu-20.04
    
    steps:
      - uses: actions/checkout@v2

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}
          
      - name: Build and push staging images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest
  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2
      
      - name: Install Helm
        uses: Azure/setup-helm@v3
        with:
          version: v3.3.1

      - uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Get AKS Credentials
        uses: Azure/aks-set-context@v3
        with:
          resource-group: mslearn-gh-pipelines-31129
          cluster-name: contoso-video

シークレットの作成

  1. リポジトリのスタート ページで、『Settings』 タブを選択します。『Security』 の下のメニューで、『Secrets and variables』 を選択し、『Action』 を選択します。
  2. 『New repository secret』をクリックします。
  3. AZURE_CREDENTIALS という名前の新しいシークレットを作成します。
    シークレットはContributer権限を持ったサービスプリンシパルを作成し、その結果のJSONを貼り付けます。
Azure Cloud Shell
$ az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<subscriptionID> --sdk-auth
  1. シークレットを保存してタブを閉じます。

アプリケーションの配置

GitHub の Actions に戻ります。
1-2. YAML ファイルの最後のステップの下に以下を追記します。

build-staging.yml
      - name: Run Helm Deploy
        run: |
          helm upgrade \
            --install \
            --create-namespace \
            --atomic \
            --wait \
            --namespace staging \
            contoso-website \
            ./kubernetes/contoso-website \
            --set image.repository=${{ secrets.ACR_NAME }} \
            --set dns.name=${{ secrets.DNS_NAME }}
  1. 新しいブラウザー タブを開き、リポジトリのスタート ページで、『Settings』 タブを選択します。『Security』 の下のメニューで、『Secrets and variables』 を選択し、『Action』 を選択します。
  2. 『New repository secret』をクリックします。
  3. DNS_NAME という名前の新しいシークレットを作成します。
    DNS_NAME は最初のAKSの作成した際に表示されたDNS_NAMEか、以下のコマンドで取得します。
Azure Cloud Shell
az aks show -g {resource-group-name} -n {aks-cluster-name} -o tsv --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName
  1. シークレットを保存してタブを閉じます。
  2. build-staging.yml に戻り、コミットします。

ステージング デプロイをテストする

http://contoso-staging.DNS_NAME/ にアクセスします。

今回はこのURL。

http://contoso-staging.d882b2f44982432e97cf.japaneast.aksapp.io/


※デプロイから10分後ぐらいに表示されるようになりました。

運用環境のデプロイを作成する

  1. GitHub のforkしたリポジトリを表示します。.github/workflows ディレクトリに移動し、build-production.yml ファイルを開きます。
  2. build-staging.yml から deploy ステップをコピーします。
build-production.yml
name: Build and push the tagged build to production

on:
  push:
    tags:
      - v*

jobs:
  build_push_image:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2
      
      - name: Fetch latest version
        id: fetch_version
        run: echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"

      - name: Docker Login
        uses: docker/login-action@v3.0.0
        with:
          registry: ${{ secrets.ACR_NAME }}
          username: ${{ secrets.ACR_LOGIN }}
          password: ${{ secrets.ACR_PASSWORD }}

      - name: Set up Buildx
        uses: docker/setup-buildx-action@v1

      - name: Build and push production images
        uses: docker/build-push-action@v5.0.0
        with:
          context: .
          push: true
          tags: ${{secrets.ACR_NAME}}/contoso-website:latest,${{secrets.ACR_NAME}}/contoso-website:${{ steps.fetch_version.outputs.TAG }}

  deploy:
    runs-on: ubuntu-20.04
    needs: build_push_image # Will wait for the execution of the previous job

    steps:
      - uses: actions/checkout@v2
      
      - name: Install Helm
        uses: Azure/setup-helm@v3
        with:
          version: v3.3.1

      - uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Get AKS Credentials
        uses: Azure/aks-set-context@v3
        with:
          resource-group: mslearn-gh-pipelines-31129
          cluster-name: contoso-video

      - name: Run Helm Deploy
        run: |
          helm upgrade \
            --install \
            --create-namespace \
            --atomic \
            --wait \
            --namespace staging \
            contoso-website \
            ./kubernetes/contoso-website \
            --set image.repository=${{ secrets.ACR_NAME }} \
            --set dns.name=${{ secrets.DNS_NAME }}
  1. Run Helm Deploy ステップで、--namespace フラグを staging から production に変更します。
build-production.yml
--namespace production \
  1. Helm コマンドの末尾に、新しい --set image.tag=${GITHUB_REF##*/} を追加します。
build-production.yml
- name: Run Helm Deploy
        run: |
          helm upgrade \
            --install \
            --create-namespace \
            --atomic \
            --wait \
            --namespace production \
            contoso-website \
            ./kubernetes/contoso-website \
            --set image.repository=${{ secrets.ACR_NAME }} \
            --set dns.name=${{ secrets.DNS_NAME }} \
            --set image.tag=${GITHUB_REF##*/}
  1. 変更をコミットします。
  2. Cloud Shell で git pull を実行して、最新の変更を取得し、新しくタグを作成します。
Azure Cloud Shell
$ git pull origin main
$ git tag -a v2.0.1 -m 'Creating first production deployment' && git push --tags
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 189 bytes | 189.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/yukiko-bass/mslearn-aks-deployment-pipeline-github-actions.git
 * [new tag]         v2.0.1 -> v2.0.1
  1. GitHub Actions のプロセスが完了するのを確認します。

運用環境のデプロイをテストする

contoso-production.DNS_NAME に移動し、Web サイトが表示されることを確認します。

今回はこのURL。

http://contoso-production.d882b2f44982432e97cf.japaneast.aksapp.io/

※こちらも10分ぐらいかかりました。

おわりに

GitHub Actionsに慣れてなくて、結構時間かかりました。。

参考

https://rhysd.github.io/actionlint/

Discussion