<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SSM Parameter Store - CayTech Lab</title>
	<atom:link href="https://caymezon.com/tag/ssm-parameter-store/feed/" rel="self" type="application/rss+xml" />
	<link>https://caymezon.com</link>
	<description></description>
	<lastBuildDate>Sat, 09 May 2026 04:16:13 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://caymezon.com/wp-content/uploads/2026/01/cropped-CayTechLab-32x32.jpg</url>
	<title>SSM Parameter Store - CayTech Lab</title>
	<link>https://caymezon.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<atom:link rel='hub' href='https://caymezon.com/?pushpress=hub'/>
	<item>
		<title>EC2 + CodePipeline（Code 3兄弟）で WebアプリをCI/CDデプロイする【完全 AWS CI/CD 体験】</title>
		<link>https://caymezon.com/aws-handson-ec2-codepipeline/</link>
					<comments>https://caymezon.com/aws-handson-ec2-codepipeline/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Sat, 09 May 2026 04:16:13 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></category>
		<category><![CDATA[ALB]]></category>
		<category><![CDATA[appspec]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[buildspec]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[CloudFormation]]></category>
		<category><![CDATA[CodeArtifact]]></category>
		<category><![CDATA[CodeBuild]]></category>
		<category><![CDATA[CodeCommit]]></category>
		<category><![CDATA[CodeDeploy]]></category>
		<category><![CDATA[CodePipeline]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[SSM Parameter Store]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20417</guid>

					<description><![CDATA[<p>目次 はじめにキーワード解説① 全体構成を理解するCodeArtifact とはbuildspec.yml の処理フロー② CloudFormation スタックを作成する③ Outputs を確認する④ git-rem [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-ec2-codepipeline/">EC2 + CodePipeline（Code 3兄弟）で WebアプリをCI/CDデプロイする【完全 AWS CI/CD 体験】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2" checked><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに</a></li><li><a href="#toc2" tabindex="0">キーワード解説</a></li><li><a href="#toc3" tabindex="0">① 全体構成を理解する</a><ol><li><a href="#toc4" tabindex="0">CodeArtifact とは</a></li><li><a href="#toc5" tabindex="0">buildspec.yml の処理フロー</a></li></ol></li><li><a href="#toc6" tabindex="0">② CloudFormation スタックを作成する</a></li><li><a href="#toc7" tabindex="0">③ Outputs を確認する</a></li><li><a href="#toc8" tabindex="0">④ git-remote-codecommit をインストールする</a></li><li><a href="#toc9" tabindex="0">⑤ ソースコードを CodeCommit に push する</a><ol><li><a href="#toc10" tabindex="0">⑤-1 CodeCommit リポジトリを clone する</a></li><li><a href="#toc11" tabindex="0">⑤-2 ソースコードをコピーして push する</a></li></ol></li><li><a href="#toc12" tabindex="0">⑥ CodePipeline の動作を確認する</a></li><li><a href="#toc13" tabindex="0">⑦ CodeBuild のログを確認する</a></li><li><a href="#toc14" tabindex="0">⑧ CodeDeploy の状況を確認する</a></li><li><a href="#toc15" tabindex="0">⑨ アプリの動作確認をする</a></li><li><a href="#toc16" tabindex="0">⑩ CI/CD サイクルを体験する</a></li><li><a href="#toc17" tabindex="0">⑪ CodeArtifact のパッケージを確認する</a></li><li><a href="#toc18" tabindex="0">⑫ SSM Session Manager で EC2 に接続する（オプション）</a></li><li><a href="#toc19" tabindex="0">⑬ リソースを削除する</a></li><li><a href="#toc20" tabindex="0">まとめ：学んだ概念</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「GitHub Actions は GitHub に依存してしまう。AWS だけで CI/CD を完結させたい」——そんなニーズに応えるのが <strong>AWS Code 4 兄弟（CodeCommit・CodeBuild・CodeDeploy・CodePipeline）</strong> です。さらに共通ライブラリは <strong>AWS CodeArtifact</strong> で管理するフルマネージドな AWS CI/CD パイプラインを構築します。</p>
<p>前のハンズオン（<a href="https://caymezon.com/aws-handson-ec2-github-actions/">EC2 + GitHub Actions</a>）との最大の違いは、<strong>すべてが AWS の中で完結すること</strong>です。ソース管理・ビルド・ライブラリ管理・デプロイ、すべてを AWS サービスで担います。</p>
<pre><code class="language-plaintext">[CodeCommit リポジトリ] ← git push
         ↓
[CodePipeline: my-cp-pipeline]
  Stage 1: Source  — CodeCommit からソースを取得
  Stage 2: Build   — CodeBuild で mvn package
                        ├─ CodeArtifact から認証トークン取得
                        ├─ common-lib を CodeArtifact に publish
                        ├─ CodeArtifact から common-lib を取得
                        └─ webapp.war を生成
  Stage 3: Deploy  — CodeDeploy で EC2 に配備
                        ├─ Tomcat を停止
                        ├─ WAR を配置
                        └─ Tomcat を再起動
         ↓
[EC2: Tomcat + Spring Boot]  my-cpapp
         ↓
[ALB: my-cp-alb] ← インターネット
         ↓
[RDS MySQL: my-cp-rds]</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li>CodeCommit + CodeBuild + CodeDeploy + CodePipeline による完全 AWS CI/CD</li>
<li>CodeArtifact による Maven ライブラリの社内管理（Maven Central のプロキシも体験）</li>
<li><code>buildspec.yml</code> でビルド手順をコード化する</li>
<li><code>git-remote-codecommit</code> で AWS CLI 認証のまま CodeCommit に push する</li>
<li>CloudFormation で全リソース（パイプラインを含む）を一括構築</li>
</ul>
<hr>
<blockquote>
<p>コード詳細は <a href="https://github.com/caymezon/aws-handson/tree/main/ec2-codepipeline">GitHub</a> を参照してください。</p>
</blockquote>
<hr>
<p><!-- ![CodePipelineの3ステージ全成功とブラウザ確認画面](images/codepipeline-success.jpg) --></p>
<p><!-- <a rel="nofollow" href="//af.moshimo.com/af/c/click?a_id=1384942&p_id=170&pc_id=185&pl_id=4062&url=https%3A%2F%2Fwww.amazon.co.jp%2Fs%3Fk%3D%25E6%259C%25AC%2BAWS%2B%25E9%2596%258B%25E7%2599%25BA%26__mk_ja_JP%3D%25E3%2582%25AB%25E3%2582%25BF%25E3%2582%25AB%25E3%2583%258A%26crid%3D1DE63UBHFOR4K%26sprefix%3D%25E6%259C%25AC%2Baws%2B%25E9%2596%258B%25E7%2599%25BA%252Caps%252C167%26ref%3Dnb_sb_noss" referrerpolicy="no-referrer-when-downgrade" attributionsrc>Amazon検索[本 AWS 開発]</a><img decoding="async" src="//i.moshimo.com/af/i/impression?a_id=1384942&p_id=170&pc_id=185&pl_id=4062" width="1" height="1" style="border:none;" alt="" loading="lazy"> --></p>
<p><!-- <!-- START MoshimoAffiliateEasyLink --><script type="text/javascript">(function(b,c,f,g,a,d,e){b.MoshimoAffiliateObject=a;b[a]=b[a]||function(){arguments.currentScript=c.currentScript||c.scripts[c.scripts.length-2];(b[a].q=b[a].q||[]).push(arguments)};c.getElementById(a)||(d=c.createElement(f),d.src=g,d.id=a,e=c.getElementsByTagName("body")[0],e.appendChild(d))})(window,document,"script","//dn.msmstatic.com/site/cardlink/bundle.js?20220329","msmaflink");msmaflink({"n":"AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解)","b":"SBクリエイティブ","t":"","d":"https:\/\/m.media-amazon.com","c_p":"\/images\/I","p":["\/51DEDQXj6oL._SL500_.jpg","\/41F589smNwL._SL500_.jpg","\/41R6f9yyCWL._SL500_.jpg","\/41HqWQ9BvmL._SL500_.jpg","\/41p8p0ZU79L._SL500_.jpg","\/41qLC-fndBL._SL500_.jpg","\/41fcLv9VT5L._SL500_.jpg","\/51lRvCsvHqL._SL500_.jpg"],"u":{"u":"https:\/\/www.amazon.co.jp\/dp\/4815607850","t":"amazon","r_v":""},"v":"2.1","b_l":[{"id":1,"u_tx":"Amazonで見る","u_bc":"#f79256","u_url":"https:\/\/www.amazon.co.jp\/dp\/4815607850","a_id":1384942,"p_id":170,"pl_id":27060,"pc_id":185,"s_n":"amazon","u_so":1},{"id":2,"u_tx":"楽天市場で見る","u_bc":"#f76956","u_url":"https:\/\/search.rakuten.co.jp\/search\/mall\/AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8%20(%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3)\/","a_id":1384917,"p_id":54,"pl_id":27059,"pc_id":54,"s_n":"rakuten","u_so":2},{"id":3,"u_tx":"Yahoo!ショッピングで見る","u_bc":"#66a7ff","u_url":"https:\/\/shopping.yahoo.co.jp\/search?first=1\u0026p=AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8%20(%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3)","a_id":1466950,"p_id":1225,"pl_id":27061,"pc_id":1925,"s_n":"yahoo","u_so":3}],"eid":"eaCUB","s":"s"});</script></p>
<div id="msmaflink-eaCUB">リンク</div>
<p><!-- MoshimoAffiliateEasyLink END --> --></p>
<h2><span id="toc2">キーワード解説</span></h2>
<table>
<thead>
<tr>
<th>用語</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>CodeCommit</strong></td>
<td>Git リポジトリを AWS 内でフルマネージドに管理するサービス。GitHub の AWS 版</td>
</tr>
<tr>
<td><strong>CodeBuild</strong></td>
<td><code>buildspec.yml</code> でビルド手順をコード化し、マネージド環境でビルドを実行するサービス</td>
</tr>
<tr>
<td><strong>CodeDeploy</strong></td>
<td>EC2 への WAR 配置・サービス再起動・ヘルスチェックを自動化するサービス</td>
</tr>
<tr>
<td><strong>CodePipeline</strong></td>
<td>Source → Build → Deploy のステージを自動で連結する CI/CD オーケストレーター</td>
</tr>
<tr>
<td><strong>CodeArtifact</strong></td>
<td>Maven/npm/PyPI ライブラリを AWS 内で管理・共有するマネージドリポジトリ。Maven Central のプロキシとしても機能</td>
</tr>
<tr>
<td><strong>buildspec.yml</strong></td>
<td>CodeBuild が実行するビルドステップをコードで定義するファイル</td>
</tr>
<tr>
<td><strong>appspec.yml</strong></td>
<td>CodeDeploy がデプロイ時に実行するファイル配置とフックスクリプトを定義するファイル</td>
</tr>
<tr>
<td><strong>git-remote-codecommit</strong></td>
<td>AWS CLI の認証情報を使って CodeCommit に push できるツール（Git 専用認証情報の設定不要）</td>
</tr>
<tr>
<td><strong>SSM Parameter Store</strong></td>
<td>DB パスワードなどの設定値を暗号化して管理し、EC2 から安全に取得できる AWS のサービス</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc3">① 全体構成を理解する</span></h2>
<h3><span id="toc4">CodeArtifact とは</span></h3>
<p>CodeArtifact は AWS が提供するマネージドな Maven リポジトリです。GitHub Packages との大きな違いの一つが <strong>Maven Central のプロキシ機能</strong>です。</p>
<pre><code class="language-plaintext">mvn package
  └─ CodeArtifact (my-cp-libs)
       ├── 社内ライブラリ: com.example:common-utils:1.0.0  ← CodeBuild が publish
       └── 外部ライブラリ: org.springframework.boot:*      ← Maven Central から透過的に取得</code></pre>
<p>外部依存関係も CodeArtifact 経由でキャッシュされるため、<strong>インターネット接続なしでも再現性の高いビルドが可能</strong>になります。</p>
<h3><span id="toc5">buildspec.yml の処理フロー</span></h3>
<p><code>buildspec.yml</code> は CodeBuild が実行するビルド手順を定義します：</p>
<pre><code class="language-yaml">phases:
  install:
    runtime-versions:
      java: corretto17    # Amazon Corretto 17 を使用

  pre_build:
    commands:
      # settings.xml に書き込んで Maven 認証を設定
      - CODEARTIFACT_TOKEN=$(aws codeartifact get-authorization-token ...)
      - CODEARTIFACT_URL=$(aws codeartifact get-repository-endpoint ...)

  build:
    commands:
      # common-lib を CodeArtifact に publish（すでに存在する場合はスキップ）
      - mvn deploy -f common-lib/pom.xml -Dcodeartifact.url="$CODEARTIFACT_URL"
      # app の WAR をビルド（CodeArtifact から common-lib を取得）
      - mvn package -f app/pom.xml -DskipTests -Dcodeartifact.url="$CODEARTIFACT_URL"
      - cp app/target/webapp.war webapp.war

artifacts:
  files:
    - webapp.war
    - appspec.yml
    - scripts/**/*   # CodeDeploy のフックスクリプト</code></pre>
<p><strong>ポイント</strong>：pom.xml の CodeArtifact URL はプレースホルダー（<code>${codeartifact.url}</code>）で、buildspec.yml が <code>-Dcodeartifact.url=</code> で実行時に渡します。pom.xml を事前に編集する必要はありません。</p>
<hr>
<h2><span id="toc6">② CloudFormation スタックを作成する</span></h2>
<p>自分の IP アドレスを確認し（<code>curl https://checkip.amazonaws.com</code>）、CloudFormation でインフラを一括作成します：</p>
<pre><code class="language-cmd">aws cloudformation deploy ^
  --template-file ec2-codepipeline/infra/template.yaml ^
  --stack-name my-cpapp-stack ^
  --parameter-overrides EmployeeId=my DBPassword=Handson1234! MyIP=123.456.78.901/32 ^
  --capabilities CAPABILITY_NAMED_IAM ^
  --region ap-northeast-1</code></pre>
<blockquote>
<p><strong>所要時間：約 10〜15 分</strong>（VPC・EC2・RDS の作成に時間がかかります）</p>
</blockquote>
<p>CloudFormation スタックが作成するリソース：</p>
<table>
<thead>
<tr>
<th>リソース</th>
<th>名前</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC / サブネット / IGW</td>
<td><code>my-cp-vpc</code></td>
</tr>
<tr>
<td>EC2（Amazon Linux 2023 + Tomcat 10.1）</td>
<td><code>my-cpapp</code></td>
</tr>
<tr>
<td>ALB</td>
<td><code>my-cp-alb</code></td>
</tr>
<tr>
<td>RDS MySQL 8.0</td>
<td><code>my-cp-rds</code></td>
</tr>
<tr>
<td>S3（パイプラインアーティファクト）</td>
<td><code>my-cp-artifacts-{アカウントID}</code></td>
</tr>
<tr>
<td>CodeCommit リポジトリ</td>
<td><code>my-cpapp</code></td>
</tr>
<tr>
<td>CodeArtifact ドメイン / リポジトリ</td>
<td><code>my-domain</code> / <code>my-libs</code></td>
</tr>
<tr>
<td>CodeBuild プロジェクト</td>
<td><code>my-cpapp-build</code></td>
</tr>
<tr>
<td>CodePipeline</td>
<td><code>my-cp-pipeline</code></td>
</tr>
<tr>
<td>CodeDeploy Application + Deployment Group</td>
<td><code>my-cpapp</code></td>
</tr>
<tr>
<td>SSM Parameter Store</td>
<td><code>/my/cpapp/db-host</code>, <code>/my/cpapp/db-password</code></td>
</tr>
<tr>
<td>IAM ロール（EC2・CodeBuild・CodeDeploy・CodePipeline 用）</td>
<td>—</td>
</tr>
</tbody>
</table>
<p><!-- ![CloudFormationスタック作成完了とリソース一覧](images/cloudformation-stack-complete.jpg) --></p>
<hr>
<h2><span id="toc7">③ Outputs を確認する</span></h2>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-cpapp-stack ^
  --query "Stacks[0].Outputs" ^
  --output table ^
  --region ap-northeast-1</code></pre>
<p><code>CodeCommitCloneUrlHttp</code> と <code>ALBEndpoint</code> の値を控えておきます。</p>
<hr>
<h2><span id="toc8">④ git-remote-codecommit をインストールする</span></h2>
<p>CodeCommit への push には <strong>git-remote-codecommit</strong> を使います。AWS CLI の認証情報をそのまま使えるため、Git 専用の認証情報を別途作成する必要がありません：</p>
<pre><code class="language-cmd">pip install git-remote-codecommit</code></pre>
<p>インストール後、<code>codecommit::</code> プレフィックスの URL で clone・push が可能になります。</p>
<hr>
<h2><span id="toc9">⑤ ソースコードを CodeCommit に push する</span></h2>
<h3><span id="toc10">⑤-1 CodeCommit リポジトリを clone する</span></h3>
<pre><code class="language-cmd">git clone codecommit::ap-northeast-1://my-cpapp %TEMP%\my-cpapp</code></pre>
<p><code>codecommit::</code> プレフィックスを使うことで、AWS CLI の認証情報が自動的に使われます（認証プロンプトは出ません）。</p>
<h3><span id="toc11">⑤-2 ソースコードをコピーして push する</span></h3>
<pre><code class="language-cmd">xcopy ec2-codepipeline\* %TEMP%\my-cpapp\ /E /I /H /Y
cd %TEMP%\my-cpapp

git add .
git commit -m "initial commit"
git branch -M main
git push origin main</code></pre>
<p>push が完了すると <strong>CodePipeline が自動的に起動</strong>します。</p>
<hr>
<h2><span id="toc12">⑥ CodePipeline の動作を確認する</span></h2>
<p>AWS コンソール → <strong>CodePipeline</strong> → <code>my-cp-pipeline</code></p>
<p>3 つのステージが順番に実行されます：</p>
<table>
<thead>
<tr>
<th>ステージ</th>
<th>処理内容</th>
<th>目安時間</th>
</tr>
</thead>
<tbody>
<tr>
<td>Source</td>
<td>CodeCommit からソース取得</td>
<td>数秒</td>
</tr>
<tr>
<td>Build</td>
<td>CodeBuild が <code>buildspec.yml</code> を実行（common-lib publish → WAR ビルド）</td>
<td>5〜8 分</td>
</tr>
<tr>
<td>Deploy</td>
<td>CodeDeploy が EC2 に配備（stop → install → start → validate）</td>
<td>2〜3 分</td>
</tr>
</tbody>
</table>
<p><strong>合計：約 8〜10 分</strong></p>
<p><!-- ![CodePipeline 3ステージ実行中の画面](images/codepipeline-stages.jpg) --></p>
<hr>
<h2><span id="toc13">⑦ CodeBuild のログを確認する</span></h2>
<p>AWS コンソール → <strong>CodeBuild</strong> → <code>my-cpapp-build</code> → 「ビルド履歴」タブ</p>
<p>ビルド実行をクリックするとインラインログが確認できます。以下が表示されれば正常です：</p>
<pre><code class="language-plaintext">=== CodeArtifact 認証トークン取得 ===
CodeArtifact URL = https://my-domain-XXXX.d.codeartifact.ap-northeast-1.amazonaws.com/maven/my-libs/
Maven settings.xml 生成完了
=== common-lib を CodeArtifact に publish ===
[INFO] BUILD SUCCESS
=== webapp WAR をビルド ===
[INFO] BUILD SUCCESS
=== デプロイパッケージを準備 ===
ビルド完了</code></pre>
<p>CodeArtifact の認証トークンは 12 時間有効な一時トークンです。有効期限が切れても次のビルド時に自動取得されるため、管理の手間がありません。</p>
<hr>
<h2><span id="toc14">⑧ CodeDeploy の状況を確認する</span></h2>
<p>AWS コンソール → <strong>CodeDeploy</strong> → アプリケーション → <code>my-cpapp</code> → デプロイグループ → 最新のデプロイメント</p>
<p>各フックスクリプト（stop_server → install → start_server → validate_service）の実行結果が確認できます。デプロイが失敗した場合はここでエラー詳細を確認します。</p>
<hr>
<h2><span id="toc15">⑨ アプリの動作確認をする</span></h2>
<p>パイプラインが成功したら ALB 経由でアクセスします：</p>
<pre><code class="language-cmd">curl http://&lt;ALBEndpoint の値&gt;/api/health
rem → {"status":"ok","message":null,"data":"OK"}

curl http://&lt;ALBEndpoint の値&gt;/api/items
rem → {"status":"ok","message":null,"data":[]}</code></pre>
<p>ブラウザで <code>ALBEndpoint</code> にアクセスするとアイテム管理 UI が表示されます。</p>
<p><!-- ![アプリ初期画面のブラウザ表示](images/app-initial-screen.jpg) --></p>
<hr>
<h2><span id="toc16">⑩ CI/CD サイクルを体験する</span></h2>
<p>CodeCommit にコードを push するだけでパイプラインが自動実行される CI/CD を体験します：</p>
<pre><code class="language-cmd">cd %TEMP%\my-cpapp</code></pre>
<p><code>app\src\main\resources\templates\index.html</code> を開いてタイトルを変更します：</p>
<pre><code class="language-html">&lt;!-- 変更後 --&gt;
&lt;h1&gt;Spring Boot + RDS Item Manager (EC2 v2) &lt;span class="badge"&gt;CodePipeline&lt;/span&gt;&lt;/h1&gt;</code></pre>
<pre><code class="language-cmd">git add app\src\main\resources\templates\index.html
git commit -m "feat: update title to EC2 v2"
git push origin main</code></pre>
<p>CodePipeline コンソール（<code>my-cp-pipeline</code>）で全ステージが成功になるまで待ちます（約 8〜10 分）。ALB にアクセスしてタイトルが変わっていることを確認します。</p>
<hr>
<h2><span id="toc17">⑪ CodeArtifact のパッケージを確認する</span></h2>
<p>AWS コンソール → <strong>CodeArtifact</strong> → ドメイン <code>my-domain</code> → リポジトリ <code>my-libs</code> → パッケージ一覧</p>
<p><code>com.example:common-utils:1.0.0</code> が登録されていることを確認します。CLI でも確認できます：</p>
<pre><code class="language-cmd">aws codeartifact list-packages ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --region ap-northeast-1</code></pre>
<p>また、Maven Central のプロキシとして機能しているため、<code>org.springframework.boot</code> なども一覧に表示されます。これらは外部から初回取得時にキャッシュされたものです。</p>
<hr>
<h2><span id="toc18">⑫ SSM Session Manager で EC2 に接続する（オプション）</span></h2>
<p>キーペアなしで EC2 内部を確認できます：</p>
<pre><code class="language-cmd">aws ssm start-session ^
  --target i-xxxxxxxxxxxxxxxxx ^
  --region ap-northeast-1</code></pre>
<pre><code class="language-bash"># Tomcat のステータス確認
sudo systemctl status tomcat

# CodeDeploy エージェントのログ確認
sudo cat /var/log/aws/codedeploy-agent/codedeploy-agent.log

# SSM から取得した DB 接続情報の確認
sudo cat /opt/tomcat/current/bin/setenv.sh

# Tomcat ログの確認
sudo journalctl -u tomcat -n 50</code></pre>
<hr>
<h2><span id="toc19">⑬ リソースを削除する</span></h2>
<p>CodeArtifact にパッケージが存在するとドメインが削除できないため、先にパッケージを手動削除します。</p>
<p><strong>① CodeArtifact のパッケージを削除する</strong></p>
<pre><code class="language-cmd">aws codeartifact delete-package-versions ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --format maven ^
  --namespace com.example ^
  --package common-utils ^
  --versions 1.0.0 ^
  --region ap-northeast-1

aws codeartifact delete-package ^
  --domain my-domain ^
  --domain-owner 123456789012 ^
  --repository my-libs ^
  --format maven ^
  --namespace com.example ^
  --package common-utils ^
  --region ap-northeast-1</code></pre>
<p><strong>② S3 バケットを空にする</strong></p>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-cpapp-stack ^
  --query "Stacks[0].Outputs[?OutputKey=='ArtifactBucketName'].OutputValue" ^
  --output text ^
  --region ap-northeast-1

aws s3 rm s3://&lt;ArtifactBucketName の値&gt; --recursive</code></pre>
<p><strong>③ CloudFormation スタックを削除する</strong></p>
<pre><code class="language-cmd">aws cloudformation delete-stack ^
  --stack-name my-cpapp-stack ^
  --region ap-northeast-1

aws cloudformation wait stack-delete-complete ^
  --stack-name my-cpapp-stack ^
  --region ap-northeast-1

echo 削除完了</code></pre>
<p><strong>④ ローカルの clone ディレクトリを削除する</strong></p>
<pre><code class="language-cmd">rmdir /S /Q %TEMP%\my-cpapp</code></pre>
<hr>
<h2><span id="toc20">まとめ：学んだ概念</span></h2>
<table>
<thead>
<tr>
<th>概念</th>
<th>ポイント</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>CodeCommit</strong></td>
<td>Git リポジトリを AWS 内でフルマネージドに管理。<code>git-remote-codecommit</code> で AWS CLI 認証のまま push できる</td>
</tr>
<tr>
<td><strong>CodeBuild</strong></td>
<td><code>buildspec.yml</code> でビルド手順をコード化。CodeArtifact の認証トークン取得→ publish → WAR ビルドまで自動化</td>
</tr>
<tr>
<td><strong>CodeDeploy</strong></td>
<td>EC2 への WAR 配置・サービス再起動・ヘルスチェックを自動化。<code>appspec.yml</code> でフックスクリプトを定義</td>
</tr>
<tr>
<td><strong>CodePipeline</strong></td>
<td>Source → Build → Deploy のステージを自動で連結する CI/CD オーケストレーター</td>
</tr>
<tr>
<td><strong>CodeArtifact</strong></td>
<td>Maven ライブラリを AWS 内で管理。Maven Central のプロキシとしても機能し、外部依存関係もキャッシュ</td>
</tr>
<tr>
<td><strong>buildspec.yml</strong></td>
<td>CodeBuild が実行するビルドステップをコードで定義するファイル</td>
</tr>
<tr>
<td><strong>git-remote-codecommit</strong></td>
<td>AWS CLI 認証情報を使って CodeCommit に push できるツール（Git 専用認証情報不要）</td>
</tr>
<tr>
<td><strong>SSM Parameter Store</strong></td>
<td>DB パスワードをインスタンスに安全に渡す仕組み</td>
</tr>
</tbody>
</table>
<p>GitHub Actions を使った<a href="https://caymezon.com/aws-handson-ec2-github-actions/">前のハンズオン</a>と比較すると、CodePipeline は <strong>すべてが AWS 内で完結</strong>する一方、GitHub Actions は <strong>Git リポジトリと AWS の柔軟な組み合わせ</strong>が強みです。どちらを使うかはチームの方針や既存インフラに合わせて選択しましょう。</p>
<p>次のステップとして、<a href="https://caymezon.com/aws-handson-cdk-ecs-webapp/">CDK + ECS Fargate ハンズオン</a>で EC2 からコンテナ化への移行も体験してみましょう。</p><p>The post <a href="https://caymezon.com/aws-handson-ec2-codepipeline/">EC2 + CodePipeline（Code 3兄弟）で WebアプリをCI/CDデプロイする【完全 AWS CI/CD 体験】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://caymezon.com/aws-handson-ec2-codepipeline/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>EC2 + GitHub Actions で WebアプリをCI/CDデプロイする【GitHub Packages + CodeDeploy 体験】</title>
		<link>https://caymezon.com/aws-handson-ec2-github-actions/</link>
					<comments>https://caymezon.com/aws-handson-ec2-github-actions/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Sat, 09 May 2026 04:16:05 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></category>
		<category><![CDATA[ALB]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[CI/CD]]></category>
		<category><![CDATA[CloudFormation]]></category>
		<category><![CDATA[CodeDeploy]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[GitHub Actions]]></category>
		<category><![CDATA[GitHub Packages]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OIDC]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[SSM Parameter Store]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20419</guid>

					<description><![CDATA[<p>目次 はじめにキーワード解説① 全体構成を理解する② OIDC 認証と IAM ロールを設定する②-1 OIDC プロバイダーを登録する（初回のみ）②-2 IAM ロールを作成する③ GitHub Variables を [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-ec2-github-actions/">EC2 + GitHub Actions で WebアプリをCI/CDデプロイする【GitHub Packages + CodeDeploy 体験】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">はじめに</a></li><li><a href="#toc2" tabindex="0">キーワード解説</a></li><li><a href="#toc3" tabindex="0">① 全体構成を理解する</a></li><li><a href="#toc4" tabindex="0">② OIDC 認証と IAM ロールを設定する</a><ol><li><a href="#toc5" tabindex="0">②-1 OIDC プロバイダーを登録する（初回のみ）</a></li><li><a href="#toc6" tabindex="0">②-2 IAM ロールを作成する</a></li></ol></li><li><a href="#toc7" tabindex="0">③ GitHub Variables を設定する</a></li><li><a href="#toc8" tabindex="0">④ CloudFormation スタックを作成する</a></li><li><a href="#toc9" tabindex="0">⑤ スタックの Outputs を確認する</a></li><li><a href="#toc10" tabindex="0">⑥ common-lib を GitHub Packages に publish する</a></li><li><a href="#toc11" tabindex="0">⑦ アプリを初回デプロイする</a></li><li><a href="#toc12" tabindex="0">⑧ GitHub Actions の進行を確認する</a></li><li><a href="#toc13" tabindex="0">⑨ ブラウザで動作確認する</a></li><li><a href="#toc14" tabindex="0">⑩ CI/CD サイクルを体験する</a></li><li><a href="#toc15" tabindex="0">⑪ SSM Session Manager で EC2 に接続する（オプション）</a></li><li><a href="#toc16" tabindex="0">⑫ リソースを削除する</a></li><li><a href="#toc17" tabindex="0">まとめ：学んだ概念</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「インフラは AWS でいいけど、デプロイは GitHub Actions でやりたい」——クラウドと Git を組み合わせたハイブリッドな CI/CD 構成は、多くの現場で採用されています。このハンズオンでは、<strong>EC2（Tomcat）への自動デプロイを GitHub Actions + AWS CodeDeploy で実現</strong>します。</p>
<p>さらに実務でよく見かける「<strong>社内共通ライブラリを GitHub Packages で管理・共有する</strong>」仕組みも体験できます。Spring Boot WAR をビルドする際に共通ライブラリを GitHub Packages からフェッチし、CodeDeploy で EC2 にデプロイするまでの一連のフローです。</p>
<pre><code class="language-plaintext">[GitHub リポジトリ]
  ├── common-lib/ → push → GitHub Actions → GitHub Packages に publish
  └── app/        → push → GitHub Actions
                               ├── GitHub Packages から common-utils を取得
                               ├── mvn package → webapp.war
                               ├── zip → S3 にアップロード
                               └── CodeDeploy を呼び出す
                                        ↓
                          [EC2: Tomcat + Spring Boot WAR]  my-ec2app
                                        ↓
                          [ALB: my-ec2app-alb] ← インターネット
                                        ↓
                          [RDS MySQL: my-ec2app-rds]</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li>GitHub Packages を使った共通ライブラリの管理・共有</li>
<li>GitHub Actions（OIDC 認証）で AWS にキーレスアクセス</li>
<li>CodeDeploy + appspec.yml を使った EC2 へのデプロイ自動化</li>
<li>SSM Parameter Store でデータベースパスワードを安全に管理</li>
<li>CloudFormation によるインフラ一括構築（VPC / EC2 / ALB / RDS / CodeDeploy）</li>
</ul>
<hr>
<blockquote>
<p>コード詳細は <a href="https://github.com/caymezon/aws-handson/tree/main/ec2-github-actions">GitHub</a> を参照してください。</p>
</blockquote>
<hr>
<p><!-- ![GitHub ActionsのCI/CDパイプライン完了とブラウザ確認画面](images/github-actions-deploy-complete.jpg) --></p>
<p><!-- <a rel="nofollow" href="//af.moshimo.com/af/c/click?a_id=1384942&p_id=170&pc_id=185&pl_id=4062&url=https%3A%2F%2Fwww.amazon.co.jp%2Fs%3Fk%3D%25E6%259C%25AC%2BAWS%2B%25E9%2596%258B%25E7%2599%25BA%26__mk_ja_JP%3D%25E3%2582%25AB%25E3%2582%25BF%25E3%2582%25AB%25E3%2583%258A%26crid%3D1DE63UBHFOR4K%26sprefix%3D%25E6%259C%25AC%2Baws%2B%25E9%2596%258B%25E7%2599%25BA%252Caps%252C167%26ref%3Dnb_sb_noss" referrerpolicy="no-referrer-when-downgrade" attributionsrc>Amazon検索[本 AWS 開発]</a><img decoding="async" src="//i.moshimo.com/af/i/impression?a_id=1384942&p_id=170&pc_id=185&pl_id=4062" width="1" height="1" style="border:none;" alt="" loading="lazy"> --></p>
<p><!-- <!-- START MoshimoAffiliateEasyLink --><script type="text/javascript">(function(b,c,f,g,a,d,e){b.MoshimoAffiliateObject=a;b[a]=b[a]||function(){arguments.currentScript=c.currentScript||c.scripts[c.scripts.length-2];(b[a].q=b[a].q||[]).push(arguments)};c.getElementById(a)||(d=c.createElement(f),d.src=g,d.id=a,e=c.getElementsByTagName("body")[0],e.appendChild(d))})(window,document,"script","//dn.msmstatic.com/site/cardlink/bundle.js?20220329","msmaflink");msmaflink({"n":"AWSの基本・仕組み・重要用語が全部わかる教科書 (見るだけ図解)","b":"SBクリエイティブ","t":"","d":"https:\/\/m.media-amazon.com","c_p":"\/images\/I","p":["\/51DEDQXj6oL._SL500_.jpg","\/41F589smNwL._SL500_.jpg","\/41R6f9yyCWL._SL500_.jpg","\/41HqWQ9BvmL._SL500_.jpg","\/41p8p0ZU79L._SL500_.jpg","\/41qLC-fndBL._SL500_.jpg","\/41fcLv9VT5L._SL500_.jpg","\/51lRvCsvHqL._SL500_.jpg"],"u":{"u":"https:\/\/www.amazon.co.jp\/dp\/4815607850","t":"amazon","r_v":""},"v":"2.1","b_l":[{"id":1,"u_tx":"Amazonで見る","u_bc":"#f79256","u_url":"https:\/\/www.amazon.co.jp\/dp\/4815607850","a_id":1384942,"p_id":170,"pl_id":27060,"pc_id":185,"s_n":"amazon","u_so":1},{"id":2,"u_tx":"楽天市場で見る","u_bc":"#f76956","u_url":"https:\/\/search.rakuten.co.jp\/search\/mall\/AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8%20(%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3)\/","a_id":1384917,"p_id":54,"pl_id":27059,"pc_id":54,"s_n":"rakuten","u_so":2},{"id":3,"u_tx":"Yahoo!ショッピングで見る","u_bc":"#66a7ff","u_url":"https:\/\/shopping.yahoo.co.jp\/search?first=1\u0026p=AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8%20(%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3)","a_id":1466950,"p_id":1225,"pl_id":27061,"pc_id":1925,"s_n":"yahoo","u_so":3}],"eid":"eaCUB","s":"s"});</script></p>
<div id="msmaflink-eaCUB">リンク</div>
<p><!-- MoshimoAffiliateEasyLink END --> --></p>
<h2><span id="toc2">キーワード解説</span></h2>
<table>
<thead>
<tr>
<th>用語</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>GitHub Packages</strong></td>
<td>GitHub リポジトリ内で Maven/npm などのパッケージを管理・共有するレジストリ。社内共通ライブラリの配布に使える</td>
</tr>
<tr>
<td><strong>GitHub Actions OIDC</strong></td>
<td>アクセスキーをリポジトリに保存せず、JWT トークンで AWS を操作するキーレス認証方式</td>
</tr>
<tr>
<td><strong>CodeDeploy</strong></td>
<td>EC2 への WAR 配置・サービス停止/起動・ヘルスチェックを自動化する AWS のデプロイサービス</td>
</tr>
<tr>
<td><strong>appspec.yml</strong></td>
<td>CodeDeploy がデプロイ時に実行するファイル配置先とフックスクリプト（BeforeInstall / AfterInstall / ValidateService）を定義するファイル</td>
</tr>
<tr>
<td><strong>SSM Parameter Store</strong></td>
<td>DB パスワードなどの設定値を暗号化して管理し、EC2 から安全に取得できる AWS のサービス</td>
</tr>
<tr>
<td><strong>CloudFormation</strong></td>
<td>AWS リソースをコード（YAML/JSON）で定義・一括管理する IaC サービス</td>
</tr>
<tr>
<td><strong>ALB（Application Load Balancer）</strong></td>
<td>HTTP/HTTPS をリスンして EC2 にリクエストを振り分けるロードバランサー</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc3">① 全体構成を理解する</span></h2>
<p>このハンズオンの主役は 2 つのワークフローです。</p>
<p><strong>①-1 common-lib のパブリッシュ（<code>ec2-publish-lib.yml</code>）</strong></p>
<p><code>common-lib/</code> が変更されると起動し、Maven ライブラリを GitHub Packages に publish します。<code>actions/setup-java</code> が <code>settings.xml</code> を自動生成するため、認証設定は不要です。</p>
<p><strong>①-2 アプリのデプロイ（<code>ec2-app-deploy.yml</code>）</strong></p>
<p><code>app/</code> が変更されると起動します。処理の流れは次の通りです：</p>
<pre><code class="language-plaintext">① OIDC で AWS に認証
② GitHub Packages から common-utils を取得しながら mvn package で WAR をビルド
③ zip 化して S3 にアップロード（webapp.war + appspec.yml + scripts/）
④ CodeDeploy でローリングデプロイ（〜1〜2 分）</code></pre>
<p><strong>デプロイパッケージの構造：</strong></p>
<pre><code class="language-plaintext">deploy.zip
├── webapp.war         ← Tomcat の webapps/ に配置
├── appspec.yml        ← CodeDeploy の設定
└── scripts/
    ├── stop_server.sh      ← Tomcat を停止・古い WAR を削除
    ├── start_server.sh     ← SSM から DB 情報を取得・Tomcat 起動
    └── validate_service.sh ← /api/health を最大 60 秒リトライ確認</code></pre>
<hr>
<h2><span id="toc4">② OIDC 認証と IAM ロールを設定する</span></h2>
<p>GitHub Actions が AWS に安全にアクセスするための <strong>OIDC（OpenID Connect）認証</strong> を設定します。アクセスキーをリポジトリに保存せずに AWS を操作できる現代的な方式です。</p>
<h3><span id="toc5">②-1 OIDC プロバイダーを登録する（初回のみ）</span></h3>
<p>AWS コンソール → <strong>IAM</strong> → 「IDプロバイダー」→「プロバイダーを追加」</p>
<table>
<thead>
<tr>
<th>項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>プロバイダータイプ</td>
<td>OpenID Connect</td>
</tr>
<tr>
<td>プロバイダー URL</td>
<td><code>https://token.actions.githubusercontent.com</code></td>
</tr>
<tr>
<td>対象者（Audience）</td>
<td><code>sts.amazonaws.com</code></td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>ECS ハンズオン（cdk-ecs-webapp）完了済みの場合</strong>はスキップ可。</p>
</blockquote>
<h3><span id="toc6">②-2 IAM ロールを作成する</span></h3>
<p>AWS CloudShell で以下を実行します（<code>GITHUB_OWNER</code> と <code>REPO</code> は自分のリポジトリに合わせて変更）：</p>
<pre><code class="language-bash">ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
GITHUB_OWNER="your-github-username"   # ← 自分の GitHub ユーザー名
REPO="your-github-repo"               # ← 自分の GitHub リポジトリ名
EMPLOYEE_ID="my"                      # ← 好きなプレフィックス（例: 123456）
ROLE_NAME="${EMPLOYEE_ID}-github-actions-role"

cat &gt; /tmp/trust-policy.json &lt;&lt; EOF
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
      },
      "StringLike": {
        "token.actions.githubusercontent.com:sub": "repo:${GITHUB_OWNER}/${REPO}:ref:refs/heads/main"
      }
    }
  }]
}
EOF

aws iam create-role \
  --role-name $ROLE_NAME \
  --assume-role-policy-document file:///tmp/trust-policy.json

# 権限ポリシーを付与（S3 + CodeDeploy）
cat &gt; /tmp/permissions.json &lt;&lt; EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject", "s3:GetObject"],
      "Resource": "arn:aws:s3:::${EMPLOYEE_ID}-ec2app-deploy-*/*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "codedeploy:CreateDeployment",
        "codedeploy:GetDeployment",
        "codedeploy:GetDeploymentConfig",
        "codedeploy:RegisterApplicationRevision"
      ],
      "Resource": "*"
    }
  ]
}
EOF

