背景
- ソースリポジトリをセルフホステッドのGitLabからGitHubに移行する計画がある
- GitHubには社内からのみアクセスしたいので、GitHub Enterpriseの機能でソースIPを絞る必要がある
- GitHubホステッドランナーはIPアドレスが特定できないため使用不可
- セルフホステッドのGitHub Actionsランナーが必要となる
今回の記事の主目的:
セルフホステッドのGitHub Actionsランナーをがっつりとホスティングするのは避けたいので、何らかのサービスに乗りたいと思っていた。
そうしたところ、以下の機能が今年4月にリリースされたということを知り、試してみた。
https://docs.aws.amazon.com/codebuild/latest/userguide/action-runner.html
ランナーの中でやっていること:
以下のようにJavaのDBテストを実施する(SpringBoot)
- MySQLのコンテナを起動
- actions/checkout
- actions/setup-java
- mvn test
大まかな手順:
-
まずは、GitHubのリポジトリにWebhookを登録し、CodeBuildと連携する。(豆蔵さんの記事のまま)
-
ソースIPを絞らずに、JavaのDBテストを実装する
-
ソースIPを絞るために、VPC + Subnet + NATGateway + EIPの構成をcdkで作る
-
上記のネットワーク資源をCodeBuildと連携する(CodeBuildを編集する)
-
GitHubのOrganizationsでソースIPの絞り込みを行う
以下に、手順に沿って説明していきます。
手順詳細
1. GitHubのリポジトリにWebhookを登録し、CodeBuildと連携する
こちらは、豆蔵さんの記事が非常に分かりやすいので、リンクを貼っておきます。
https://developer.mamezou-tech.com/blogs/2024/04/29/githubactions-codebuild-runner/
2. ソースIPを絞らずに、JavaのDBテストを実装する
SpringBootのアプリでMySQLを使ったテストを実施します。
ここでは、GitHub Actionsのスクリプトを掲載します。
name: test-codebuild-runner
on:
push:
jobs:
build:
runs-on: codebuild-GitHubActionsExampleRunner-${{ github.run_id }}-${{ github.run_attempt }}
services:
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: database-name
TZ: 'Asia/Tokyo'
MYSQL_CHARACTER_SET_SERVER: 'utf8mb4'
MYSQL_COLLATION_SERVER: 'utf8mb4_unicode_ci'
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=10
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt'
cache: 'maven'
- name: Run tests
run: mvn test
3. ソースIPを絞るために、VPC + Subnet + NATGateway + EIPの構成をcdkで作る
ここでは、cdkのソースを掲載しておきます。
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class VpcWithCodedeployCdkProjectStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, 'MyVpc', {
cidr: '10.x.x.x/16',
maxAzs: 1, // アベイラビリティゾーンの数
natGateways: 1,
subnetConfiguration: [
{
cidrMask: 24,
name: 'PrivateSubnet',
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
{
cidrMask: 24,
name: 'PublicSubnet',
subnetType: ec2.SubnetType.PUBLIC,
},
],
});
// セキュリティグループの作成
const securityGroup = new ec2.SecurityGroup(this, 'MySecurityGroup', {
vpc,
allowAllOutbound: true, // アウトバウンドで全てのIPに送信を許可
description: 'Allow all outbound traffic',
securityGroupName: 'MySecurityGroup',
});
}
}
cdkデプロイしたら、EIPの値をメモします。(後で、GitHubに設定します)
4. 上記のネットワーク資源をCodeBuildと連携する(CodeBuildを編集する)
ここでは、1. の手順からの変更点のみを掲載します。(マネジメントコンソールの画面スクショです)
- ネットワーク資源との連携と直接関係ありませんが、ランナーの中でDockerを使うために「特権付与」のチェックをします。(これをチェックしないとDockerInDockerが起動しません)
- VPC、サブネット、セキュリティグループを設定します
- 「VPC設定の確認」を押すと、設定の成否が確認できます(便利です)
5. GitHubのOrganizationsでソースIPの絞り込みを行う
こちらは画面キャプチャーなどを載せられないので、設定の手順へのリンクを貼っておきます。
Allow IP ListにEIPの値を追加します。
手順リンク
まとめ
この記事では、GitHubリポジトリへの移行に伴い、AWS CodeBuildを利用してセルフホステッドのGitHub Actionsランナーを設定し、ネットワーク設定を行う手順について解説しました。これにより、ソースIPを絞り込む必要がある場合でも、セキュアにビルドを実行することができます。
ホスティングするというよりは、GitHub ActionsとAWS CodeBuildを連携するという感じで、かなりモダンなアーキテクチャーになりました!
注意点
実際に二本目のワークフローを組んだ時にハマった点を書いておきます。
新しいビルドプロジェクトを作成する際にはGitHubのIPアドレス制御を一時的に外す
新しいビルドプロジェクトを作成する際に、IPアドレス制御を有効なままにすると、webhookの登録に失敗します。これは、AWS側からGitHubへのアクセスがVPCを介さない操作のため、IPアドレス制御を入れてあるとはねられるためです。
VPCをCodeBuildに紐づける際には、EC2操作権限のあるポリシーをアタッチする必要がある
CodeBuildの生成時に自動的にRoleが作成されていますが、VPCを設定する際には、EC2に対して「リスト, 許可の管理, 書き込み」が可能なポリシーをアタッチする必要があります。これが無いと、SecurityGroupの設定が出来ないという旨のエラーが発生します。
参考記事
非常に参考になりました。ありがとうございます!