APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

GitHub ActionsとAzureのPrivate Networkとの統合がサポートされましたよ

はじめに

おはようございます!こんにちは!こんばんわ!
ACS事業部の谷合です。
この記事は エーピーコミュニケーションズ Advent Calendar 2023 の8日目の投稿です。

先月ではありますが、GitHub-hosted runnerとAzureのPrivate Networkの統合がPublic Betaでサポートされたのはご存じでしょうか?

github.blog

詳細は、以下のドキュメントに記載がありますが、簡単に言うとGitHub ActionsでWorkflowを実行時に、AzureのPrivate Network経由で
オンプレ環境と通信ができるようになる機能です。この時、Azure VPN GatewayやAzure ExpressRouteでAzure バックボーン経由でセキュアな
通信が実現できます!GitHub-hosted runnerから、E2Eテストなどの時にオンプレのVMにあるDBなどと通信ができる、何とも素敵な機能ですよね。

docs.github.com

今回はこの機能の実装方法を解説していきます。

アーキテクチャ

GitHubから公開されているアーキテクチャ図は以下の通りです。

  1. A GitHub Actions workflow is triggered.
  2. The GitHub Actions service creates a runner.
  3. The runner service deploys the GitHub-hosted runner's network interface card (NIC) into your Azure VNET.
  4. The runner agent picks up the workflow job. The GitHub Actions service queues the job.
  5. The runner sends logs back to the GitHub Actions service.
  6. The NIC accesses on-premise resources.

参照:https://docs.github.com/ja/enterprise-cloud@latest/admin/configuration/configuring-private-networking-for-hosted-compute-products/about-using-github-hosted-runners-in-your-azure-virtual-network

上記のように説明文付きでアーキテクチャ図が公開されていますが、要約すると、
「Workflowが実行されると、AzureにNICがデプロイされ、Network Security Group(以降NSG)のポリシーに従い、オンプレと通信ができる」
です。

これを実際にAzureの世界に落とし込むと以下の通りとなります。
以降で解説していく環境を図にしたものとなりますが、Azure内でクラウドとオンプレを疑似的に実装してみています。
GitHubがAzure VnetにNICをデプロイし、NICにSubnetに紐づくNSGのポリシーに従い、疑似オンプレのMySQLと通信をしています。
この時、Vnet間はVPN Gateway経由でS2S接続をしています。

実装してみよう

前提

  1. GitHub Enterpriseアカウントを有していること

  2. 疑似オンプレ側のVMにMySQLをインストールし、mysqlコマンドでリモート接続ができること

  3. GitHub ActionsとAzureのPrivate Networkとの統合でサポートされるリージョンには、East US、East US 2、West US 2のみ (このリストにないリージョンのサポートをリクエストするには、リージョンリクエストフォームにご記入ください)

  4. 以降の工程で、GitHub.Network リソースプロバイダを登録し、サブネットを委任します。
    この時サブスクリプション共同作成者ロールとネットワーク共同作成者ロールを持つ Azure アカウントが必要なので、あらかじめロールを付与しておくこと

以降の手順は、以下のドキュメントに沿って実施いきます。

docs.github.com

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スクリプトを作成します。
このスクリプトを実行することで、以下の動作が実行されます。

  1. リソースグループ、NSG、VNet、Subnet、Network Settings が作成される。
  2. GitHub.Network リソースプロバイダをサブスクリプションに登録される。
  3. 作成したサブネットを 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

本記事の投稿者: 谷合純也
AKS/ACA、GitHubをメインにインフラ系のご支援を担当しています。
junya0530さんの記事一覧 | Zenn