1. TOP
  2. BLOG
  3. TECH ARTICLE:第20回
    GitHubアクションで
    CIシステムを構築
TECH ARTICLE

2025年05月24日

第20回
GitHubアクションで
CIシステムを構築

今回は GitHubアクションを利用して CIシステムを構築する方法を確認します。

CI(Continuous Integration)システムは、ソフトウエア開発プロセスでビルド、テスト、イメージのアップロードまでの自動化をサポートする重要なツールです。CIシステムは開発者がアプリケーションコードを統合してエラーを素早く発見し、アプリケーションの品質を維持し、改善することに使用されます。

開発者が新しいコードをバージョン管理システム(GitHub)にPushすると、CIシステムがコードを検知して自動でビルドから、テスト、イメージのアップロードまでを実行します。求める条件を満たした時に自動で実行し、イメージのビルド時間を削減します。

主に使用するCIツールにはJenkins、GitLab CI/CD、Travis CI、CircleCI等がありますが、最近はGitHubアクションを使用するユーザーが増えています。その理由は、ほとんどの開発者がGitHubアカウントを持っているので、参入ハードルが低く、便利だからです。DebOpsの立場ではCIは単純作業のため、CI用に追加ツールを使用して管理工数を増やすより、Gitの保存と統合されたCIシステムが求められています。

例えば、JenkinsはGitHubアクションに比べて最も多く使用されるツールの一つですが、追加プラグイン管理などが複雑で初期設定が難しいため、参入ハードルが高いです。大半のスタートアップ、中小企業は GitHub チームプラン(使用料が6US$/月)を使用していると推測されます。このプランは GitHubアクションを 3,000分まで無料で使用できるため、そのコストは大きくありません。また、GitHubアクションを EC2またはVMのセルフホストで使用すると、追加費用の負担がなく使用できるため、無料の3,000分以上を使用する組織でもコスト削減に繋がります。

次は実習で詳細を説明します。

今回の実習リストを整理します。

実習の内容:
① AWS IAM ロールとIdentity Providerの生成
② AWS ECRの生成
③ Dockerfileとサンプル用 APPコードの生成
④ CIテスト用の GitHubレポジトリの生成(環境変数の登録)
⑤ GitHubアクションワークフローファイルの生成
⑥ イメージ build & push GitHubアクション作業の検証
⑦ 生成 ECRイメージ基盤 Podの生成 (イメージの検証)

他のCI設定と類似したプロセスですが、少し異なるところはイメージタグ情報を GitHubソースタグ情報として使用することや、ECR認証情報を永久資格証明のユーザー基盤ではない、トークン基盤の臨時資格証明を使用することです。

次はステップ別に実習で確認します。

1. AWS IAM ロールとIdentity Providerの生成

認証用のセキュリティー強化のため、ユーザーではなくAWS IAMロールを使用します。 ロールの Trust Relations(信頼関係)では GitHubを使用しますが、GitHub公式ドキュメントで詳細な設定を確認できます。

GitHubアクションワークフローが使用する認証をクラウドプロバイダーの AWSがOIDCトラストを提供し、AWSの ロールとそのロールが使用するリソースを定義したポリシーを事前に定義します。その設定を利用して、GitHubアクションワークフローで認証をリクエストすると、AWSが臨時トークンを発給し、認証ステップを完了して、要求事項を満たすようにAWSの関連設定を進めます。

先ず、AWSコンソールでIdentity Providerを生成します。

上記のスクリーンショットのようにIAM – Identity Providerメニューで新しいIdentity Providerの追加を選択し、OpenID Connect を選択してProvider URLと Audienceに‘https://token.actions.githubusercontent.com’と ‘sts.amazonaws.com’ をそれぞれ入力します。

ここで指定した Providerを利用して IAM ロール認証を実行します。

