内容
GitHub Actions WorkflowのJob実行に使われる環境にセルフホステッド ランナー(AWS CodeBuild)を使用する
今回は、セルフホステッド ランナーを使ったJobでRDSクラスターの操作を行う
また、CodeBuildのデプロイにはCFNを使用する
セルフホステッド ランナー
ランナーはJob実行に使用する環境で、
GitHub ホステッド ランナーとして、Linux、Windows、macOSが用意されており、
以下のように runs-on
で指定する
jobs:
check-bats-version:
runs-on: ubuntu-latest
セルフホステッド ランナーも使用することができ、一つの方法としてAWS CodeBuildでランナーを作成することができる
以下のように各種カスタマイズが可能
※VPC等EC2でのみ設定可能な項目あり
AWS CodeBuild用に用意されているイメージはドキュメント参照
例えば、Lambda用のイメージ aws/codebuild/amazonlinux-x86_64-lambda-standard:python3.11
の中身はDockerfileで確認できる
GitHub ホステッド ランナーのLinuxとはインストールされているツール、ライブラリが異なるため注意が必要
(GitHub ホステッド ランナーLinuxで使える jq
がLambdaでは使用できない等)
また、料金に違いがあり、
プライベート リポジトリの場合、GitHub ホステッド ランナーの使用時間(分)に応じて料金が発生するが、
セルフホステッド ランナーは料金が発生しない(AWS料金は発生する)
CodeBuild設定内容
使用するコンピューティング環境のイメージやスペックの設定、
GitHubの認証、リポジトリ指定、GitHubからCodeBuild環境を呼び出すためのWebhook登録等を行う
以下AWS CodeBuildに必要な主な設定
ソース
対象のGitHubリポジトリの接続を行う
OAuthを使用した接続(username, passwordでサインイン)か、個人用アクセストークン(PAT)を登録して接続する
GitHub Apps で生成したトークンは使用できなかった
今回は、OAuthを使用した接続を行った
[!IMPORTANT]
Githubの認証情報はAWSアカウント×リージョンに対して1個しか登録できない
そのため、同アカウント、リージョンの他CodeBuildプロジェクトで別のGithub認証を行うと先に登録した認証情報が消えてしまう
Webhook登録
GitHubからCodeBuild環境を呼び出すためのWebhook登録を行う
イベントタイプには WORKFLOW_JOB_QUEUED
を選択する
この登録行うと、以下のようにGitHubにWebhookが登録される
そのため、GitHubの認証が通っている状態でなければこの設定はできない
コンピューティング環境
今回は処理時間の都合上EC2を選択
指定するロールにRDSの操作権限を付与する
CFN 実装
Resources:
CodebuildGitHubActionsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /aws/codebuild/CodebuildGitHubActions
RetentionInDays: 30
UpdateReplacePolicy: Delete
DeletionPolicy: Delete
CodebuildGitHubActionsRole:
Type: AWS::IAM::Role
Properties:
RoleName: CodebuildGitHubActionsRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- codebuild.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: CodebuildGitHubActionsRolePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
# RDS操作用権限
- Effect: Allow
Action:
- rds:DescribeDBClusters
- rds:StartDBCluster
- rds:StopDBCluster
Resource: !Ref RdsClusterArn
# CDKでは以下権限不要
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/CodebuildGitHubActions
- !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/CodebuildGitHubActions:*
- Effect: Allow
Action:
- codebuild:CreateReportGroup
- codebuild:CreateReport
- codebuild:UpdateReport
- codebuild:BatchPutTestCases
- codebuild:BatchPutCodeCoverages
Resource:
- !Sub arn:${AWS::Partition}:codebuild:${AWS::Region}:${AWS::AccountId}:report-group/CodebuildGitHubActionsProject-*
CodebuildGitHubActionsProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: NO_ARTIFACTS
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
PrivilegedMode: false
Type: LINUX_CONTAINER
LogsConfig:
CloudWatchLogs:
GroupName: !Ref CodebuildGitHubActionsLogGroup
Status: ENABLED
Name: CodebuildGitHubActionsProject
ServiceRole: !GetAtt CodebuildGitHubActionsRole.Arn
Source:
GitCloneDepth: 1
Location: https://github.com/xxxxxx.git
ReportBuildStatus: false
Type: GITHUB
TimeoutInMinutes: 30
CDKで実装した場合、
CodeBuildで使用するロールに付与しているRDS操作用権限以外は自動的に付与される
今回、GitHubの認証、Webhookの登録は手動で行うようにした
(認証情報登録を手動で行うと、認証を前提としているWebhook登録も手動になる)
PATをSecretsManagerに登録してよい場合等は、
CFNの場合、AWS::CodeBuild::SourceCredential、CDKの場合、GitHubSourceCredentialsを使用して認証情報を登録できる
このGithub認証情報はAWSアカウント×リージョンに対して1個の独立したリソースのため、
実装上、CodeBuildプロジェクトとの関連付けするようなことはない
GitHub Actions 実装
jobs:
describe_rds_cluster:
name: Start Rds Cluster
runs-on: codebuild-CodebuildGitHubActionsProject-${{ github.run_id }}-${{ github.run_attempt }}
timeout-minutes: 30
outputs:
cluster_status: ${{ steps.get_cluster_status.outputs.status }}
steps:
- name: Get Cluster Status
id: get_cluster_status
shell: bash
run: |
status=$(aws rds describe-db-clusters \
--db-cluster-identifier ${{ inputs.clusterName }} \
--query DBClusters[0].Status)
status=$(echo $status | tr -d '"')
echo $status
echo "status=${status}" >> $GITHUB_OUTPUT
AWS CodeBuildのランナーを使用する場合、runs-on
は、
codebuild-{CodeBuild Project Name}-${{ github.run_id }}-${{ github.run_attempt }}
となる、{CodeBuild Project Name}
部分はデプロイしたCodeBuildのプロジェクト名
このruns-on
のJobが実行される際にCodeBuildに対するWebhookが実行されるが、
CodeBuild側の権限不足によりエラーが発生した場合等、Webhookにエラー応答が返ってきた場合、
Jobが即時エラーとはなってくれず、いつ終了するのか不安になるので、
timeout-minutes
は一応設定しておいたほうが良い
ログ
CodeBuildはもちろんCloudWatch Logsにログを出力するが、
GitHubからWebhookを実行された際にCodeBuild側の権限不足によりエラーが発生した場合等、AWS側にログが残らない
その場合、エラーはGithub側のWebhook履歴で確認できる
ただし、Webhookが登録されていると、runs-on: ubuntu-latest
等、
セルフホステッド ランナー以外でもWebhookが実行され、エラーログが多数残るため、ほとんどのエラーログは無関係