はじめに
おはようございます!こんにちは!こんばんわ!
ACS事業部の谷合です。
この記事は エーピーコミュニケーションズ Advent Calendar 2023 の8日目の投稿です。
先月ではありますが、GitHub-hosted runnerとAzureのPrivate Networkの統合がPublic Betaでサポートされたのはご存じでしょうか?
詳細は、以下のドキュメントに記載がありますが、簡単に言うとGitHub ActionsでWorkflowを実行時に、AzureのPrivate Network経由で
オンプレ環境と通信ができるようになる機能です。この時、Azure VPN GatewayやAzure ExpressRouteでAzure バックボーン経由でセキュアな
通信が実現できます!GitHub-hosted runnerから、E2Eテストなどの時にオンプレのVMにあるDBなどと通信ができる、何とも素敵な機能ですよね。
今回はこの機能の実装方法を解説していきます。
アーキテクチャ
GitHubから公開されているアーキテクチャ図は以下の通りです。
- A GitHub Actions workflow is triggered.
- The GitHub Actions service creates a runner.
- The runner service deploys the GitHub-hosted runner's network interface card (NIC) into your Azure VNET.
- The runner agent picks up the workflow job. The GitHub Actions service queues the job.
- The runner sends logs back to the GitHub Actions service.
- The NIC accesses on-premise resources.
上記のように説明文付きでアーキテクチャ図が公開されていますが、要約すると、
「Workflowが実行されると、AzureにNICがデプロイされ、Network Security Group(以降NSG)のポリシーに従い、オンプレと通信ができる」
です。
これを実際にAzureの世界に落とし込むと以下の通りとなります。
以降で解説していく環境を図にしたものとなりますが、Azure内でクラウドとオンプレを疑似的に実装してみています。
GitHubがAzure VnetにNICをデプロイし、NICにSubnetに紐づくNSGのポリシーに従い、疑似オンプレのMySQLと通信をしています。
この時、Vnet間はVPN Gateway経由でS2S接続をしています。
実装してみよう
前提
GitHub Enterpriseアカウントを有していること
疑似オンプレ側のVMにMySQLをインストールし、mysqlコマンドでリモート接続ができること
GitHub ActionsとAzureのPrivate Networkとの統合でサポートされるリージョンには、East US、East US 2、West US 2のみ (このリストにないリージョンのサポートをリクエストするには、リージョンリクエストフォームにご記入ください)
以降の工程で、GitHub.Network リソースプロバイダを登録し、サブネットを委任します。
この時サブスクリプション共同作成者ロールとネットワーク共同作成者ロールを持つ Azure アカウントが必要なので、あらかじめロールを付与しておくこと
以降の手順は、以下のドキュメントに沿って実施いきます。
AzureのPrivate Networkとの統合用Azureリソースの作成
まずは、NSGルール用Bicepスクリプトを、actions-nsg-deployment.bicepという名前で作成します。
これはそのままコピペで問題ないです。
param location string param nsgName string = 'actions_NSG' resource actions_NSG 'Microsoft.Network/networkSecurityGroups@2017-06-01' = { name: nsgName location: location properties: { securityRules: [ { name: 'DenyInternetOutBoundOverwrite' properties: { protocol: '*' sourcePortRange: '*' destinationPortRange: '*' sourceAddressPrefix: '*' destinationAddressPrefix: 'Internet' access: 'Deny' priority: 400 direction: 'Outbound' } } { name: 'AllowVnetOutBoundOverwrite' properties: { protocol: 'TCP' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: '*' destinationAddressPrefix: 'VirtualNetwork' access: 'Allow' priority: 200 direction: 'Outbound' destinationAddressPrefixes: [] } } { name: 'AllowAzureCloudOutBound' properties: { protocol: 'TCP' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: '*' destinationAddressPrefix: 'AzureCloud' access: 'Allow' priority: 210 direction: 'Outbound' destinationAddressPrefixes: [] } } { name: 'AllowInternetOutBoundGitHub' properties: { protocol: 'TCP' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: '*' access: 'Allow' priority: 220 direction: 'Outbound' destinationAddressPrefixes: [ '140.82.112.0/20' '142.250.0.0/15' '143.55.64.0/20' '192.30.252.0/22' '185.199.108.0/22' ] } } { name: 'AllowInternetOutBoundMicrosoft' properties: { protocol: 'TCP' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: '*' access: 'Allow' priority: 230 direction: 'Outbound' destinationAddressPrefixes: [ '13.64.0.0/11' '13.96.0.0/13' '13.104.0.0/14' '20.33.0.0/16' '20.34.0.0/15' '20.36.0.0/14' '20.40.0.0/13' '20.48.0.0/12' '20.64.0.0/10' '20.128.0.0/16' '52.224.0.0/11' '204.79.197.200' ] } } { name: 'AllowInternetOutBoundCannonical' properties: { protocol: 'TCP' sourcePortRange: '*' destinationPortRange: '443' sourceAddressPrefix: '*' destinationAddressPrefix: '185.125.188.0/22' access: 'Allow' priority: 240 direction: 'Outbound' destinationAddressPrefixes: [] } } ] } }
次にEnterpriseのdatabaseIdを取得します。
この時、BEARER_TOKENとして、Persoal Access Token(PAT)もしくは、GitHub Appを指定します。
更に、slugにはEnterprise名を指定してください。
$ curl -H "Authorization: Bearer <PAT or GitHub App>" -X POST \ -d '{ "query": "query($slug: String!) { enterprise (slug: $slug) { slug databaseId } }" , "variables": { "slug": "<Enterprise名>" } }' \ https://api.github.com/graphql {"data":{"enterprise":{"slug":"<Enterprise名>","databaseId":12345}}}
次に以下のShellスクリプトを作成します。
このスクリプトを実行することで、以下の動作が実行されます。
- リソースグループ、NSG、VNet、Subnet、Network Settings が作成される。
GitHub.Network
リソースプロバイダをサブスクリプションに登録される。- 作成したサブネットを
GitHub.Network/NetworkSettings
リソースタイプでアクションサービスに委任し、サブネットに NSG のルールを適用する。
#!/bin/bash # This script creates the following resources in the specified subscription: # - Resource group # - Network Security Group rules # - Virtual network (vnet) and subnet # - Network Settings with specified subnet and GitHub Enterprise databse ID # # It also registers the `GitHub.Network` resource provider with the subscription, # delegates the created subnet to the Actions service via the `GitHub.Network/NetworkSettings` # resource type, and applies the NSG rules to the created subnet. # stop on failure set -e #set environment export AZURE_LOCATION=eastus export SUBSCRIPTION_ID=<サブスクリプションID> export RESOURCE_GROUP_NAME=<NICをデプロイするリソースグループ名> export VNET_NAME=<VNET名> export SUBNET_NAME=<Subnet名> export NSG_NAME=<NSG名> export NETWORK_SETTINGS_RESOURCE_NAME=<Network Settings名> export DATABASE_ID=<GitHub Enterprise databaseId> # These are the default values. You can adjust your address and subnet prefixes. export ADDRESS_PREFIX=10.0.0.0/16 export SUBNET_PREFIX=10.0.0.0/24 echo echo login to Azure . az login --output none echo echo set account context $SUBSCRIPTION_ID . az account set --subscription $SUBSCRIPTION_ID echo echo Register resource provider GitHub.Network . az provider register --namespace GitHub.Network echo echo Create resource group $RESOURCE_GROUP_NAME at $AZURE_LOCATION . az group create --name $RESOURCE_GROUP_NAME --location $AZURE_LOCATION echo echo Create NSG rules deployed with 'actions-nsg-deployment.bicep' file . az deployment group create --resource-group $RESOURCE_GROUP_NAME --template-file ./actions-nsg-deployment.bicep --parameters location=$AZURE_LOCATION nsgName=$NSG_NAME echo echo Create vnet $VNET_NAME and subnet $SUBNET_NAME . az network vnet create --resource-group $RESOURCE_GROUP_NAME --name $VNET_NAME --address-prefix $ADDRESS_PREFIX --subnet-name $SUBNET_NAME --subnet-prefixes $SUBNET_PREFIX echo echo Delegate subnet to GitHub.Network/networkSettings and apply NSG rules . az network vnet subnet update --resource-group $RESOURCE_GROUP_NAME --name $SUBNET_NAME --vnet-name $VNET_NAME --delegations GitHub.Network/networkSettings --network-security-group $NSG_NAME echo echo Create network settings resource $NETWORK_SETTINGS_RESOURCE_NAME . az resource create --resource-group $RESOURCE_GROUP_NAME --name $NETWORK_SETTINGS_RESOURCE_NAME --resource-type GitHub.Network/networkSettings --properties "{ \"location\": \"$AZURE_LOCATION\", \"properties\" : { \"subnetId\": \"/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Network/virtualNetworks/$VNET_NAME/subnets/$SUBNET_NAME\", \"organizationId\": \"$DATABASE_ID\" }}" --is-full-object --output table --query "{GitHubId:tags.GitHubId, name:name}" --api-version 2023-11-01-preview echo echo To clean up and delete resources run the following command: echo az group delete --resource-group $RESOURCE_GROUP_NAME
ここまで来たら、準備完了です。
Shellスクリプトを実行してみましょう。
この時、Azureへのログインが促されますので、コードを入力しログインします。
Shellスクリプト内のazコマンドで各種リソースが作成されるはずです。
また、最後に出力されるGitHubIdはGitHubへのAzure Private Network登録に使いますので、控えておいてください。
$ . ./create-azure-resources.sh : Create network settings resource integrated-github-actions-nwsettings GitHubId Name ---------------------------------------------------------------- ------------------------------------ 123456789012345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGH <Network Settings名>
次に、以下ドキュメントに沿ってS2S接続できる環境を実装します。
こちらのドキュメント、非常に素敵なドキュメントなので、本記事だけでなくいろんな場面で使えると思います。
t.co
以上で、Azureリソースの作成は完了です。
ここまでくると、以下のように各種リソースが作成されているはずです。
$ az resource list -g rg-taniai-integrated-github-actions -otable Name ResourceGroup Location Type Status -------------------------------------------------------------- ----------------------------------- ---------- ---------------------------------------- -------- integrated-github-actions-nwsettings rg-taniai-integrated-github-actions eastus GitHub.Network/networkSettings taniai-vm-hub-ubuntu_OsDisk_1_2c24792f5f174264a2356b61b99b1706 RG-TANIAI-INTEGRATED-GITHUB-ACTIONS eastus Microsoft.Compute/disks taniai-vm-onp-ubuntu_OsDisk_1_03c8a4907b9740449b363e8cb47a8298 RG-TANIAI-INTEGRATED-GITHUB-ACTIONS eastus Microsoft.Compute/disks taniai-vm-hub-ubuntu_key rg-taniai-integrated-github-actions eastus Microsoft.Compute/sshPublicKeys taniai-vm-onp-ubuntu_key rg-taniai-integrated-github-actions eastus Microsoft.Compute/sshPublicKeys taniai-vm-hub-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Compute/virtualMachines taniai-vm-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Compute/virtualMachines shutdown-computevm-taniai-vm-hub-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.DevTestLab/schedules shutdown-computevm-taniai-vm-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.DevTestLab/schedules HubToOnp rg-taniai-integrated-github-actions eastus Microsoft.Network/connections OnpToHub rg-taniai-integrated-github-actions eastus Microsoft.Network/connections HUB_LNG rg-taniai-integrated-github-actions eastus Microsoft.Network/localNetworkGateways ONP_LNG rg-taniai-integrated-github-actions eastus Microsoft.Network/localNetworkGateways taniai-vm-hub-ubuntu223_z1 rg-taniai-integrated-github-actions eastus Microsoft.Network/networkInterfaces taniai-vm-onp-ubuntu679_z1 rg-taniai-integrated-github-actions eastus Microsoft.Network/networkInterfaces integrated-github-actions-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-nsg-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vm-hub-ubuntu-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vnet-hub-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vm-hub-ubuntu-ip rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses taniai-vm-onp-ubuntu-ip rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub-pip1 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub-pip2 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-onp-pip1 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-onp-pip2 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworkGateways vpngw-onp rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworkGateways integrated-github-actions-vnet rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworks taniai-vnet-onp rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworks
GitHubへのAzureリソースの登録
ここまで作成したAzureリソースをGitHub Enterpriseに登録します。
まず、Enterprise→Setrings→Hosted compute networkingの順に進みます。
そうすると、以下の画面が表示されますので、Azure private network
を選択します。
次に表示されるAdd Azure Virtual Network内のNetwork settings resource ID
に、先ほど実行したShellスクリプト結果のGitHubIdを入力します。
入力するとNetwork settingsに紐づく、Subscripution IDをはじめ、VnetやSunet、リソースグループ、リージョンが自動入力されます。
最後に登録名を入力して、Create Configurationボタンを押下することで、Azureリソースの登録は完了です。
Runner GroupとGitHub-hosted larger runnerの作成
Azureリソース登録が完了したら、次はRunner GroupとGitHub-hosted larger runnerの作成を行います。
まずRunner Groupを作成します。Hosted compute networkingの画面にいくと、以下のようにRunner Group作成が促されます。
Group名などの必要項目を入力、Azureリソースを登録した際の名前を選択し作成します。
作成したRunner Groupの画面にいくと、GitHub-hosted larger runnerの作成ができるようになります。
GitHub-hosted larger runnerの作成画面では、好みの設定をImageやSizeを選んでください。
GitHub-hosted larger runnerの作成では1点注意点があります。
今回作成するRunnerは、Private Network内で動作します。そのため、Public IPを付与することができません。
GitHub-hosted larger runnerには、Public IPのレンジを2つ付与することができますが、今回の場合に付与してRunnerを作成しようとすると、以下のエラーが発生します。
ここまでで、GitHub側の設定は完了です。
お疲れ様でした!!!
動作確認
それでは動作確認をしてみましょう。
今回は下図に記載の通り、GitHubからAzure VNetに接続し、NICをデプロイ後、VPN Gateway経由で、疑似オンプレのVM内のMySQLに接続してみます。
この時、MySQLに接続するため、NSGの送信ルールにもMySQLポート3306を登録しておきます。
また、併せて疑似オンプレ側のNSGの受信ルールも3306を登録しておきます。
ちなみに、上記NSGはNIC側から確認しています。
GitHub ActionsとAzureのPrivate Networkとの統合をすると、Workflow実行時にNICがデプロイされます。
その際NSGはNICでなく、Subnetに紐づくようになっています。そのため、ヘルプの有効なセキュリティルール
から確認をしています。
Workflowを実行してみましょう。
Wokflowでは、mysqlコマンドで疑似オンプレのVM内のMySQLにリモート接続して、show databasesコマンドを実行しています。
name: Larger runnner test on: workflow_dispatch jobs: my-job: runs-on: integrated-azure-runner steps: - uses: actions/checkout@v2 - name: Connecting to on-prem mysql run: MYSQL_PWD=Surf_0530 mysql -h 172.16.1.4 -u gha_user -e'show databases;'
なお、上記、mysqlコマンドにしているのは、疑似オンプレのVMのプライベートIPアドレスです。
Workflow実行後に確認してみると、以下のように正常に終了していることが確認できるはずです。
なお、先ほどGitHub ActionsとAzureのPrivate Networkとの統合をすると、Workflow実行時にNICがデプロイされるとお伝えしました。
以下のように、GHA-xxxx-xxxx-xxといった名前のNICがデプロイされていること確認できるはずです。
$ az resource list -g rg-taniai-integrated-github-actions -otable Name ResourceGroup Location Type Status -------------------------------------------------------------- ----------------------------------- ---------- ---------------------------------------- -------- integrated-github-actions-nwsettings rg-taniai-integrated-github-actions eastus GitHub.Network/networkSettings taniai-vm-hub-ubuntu_OsDisk_1_2c24792f5f174264a2356b61b99b1706 RG-TANIAI-INTEGRATED-GITHUB-ACTIONS eastus Microsoft.Compute/disks taniai-vm-onp-ubuntu_OsDisk_1_03c8a4907b9740449b363e8cb47a8298 RG-TANIAI-INTEGRATED-GITHUB-ACTIONS eastus Microsoft.Compute/disks taniai-vm-hub-ubuntu_key rg-taniai-integrated-github-actions eastus Microsoft.Compute/sshPublicKeys taniai-vm-onp-ubuntu_key rg-taniai-integrated-github-actions eastus Microsoft.Compute/sshPublicKeys taniai-vnet-hub_key rg-taniai-integrated-github-actions eastus Microsoft.Compute/sshPublicKeys taniai-vm-hub-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Compute/virtualMachines taniai-vm-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Compute/virtualMachines shutdown-computevm-taniai-vm-hub-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.DevTestLab/schedules shutdown-computevm-taniai-vm-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.DevTestLab/schedules HubToOnp rg-taniai-integrated-github-actions eastus Microsoft.Network/connections OnpToHub rg-taniai-integrated-github-actions eastus Microsoft.Network/connections HUB_LNG rg-taniai-integrated-github-actions eastus Microsoft.Network/localNetworkGateways ONP_LNG rg-taniai-integrated-github-actions eastus Microsoft.Network/localNetworkGateways ↓★★★★★★★★★ GHA-0ab2-2585-f2 rg-taniai-integrated-github-actions eastus Microsoft.Network/networkInterfaces taniai-vm-hub-ubuntu223_z1 rg-taniai-integrated-github-actions eastus Microsoft.Network/networkInterfaces taniai-vm-onp-ubuntu679_z1 rg-taniai-integrated-github-actions eastus Microsoft.Network/networkInterfaces integrated-github-actions-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-nsg-onp-ubuntu rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vm-hub-ubuntu-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vnet-hub-nsg rg-taniai-integrated-github-actions eastus Microsoft.Network/networkSecurityGroups taniai-vm-hub-ubuntu-ip rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses taniai-vm-onp-ubuntu-ip rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub-pip1 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub-pip2 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-onp-pip1 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-onp-pip2 rg-taniai-integrated-github-actions eastus Microsoft.Network/publicIPAddresses vpngw-hub rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworkGateways vpngw-onp rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworkGateways integrated-github-actions-vnet rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworks taniai-vnet-onp rg-taniai-integrated-github-actions eastus Microsoft.Network/virtualNetworks
さいごに
VPN Gatewayを立てたり、GitHubにAzureリソース登録したりと、なかなか骨のある検証ができたかと思います。
この機能は、まだPublic Betaなので本番投入はできないですが、GAになったら是非活用してみてください!
オンプレとの様々な連携に夢をはせて、GAを待ちましょう!!
明日は私の上長である、pyorneさんです。
ACS事業部のご紹介
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化やGitHub Enterpriseの導入のご支援をしております。
www.ap-com.co.jp
www.ap-com.co.jp
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。
www.ap-com.co.jp