aws iam put-role-policy \
  --role-name $ROLE_NAME \
  --policy-name "${ROLE_NAME}-policy" \
  --policy-document file:///tmp/permissions.json

# ロール ARN を表示
aws iam get-role --role-name $ROLE_NAME --query Role.Arn --output text</code></pre>
<p>出力された <strong>ロール ARN</strong>（<code>arn:aws:iam::...</code>）をコピーしておきます。</p>
<hr>
<h2><span id="toc7">③ GitHub Variables を設定する</span></h2>
<p>GitHub リポジトリ → <strong>Settings</strong> → <strong>Secrets and variables</strong> → <strong>Actions</strong> → <strong>「Variables」タブ</strong></p>
<p>「New repository variable」で以下を追加します：</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>例</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>EMPLOYEE_ID</code></td>
<td><code>my</code></td>
<td>リソース名プレフィックス</td>
</tr>
<tr>
<td><code>AWS_ROLE_ARN</code></td>
<td><code>arn:aws:iam::...</code></td>
<td>②-2 で表示されたロール ARN</td>
</tr>
<tr>
<td><code>AWS_ACCOUNT_ID</code></td>
<td><code>123456789012</code></td>
<td>AWS アカウント ID（S3 バケット名に使用）</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>Variables vs Secrets</strong>：ARN や ID は機密情報ではないため Variables に保存します（パスワード類は Secrets を使う）。</p>
</blockquote>
<hr>
<h2><span id="toc8">④ CloudFormation スタックを作成する</span></h2>
<p>自分の IP アドレスを確認し（<code>curl https://checkip.amazonaws.com</code>）、CloudFormation でインフラを一括作成します：</p>
<pre><code class="language-cmd">aws cloudformation deploy ^
  --template-file ec2-github-actions/infra/template.yaml ^
  --stack-name my-ec2app ^
  --parameter-overrides EmployeeId=my DBPassword=Handson1234! MyIP=123.456.78.901/32 ^
  --capabilities CAPABILITY_NAMED_IAM ^
  --region ap-northeast-1</code></pre>