次にIAM ロールを生成します。コンソールメニューでRoles – Create Roleを選択し、下記のスクリーンショットのように Select trusted entityのTrusted entity typeに Webで資格証明の Web identityを選択し、以前作成したGitHubアクション設定を選択します。

組織設定のGitHub organizationで個人アカウントの場合、個人のアカウント ID(例:junghoon2)を登録します。

次に、権限設定でECR関連ポリシー(policy)を選択します。 ECRイメージを照会してPushできる権限を次のように選択します。

すると、ロールの設定が完了し、そのロールがGitHubアクションワークフローで認証用に使用されます。

2. AWS ECRの生成

GitHubアクションでビルドしたイメージをアップロードするAWS ECRを生成します。イメージレポジトリタイプにHarbor、Docker Hub、GitHub等も使用できます。AWS EKS環境であれば、追加の認証なく使用できます。ECRの使用は速度とコストに競争力があり、良い選択です。

ECRは AWSコンソールで生成できますが、できればTerraformなどのIaCツールを使用することをお勧めします。下記は ECR生成の Terraformコードです。

1.	resource "aws_ecr_repository" "github_actions_ecr" {
2.	    name = "python-flask" # ECRレポジトリ名
3.	    image_tag_mutability = "MUTABLE"
4.	}

Terraformコードは非常に単純で、簡単にECRを Terraformコードで生成できますが、以下は各ラインの説明です。

• resource “aws_ecr_repository”
ECRを生成するために Terraformリソースに aws_ecr_repositoryを使用します。 Terraformリソース名は任意の名前で github_actions_ecrを指定します。

• name
ECRレポジトリ名です。他のレポジトリと区別できるように指定します。

• image_tag_mutability
タグの変更可否の設定でMUTABLE(変更可能)とIMMUTABLE(変更不可)のオプションがあります。個別の要求事項に合うように適切に選択してください。筆者は変更可能な MUTABLEオプションを選択しました。

Terraformコードが完成し、Terraformを利用してリソースを生成します。

1.	tf init
2.	tf plan -out planfile
3.	tf apply

適用が完了すると、AWS ECRコンソールで下記のように python-flask名のレポジトリを確認できます。

3. Dockerfileとサンプル用 APPコードの生成

Dockerfileとサンプル用の簡単な APPコードを生成します。全体のコードは GitHubアドレスを参考にしてください。下記は Dockerfileの例です。

1.	# ベースイメージにPython 3.8を使用します。
2.	FROM python:3.8
3.	
4.	# 作業ディレクトリ設定
5.	WORKDIR /app
6.	
7.	# Python依存性ファイルをコンテナにコピー
8.	COPY requirements.txt requirements.txt
9.	
10.	# 依存性インストール
11.	RUN pip install -r requirements.txt
12.	
13.	# その他ファイルを作業ディレクトリにコピー
14.	COPY . .
15.	
16.	# Flaskアプリケーション実行
17.	CMD [ "python", "./app.py" ]

上記の例は、Python基本イメージを基に依存性ファイル(flask)をインストールし、実行コマンドに app.pyで指定した簡単な Dockerファイルです。その他app.py、requirement.txtファイルは共有したGitHubファイルを参照します。

4. CIテスト用GitHubレポジトリの生成 (環境変数の登録)

次は、GitHubアクションファイルを実行するGitHubレポジトリを生成します。

レポジトリ名は任意の名前で指定できます。生成が完了すると、アクションファイルで使用する環境変数を登録します。 Settingsの Actions secrets and variablesに下記のようにAWS_ECR_REPOと AWS_REGION情報を環境に合わせて登録します。

AWS_ECR_REPOにはECRレポジトリ名を指定します。GitHubアクションワークフローファイルで環境変数を使用し、その名前で ECRレポジトリが生成されます。

5. GitHubアクションワークフローファイルの生成

以上で事前準備が完了したので、GitHubアクションファイルを作成します。アクションファイルは下記のように .github/workflows/ ディレクトリに.yml(又はyaml) 形式で保存します。