<blockquote>
<p><strong>所要時間：約 10〜15 分</strong>（RDS の作成に時間がかかります）</p>
</blockquote>
<p>CloudFormation スタックが作成するリソース：</p>
<table>
<thead>
<tr>
<th>リソース</th>
<th>名前</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC / サブネット / IGW</td>
<td><code>my-ec2app-vpc</code></td>
</tr>
<tr>
<td>EC2（Amazon Linux 2023 + Tomcat 10.1）</td>
<td><code>my-ec2app</code></td>
</tr>
<tr>
<td>ALB</td>
<td><code>my-ec2app-alb</code></td>
</tr>
<tr>
<td>RDS MySQL 8.0</td>
<td><code>my-ec2app-rds</code></td>
</tr>
<tr>
<td>S3（デプロイアーティファクト保管）</td>
<td><code>my-ec2app-deploy-{アカウントID}</code></td>
</tr>
<tr>
<td>CodeDeploy Application + Deployment Group</td>
<td><code>my-ec2app</code></td>
</tr>
<tr>
<td>SSM Parameter Store（DB 接続情報）</td>
<td><code>/my/ec2app/db-host</code>, <code>/my/ec2app/db-password</code></td>
</tr>
</tbody>
</table>
<p><!-- ![CloudFormationスタック作成完了の画面](images/cloudformation-stack-complete.jpg) --></p>
<hr>
<h2><span id="toc9">⑤ スタックの Outputs を確認する</span></h2>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2app ^
  --region ap-northeast-1 ^
  --query "Stacks[0].Outputs" ^
  --output table</code></pre>