イメージの build & pushを実行するアクションファイルの例です。(GitHubリンク)

1.	name: Docker Build and Push
2.	
3.	on:
4.	    push:
5.	        tags:
6.	        - '*' # 全てのタグに対してこのワークフローをトリガーします。
7.	
8.	jobs:
9.	    build-and-push:
10.	        runs-on: ubuntu-latest
11.	
12.	        permissions:
13.	            id-token: write
14.	            contents: read
15.	
16.	        steps:
17.	        - name: Checkout Repository
18.	            uses: actions/checkout@v4
19.	
20.	        - name: Configure AWS credentials
21.	            uses: aws-actions/configure-aws-credentials@v4
22.	            with:
23.	                aws-region: ${{ vars.AWS_REGION }}
24.	                role-to-assume: arn:aws:iam::516696002612:role/github-actions-ci 
25.	
26.	        - name: Login to Amazon ECR
27.	            id: login-ecr
28.	            uses: aws-actions/amazon-ecr-login@v2
29.	
30.	        - name: Extract tag name
31.	            id: extract_tag
32.	            shell: bash
33.	            run: echo "IMAGE_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
34.	
35.	        - name: echo image tag
36.	            run: echo $IMAGE_TAG
37.	
38.	        - name: Build and Push Docker Image
39.	            uses: docker/build-push-action@v5
40.	            with:
41.	                push: true
42.	                tags: ${{ steps.login-ecr.outputs.registry }}/${{ vars.AWS_ECR_REPO }}:${{ env.IMAGE_TAG }}

• on.push.tags. ‘*’
ワークフローは GitHubレポジトリにタグがPushされる度にトリガーされます。ここで ‘*‘ は全てのタグでこのワークフローを実行することを意味します。コードを変更してタグをPushすると、ワークフローファイルが実行します。明示的にタグをコネクションした場合のみワークフローを実行するように指定すると、mainにマージする場合は、ワークフローは実行されません。

• jobs.build-and-push.runs-on: ubuntu-latest
この作業は ubuntu-latest環境で実行されます。Dockerイメージをbuildして、Amazon ECRでPushするステップを含みます。

• permissions.id-token, contents
id-token: writeと contents: read権限を設定して、GitHub Actionsが必要な権限でIDトークンを作成し、レポジトリコンテンツを読めるようにします。

• steps
個別アクションを定義します。

• name: Checkout Repository
actions/checkout@v4アクションでレポジトリのソースコードをチェックアウト(切替え)します。 GitHubアクションに使用できる多様なアクションリストは、下記 github.com/actionsで確認できます。

• name: Configure AWS credentials
aws-actions/configure-aws-credentials@v4アクションで、AWS資格証明を作成します。ここでAWSリージョンと GitHub Actionsが使用するIAM Roleの ARNを指定します(vars.AWS_REGIONと role-to-assumeの値を使用)。 前で生成したIAM Roleの情報を使用します。

• name: Login to Amazon ECR
aws-actions/amazon-ecr-login@v2アクションで、Amazon ECRにログインします。このステップは Dockerイメージを Amazon ECRにPushする時に必要な認証情報を取得します。

• id: login-ecr
login-ecrはこのステップのユニーク識別子(ID)です。このIDを使用して、ステップの出力(output)を他のステップで参照できます。例えば、イメージを pushするsteps.login-ecr.outputs.some-outputと同じ方式で使用します。

• name: Extract tag name
自動的に生成されるハッシュ値を基に、Dockerイメージタグとして使用する他のアクションファイルと異なる部分です。 GitHubのタグ情報を環境変数に保存して、これをイメージタグ情報に使用する設定です。 Bashスクリプトを使用してタグ名を抽出し、これを環境変数 IMAGE_TAGに保存します。この変数は Dockerイメージのタグとして使用されます。

• name: echo image tag
デバッグ用にイメージタグ情報を出力する設定です。

• name: Build and Push Docker Image
docker/build-push-action@v5アクションで、Dockerイメージをbuildして、Pushします。 push: trueはイメージをレジストリで実際にPushすることを意味します。Tagsはイメージに使用するタグを指定します。ここでAmazon ECRのレジストリアドレス、ECRレポジトリ名と前に抽出したイメージタグを使用します。

以前にGitHubに設定した環境変数を ECRレポジトリ名で指定します。

以上でGitHubアクションファイルの設定が完了しました。次は、タグを Pushして実際 GitHubアクションワークフローを実行します。

6. イメージ build & push GitHubアクション作業の検証

では、ローカルで新しいタグを生成し、GitHubにそのタグを Pushしてアクションワークフローファイルを実行します。

新しいタグを作成します。

1.	(jerry-dev:sns)github-actions-python$ git tag -a v0.1.3

タグをリモートの originに pushします。

1.	(jerry-dev:sns)github-actions-python$ git push --tags
2.	Enumerating objects: 1, done.
3.	Counting objects: 100% (1/1), done.
4.	Writing objects: 100% (1/1), 153 bytes | 153.00 KiB/s, done.
5.	Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
6.	To https://github.com/junghoon2/github-actions-python.git
7.	* [new tag] v0.1.3 -> v0.1.3

次は、リモートの GitHubの Actions メニューを確認すると、下記のように自動的にJobsを実行するようになっています。

メニューをクリックすると、詳細作業ログが確認できます。

エラーがなく作業が終了すると、下記のようなチェック表示を確認できます。

次は、作業が終了したので、作業結果をAWS ECRコンソールで確認すると、アクションファイルの設定通りにGitHubタグ名でイメージタグが指定され、イメージが Pushされていることを確認できます。

7. 生成したECRイメージ基盤 Podの生成 (イメージの検証)

最後のステップで生成されたイメージアドレスを Podのマニフェストに表示して、正常にイメージが生成されたかを検証します。基本 deploymentマニフェストを使用して、イメージ部分だけ先程生成したECRイメージアドレスとタグに変更します。

1.	apiVersion: apps/v1
2.	kind: Deployment
3.	metadata:
4.	    name: python-flask
5.	    namespace: default
6.	spec:
7.	    selector:
8.	        matchLabels:
9.	            app: python-flask
10.	    template: 
11.	        metadata:
12.	            labels:
13.	                app: python-flask
14.	        spec:
15.	            containers:
16.	            - name: python-flask
17.	                image: 516696002612.dkr.ecr.ap-northeast-2.amazonaws.com/python-flask:v0.1.3

image
各自生成したイメージアドレスに変更します。イメージアドレスは GitHubアクションファイル又は下記のように ECRコンソールで参照できます。

YAMLファイルを適用(apply)し、ポートフォワーディングを利用して接続します。

1.	$ k apply -f deployment/deploy-ecr-python-flask.yaml 
2.	deployment.apps/python-flask created
3.	
4.	$ k port-forward pod/python-flask-6f75c79c8-pdpnh 8080:8080
5.	Forwarding from 127.0.0.1:8080 -> 8080
6.	Forwarding from [::1]:8080 -> 8080

正常にPodが実行されて、ブラウザでイメージ内容の変更も確認できます。

次は設定したGitHubアクションファイルを利用してGitHubにタグがPushされると、自動的にイメージをビルドしてリモートの ECRにPushまで行う CIシステムの構成を完了しました。 CIシステムは1回設定すると、その後は変更がほとんどない作業です。

以上で GitHubアクションを利用して Dockerイメージの BuildとPushまでを行い、 CIシステムを構成しました。

お気軽にお問い合わせください

製品に関する事やご不明な点など、お気軽にご相談ください。
また、ジェニファーソフトでは2週間の無償トライアルを提供しています。

詳しく知りたい方は
導入や費用のご相談は