<table>
<thead>
<tr>
<th>キー</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ALBEndpoint</code></td>
<td>アプリ URL（後で使用）</td>
</tr>
<tr>
<td><code>DeploymentBucketName</code></td>
<td>S3 バケット名</td>
</tr>
<tr>
<td><code>CodeDeployApplicationName</code></td>
<td>CodeDeploy アプリ名</td>
</tr>
<tr>
<td><code>EC2InstanceId</code></td>
<td>EC2 インスタンス ID（SSM 接続に使用）</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc10">⑥ common-lib を GitHub Packages に publish する</span></h2>
<p><code>common-lib/pom.xml</code> と <code>app/pom.xml</code> にある GitHub ユーザー名・リポジトリ名のプレースホルダーを自分のものに変更してから push します：</p>
<pre><code class="language-xml">&lt;!-- common-lib/pom.xml と app/pom.xml の両方を変更 --&gt;
&lt;url&gt;https://maven.pkg.github.com/your-github-username/your-github-repo&lt;/url&gt;</code></pre>
<p>変更を push すると <strong><code>Publish common-utils to GitHub Packages</code></strong> ワークフローが自動起動します：</p>
<pre><code class="language-cmd">cd C:\my-aws\aws-learning-projects
git add ec2-github-actions/common-lib/ ec2-github-actions/app/pom.xml
git commit -m "feat: configure GitHub Packages URL for ec2-github-actions"
git push</code></pre>
<p>GitHub リポジトリ → <strong>Actions タブ</strong> → <code>Publish common-utils to GitHub Packages</code> の実行を確認します。完了後、<strong>Packages タブ</strong>に <code>common-utils 1.0.0</code> が表示されます。</p>
<blockquote>
<p><strong><code>ResponseWrapper</code> クラスとは</strong>：このハンズオンの共通ライブラリは API レスポンスを <code>{&quot;status&quot;:&quot;ok&quot;,&quot;data&quot;:{...}}</code> の統一形式にラップするユーティリティです。チーム開発でレスポンス形式を統一する際によく使われるパターンです。</p>
</blockquote>
<hr>
<h2><span id="toc11">⑦ アプリを初回デプロイする</span></h2>
<p><code>app/</code> の変更を push して <strong><code>Deploy App to EC2</code></strong> ワークフローを起動します：</p>
<pre><code class="language-cmd">cd C:\my-aws\aws-learning-projects
git add ec2-github-actions/app/
git commit -m "feat: initial deploy via GitHub Actions (EC2)"
git push</code></pre>
<blockquote>
<p><strong><code>nothing to commit</code> と表示された場合</strong>：<code>index.html</code> に空白行を追加して変更を作ります：</p>
<pre><code class="language-cmd">echo. &gt;&gt; ec2-github-actions\app\src\main\resources\templates\index.html
git add ec2-github-actions/app/src/main/resources/templates/index.html
git commit -m "chore: trigger initial deploy"
git push</code></pre>
</blockquote>
<hr>
<h2><span id="toc12">⑧ GitHub Actions の進行を確認する</span></h2>
<p>GitHub → <strong>Actions タブ</strong> → <code>Deploy App to EC2</code> で各ステップの実行状況を確認します：</p>
<table>
<thead>
<tr>
<th>ステップ</th>
<th>内容</th>
<th>時間目安</th>
</tr>
</thead>
<tbody>
<tr>
<td>Checkout</td>
<td>コード取得</td>
<td>〜10秒</td>
</tr>
<tr>
<td>Configure AWS credentials</td>
<td>OIDC 認証（アクセスキー不要）</td>
<td>〜10秒</td>
</tr>
<tr>
<td>Set up Java</td>
<td>JDK 17 + settings.xml 生成</td>
<td>〜30秒</td>
</tr>
<tr>
<td>Build WAR</td>
<td>GitHub Packages から common-utils 取得 + <code>mvn package</code></td>
<td>〜1〜2分</td>
</tr>
<tr>
<td>Package and upload to S3</td>
<td>zip 化 → S3 へアップロード</td>
<td>〜10秒</td>
</tr>
<tr>
<td>Deploy via CodeDeploy</td>
<td>EC2 にデプロイ + 完了待ち</td>
<td>〜1〜2分</td>
</tr>
</tbody>
</table>
<p><strong>合計：約 3〜5 分</strong></p>
<p>ポイントは <strong>「Set up Java」ステップ</strong>です。<code>actions/setup-java</code> に <code>server-id: github</code> を指定するだけで、GitHub Packages の認証情報を含む <code>settings.xml</code> が自動生成されます。Maven のパスワード設定を手書きする必要はありません。</p>
<hr>
<h2><span id="toc13">⑨ ブラウザで動作確認する</span></h2>
<p><code>ALBEndpoint</code> の URL にアクセスすると「Spring Boot + RDS Item Manager (EC2)」が表示されます。</p>
<p><code>/api/health</code> にアクセスして以下が返ることも確認します：</p>
<pre><code class="language-json">{"status":"ok","message":null,"data":"OK"}</code></pre>
<p>このレスポンス形式こそが <strong><code>common-utils</code> の <code>ResponseWrapper</code></strong> が GitHub Packages 経由で取得・ビルドされた証拠です。</p>
<p><!-- ![アプリの初期画面とAPIヘルスチェック結果](images/app-initial-screen.jpg) --></p>
<hr>
<h2><span id="toc14">⑩ CI/CD サイクルを体験する</span></h2>
<p><code>index.html</code> のタイトルを変更して push すると、約 3〜5 分でブラウザに反映されます：</p>
<pre><code class="language-html">&lt;!-- 変更後 --&gt;
&lt;h1&gt;Spring Boot + RDS Item Manager (EC2 v2) &lt;span class="badge"&gt;GitHub Actions&lt;/span&gt;&lt;/h1&gt;</code></pre>
<pre><code class="language-cmd">git add ec2-github-actions/app/src/main/resources/templates/index.html
git commit -m "feat: update title to EC2 v2"
git push</code></pre>
<p>これが CI/CD の醍醐味です。<strong>コードを push するだけで自動的にデプロイが完了</strong>します。</p>
<hr>
<h2><span id="toc15">⑪ SSM Session Manager で EC2 に接続する（オプション）</span></h2>
<p>キーペアなしで EC2 内部を確認できます：</p>
<pre><code class="language-cmd">aws ssm start-session ^
  --target i-xxxxxxxxxxxxxxxxx ^
  --region ap-northeast-1</code></pre>
<pre><code class="language-bash"># Tomcat のステータス確認
sudo systemctl status tomcat

# デプロイログの確認
sudo cat /var/log/aws/codedeploy-agent/codedeploy-agent.log

# SSM から取得した DB 接続情報の確認
sudo cat /opt/tomcat/current/bin/setenv.sh

# Tomcat ログの確認
sudo journalctl -u tomcat -n 50</code></pre>
<p><code>setenv.sh</code> を確認すると、SSM Parameter Store から取得した DB ホスト名とパスワードが環境変数としてセットされていることがわかります。パスワードをコードに書かずに安全に注入できています。</p>
<hr>
<h2><span id="toc16">⑫ リソースを削除する</span></h2>
<p><strong>① S3 バケットを空にする</strong>（デプロイアーティファクトが蓄積されているため先に削除）</p>
<pre><code class="language-cmd">aws s3 rm s3://my-ec2app-deploy-123456789012 --recursive</code></pre>
<p><strong>② CloudFormation スタックを削除する</strong></p>
<pre><code class="language-cmd">aws cloudformation delete-stack ^
  --stack-name my-ec2app ^
  --region ap-northeast-1

aws cloudformation wait stack-delete-complete ^
  --stack-name my-ec2app ^
  --region ap-northeast-1

echo スタック削除完了</code></pre>
<hr>
<h2><span id="toc17">まとめ：学んだ概念</span></h2>
<table>
<thead>
<tr>
<th>概念</th>
<th>ポイント</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>GitHub Packages</strong></td>
<td>Maven ライブラリを GitHub リポジトリ内で管理・共有する仕組み。社内共通ライブラリの配布に活用できる</td>
</tr>
<tr>
<td><strong>GitHub Actions OIDC</strong></td>
<td>アクセスキー不要で AWS に認証するキーレス方式。<code>aws-actions/configure-aws-credentials</code> で簡単に設定可</td>
</tr>
<tr>
<td><strong>CodeDeploy</strong></td>
<td>EC2 への WAR 配置・サービス再起動・ヘルスチェックを自動化するサービス</td>
</tr>
<tr>
<td><strong>appspec.yml</strong></td>
<td>CodeDeploy がデプロイ時に実行するファイル配置とフックスクリプトを定義するファイル</td>
</tr>
<tr>
<td><strong>SSM Parameter Store</strong></td>
<td>DB パスワードをインスタンスに安全に渡す仕組み。<code>start_server.sh</code> から取得して <code>setenv.sh</code> に書き込む</td>
</tr>
<tr>
<td><strong>CloudFormation</strong></td>
<td>VPC・EC2・RDS・ALB・CodeDeploy を 1 つの YAML テンプレートで一括構築</td>
</tr>
</tbody>
</table>
<p>GitHub Actions と AWS を組み合わせることで、<strong>Git push だけでインフラから独立してアプリをデプロイできる</strong>柔軟な CI/CD パイプラインを構築できます。次のステップとして、<a href="https://caymezon.com/aws-handson-ec2-codepipeline/">EC2 + CodePipeline ハンズオン</a>で完全 AWS ネイティブな CI/CD も体験してみましょう。</p><p>The post <a href="https://caymezon.com/aws-handson-ec2-github-actions/">EC2 + GitHub Actions で WebアプリをCI/CDデプロイする【GitHub Packages + CodeDeploy 体験】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://caymezon.com/aws-handson-ec2-github-actions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
