<?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>プライベートサブネット - CayTech Lab</title>
	<atom:link href="https://caymezon.com/tag/%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88/feed/" rel="self" type="application/rss+xml" />
	<link>https://caymezon.com</link>
	<description></description>
	<lastBuildDate>Sat, 04 Apr 2026 07:34:06 +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>プライベートサブネット - 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>AWSコンソールでVPC設計からAP+DB 2層構成を構築する手順【踏み台SSH / CloudFormation版との比較付き】</title>
		<link>https://caymezon.com/aws-handson-console-ec2-2tier/</link>
					<comments>https://caymezon.com/aws-handson-console-ec2-2tier/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Sat, 04 Apr 2026 07:34:06 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></category>
		<category><![CDATA[2層構成]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWSコンソール]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[MariaDB]]></category>
		<category><![CDATA[SG参照]]></category>
		<category><![CDATA[UserData]]></category>
		<category><![CDATA[VPC]]></category>
		<category><![CDATA[セキュリティグループ]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[パブリックサブネット]]></category>
		<category><![CDATA[プライベートサブネット]]></category>
		<category><![CDATA[初心者]]></category>
		<category><![CDATA[踏み台]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20325</guid>

					<description><![CDATA[<p>目次 はじめにキーワード解説前フェーズとの違い使用するAWSサービス構築するリソース一覧全体の作業順序【重要】⓪ 自分のIPアドレスを確認する① キーペアの作成② IAMロールの作成③ VPCの作成④ インターネットゲー [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-console-ec2-2tier/">AWSコンソールでVPC設計からAP+DB 2層構成を構築する手順【踏み台SSH / CloudFormation版との比較付き】</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></li><li><a href="#toc4" tabindex="0">使用するAWSサービス</a></li><li><a href="#toc5" tabindex="0">構築するリソース一覧</a></li><li><a href="#toc6" tabindex="0">全体の作業順序</a></li><li><a href="#toc7" tabindex="0">【重要】⓪ 自分のIPアドレスを確認する</a></li><li><a href="#toc8" tabindex="0">① キーペアの作成</a></li><li><a href="#toc9" tabindex="0">② IAMロールの作成</a></li><li><a href="#toc10" tabindex="0">③ VPCの作成</a></li><li><a href="#toc11" tabindex="0">④ インターネットゲートウェイの作成・アタッチ</a><ol><li><a href="#toc12" tabindex="0">4-1. インターネットゲートウェイを作成する</a></li><li><a href="#toc13" tabindex="0">4-2. VPCにアタッチする</a></li></ol></li><li><a href="#toc14" tabindex="0">⑤ サブネットの作成</a><ol><li><a href="#toc15" tabindex="0">5-1. パブリックサブネット</a></li><li><a href="#toc16" tabindex="0">5-2. プライベートサブネット</a></li><li><a href="#toc17" tabindex="0">5-3. パブリックサブネットのパブリックIP自動割り当てを有効化</a></li></ol></li><li><a href="#toc18" tabindex="0">⑥ ルートテーブルの設定</a><ol><li><a href="#toc19" tabindex="0">6-1. パブリックルートテーブルを作成する</a></li><li><a href="#toc20" tabindex="0">6-2. プライベートルートテーブルを作成する</a></li><li><a href="#toc21" tabindex="0">6-3. S3 VPC Gateway Endpointを作成する（重要）</a></li></ol></li><li><a href="#toc22" tabindex="0">⑦ セキュリティグループの作成</a><ol><li><a href="#toc23" tabindex="0">7-1. APサーバSGの作成</a></li><li><a href="#toc24" tabindex="0">7-2. DBサーバSGの作成</a></li></ol></li><li><a href="#toc25" tabindex="0">⑧ APサーバEC2の起動（パブリックサブネット）</a><ol><li><a href="#toc26" tabindex="0">8-1. 基本設定</a></li><li><a href="#toc27" tabindex="0">8-2. ネットワーク設定</a></li><li><a href="#toc28" tabindex="0">8-3. IAMロール・UserDataの設定</a></li></ol></li><li><a href="#toc29" tabindex="0">⑨ DBサーバEC2の起動（プライベートサブネット）</a><ol><li><a href="#toc30" tabindex="0">9-1. 基本設定</a></li><li><a href="#toc31" tabindex="0">9-2. ネットワーク設定</a></li><li><a href="#toc32" tabindex="0">9-3. IAMロール・UserDataの設定</a></li></ol></li><li><a href="#toc33" tabindex="0">⑩ 動作確認</a><ol><li><a href="#toc34" tabindex="0">10-1. APサーバのWeb確認</a></li><li><a href="#toc35" tabindex="0">10-2. APサーバへのSSH接続</a></li><li><a href="#toc36" tabindex="0">10-3. キーペアをAPサーバにコピーする（踏み台SSH準備）</a></li><li><a href="#toc37" tabindex="0">10-4. APサーバ経由でDBサーバにSSH接続（踏み台接続）</a></li><li><a href="#toc38" tabindex="0">10-5. APサーバからMySQLに接続（AP→DB通信確認）</a></li></ol></li><li><a href="#toc39" tabindex="0">⑪ リソースの削除</a><ol><li><a href="#toc40" tabindex="0">削除順序</a></li></ol></li><li><a href="#toc41" tabindex="0">CloudFormation版との比較</a></li><li><a href="#toc42" tabindex="0">トラブルシューティング</a></li><li><a href="#toc43" tabindex="0">まとめ</a></li><li><a href="#toc44" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「APサーバはインターネットに公開しつつ、DBサーバはインターネットから完全に隔離したい」——これが実際のAWSシステム設計でよく使われる <strong>AP+DB 2層構成</strong> です。</p>
<p>この記事では、<strong>AWSコンソール（GUI）のみ</strong>を使って、カスタムVPCを設計し、パブリックサブネット（APサーバ）とプライベートサブネット（DBサーバ）に分離した2層アーキテクチャをゼロから手動構築するハンズオンを紹介します。</p>
<pre><code class="language-plaintext">インターネット
  ↓ HTTP(80) / SSH(22)  ← 自分のIPのみ
[インターネットゲートウェイ（my-igw）]
  ↓
[VPC: my-vpc（10.0.0.0/16）]
  │
  ├─ [パブリックサブネット: 10.0.1.0/24]
  │    └── APサーバEC2（my-ap-instance）
  │          ├── Apache（ポート80）   ← インターネットから直接アクセス可
  │          └── my-ap-sg
  │                ↓ SSH(22) / MySQL(3306) ← APサーバSGのみ許可（SG参照）
  └─ [プライベートサブネット: 10.0.2.0/24]
       └── DBサーバEC2（my-db-instance）
             ├── MariaDB（ポート3306）
             ├── パブリックIPなし       ← インターネットから隔離
             └── my-db-sg</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li>カスタムVPC・サブネット・インターネットゲートウェイ・ルートテーブルを一から設計・構築</li>
<li>パブリックサブネット（APサーバ）とプライベートサブネット（DBサーバ）の分離</li>
<li>DBサーバにパブリックIPを付与せずインターネットから隔離する設計</li>
<li>APサーバを踏み台（Bastion）としてDBサーバにSSH接続する方法</li>
<li>S3 VPC Gateway Endpointでプライベートサブネットからパッケージをインストールする方法</li>
</ul>
<p><strong>このハンズオンのポイント：</strong></p>
<p>Phase 1-3（MySQL）まではデフォルトVPCを使っていましたが、今回は<strong>カスタムVPCを一から設計</strong>します。実際のAWS本番環境に近いネットワーク設計を体験できます。</p>
<hr>
<blockquote>
<p><strong>この記事は <a href="https://caymezon.com/aws-handson-cloudformation-ec2-2tier/">CloudFormation版ハンズオン</a> の比較記事です。</strong><br />コンソール操作でVPCリソースの依存関係・設定手順を視覚的に学び、CloudFormationとの違いを比較したい方向けです。</p>
</blockquote>
<hr>
<p><!-- ![ハンズオン完成後の構成確認画面](images/ec2-2tier-top.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>VPC（Virtual Private Cloud）</strong></td>
<td>AWS上に作るプライベートなネットワーク空間。今回は <code>10.0.0.0/16</code> のCIDRで作成する</td>
</tr>
<tr>
<td><strong>パブリックサブネット</strong></td>
<td>インターネットゲートウェイへのルートを持つサブネット。APサーバを配置する</td>
</tr>
<tr>
<td><strong>プライベートサブネット</strong></td>
<td>インターネットへの経路を持たないサブネット。DBサーバを配置し外部から隔離する</td>
</tr>
<tr>
<td><strong>インターネットゲートウェイ（IGW）</strong></td>
<td>VPCとインターネットを接続する出入り口</td>
</tr>
<tr>
<td><strong>ルートテーブル</strong></td>
<td>サブネット内のEC2がパケットを送るときの「経路表」</td>
</tr>
<tr>
<td><strong>S3 VPC Gateway Endpoint</strong></td>
<td>プライベートサブネットからS3（パッケージリポジトリ）にアクセスするための無料エンドポイント</td>
</tr>
<tr>
<td><strong>踏み台（Bastion）</strong></td>
<td>プライベートサブネットのEC2にアクセスするための中継サーバ。今回はAPサーバが踏み台を兼ねる</td>
</tr>
<tr>
<td><strong>SG参照（SG-to-SG）</strong></td>
<td>セキュリティグループのルールで、アクセス元として別のSGを指定する設定</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc3">前フェーズとの違い</span></h2>
<table>
<thead>
<tr>
<th>比較項目</th>
<th>Phase 1-3（MySQL）</th>
<th>Phase 1-4（2層構成・今回）</th>
</tr>
</thead>
<tbody>
<tr>
<td>ネットワーク</td>
<td>デフォルトVPC</td>
<td><strong>カスタムVPC</strong></td>
</tr>
<tr>
<td>サブネット</td>
<td>デフォルトサブネット（パブリック）</td>
<td><strong>パブリック + プライベート</strong></td>
</tr>
<tr>
<td>DBのパブリックIP</td>
<td>あり</td>
<td><strong>なし（インターネット隔離）</strong></td>
</tr>
<tr>
<td>DBへのSSH</td>
<td>直接SSH可能</td>
<td><strong>APサーバ経由の踏み台接続</strong></td>
</tr>
<tr>
<td>リソース数</td>
<td>4〜5個</td>
<td><strong>12個以上（VPC関連が多数）</strong></td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc4">使用するAWSサービス</span></h2>
<table>
<thead>
<tr>
<th>サービス</th>
<th>役割</th>
<th>料金</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>VPC</strong></td>
<td>カスタムネットワーク空間</td>
<td>無料</td>
</tr>
<tr>
<td><strong>EC2 × 2台</strong></td>
<td>APサーバ（Apache） + DBサーバ（MariaDB）（各t2.micro）</td>
<td>月750時間まで無料枠あり（2台で消費が倍）</td>
</tr>
<tr>
<td><strong>セキュリティグループ × 2</strong></td>
<td>APサーバSG / DBサーバSGのアクセス制御</td>
<td>無料</td>
</tr>
<tr>
<td><strong>S3 VPC Gateway Endpoint</strong></td>
<td>プライベートサブネットからS3へのアクセス</td>
<td><strong>無料</strong></td>
</tr>
<tr>
<td><strong>IAM</strong></td>
<td>EC2へのSession Manager接続権限</td>
<td>無料</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>注意</strong>: EC2を2台同時に稼働させるため、無料枠の消費が2倍になります。ハンズオン後は必ず2台とも削除してください。</p>
</blockquote>
<hr>
<h2><span id="toc5">構築するリソース一覧</span></h2>
<table>
<thead>
<tr>
<th>カテゴリ</th>
<th>リソース</th>
<th>役割</th>
</tr>
</thead>
<tbody>
<tr>
<td>ネットワーク</td>
<td>VPC（<code>my-vpc</code>）</td>
<td>独自のネットワーク空間（10.0.0.0/16）</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>インターネットゲートウェイ（<code>my-igw</code>）</td>
<td>VPCとインターネットを接続</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>パブリックサブネット（<code>my-public-subnet</code>）</td>
<td>APサーバ用（インターネットアクセスあり）</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>プライベートサブネット（<code>my-private-subnet</code>）</td>
<td>DBサーバ用（インターネットアクセスなし）</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>パブリックルートテーブル（<code>my-public-rt</code>）</td>
<td>インターネットへの経路（→IGW）</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>プライベートルートテーブル（<code>my-private-rt</code>）</td>
<td>VPC内のみ（インターネット経路なし）</td>
</tr>
<tr>
<td>ネットワーク</td>
<td>S3 VPC Gateway Endpoint</td>
<td>プライベートサブネットからS3へのアクセス（無料）</td>
</tr>
<tr>
<td>セキュリティ</td>
<td>APサーバSG（<code>my-ap-sg</code>）</td>
<td>SSH(22)・HTTP(80)を自分のIPから許可</td>
</tr>
<tr>
<td>セキュリティ</td>
<td>DBサーバSG（<code>my-db-sg</code>）</td>
<td>SSH(22)・MySQL(3306)をAPサーバSGのみ許可</td>
</tr>
<tr>
<td>認証</td>
<td>キーペア（<code>my-ec2-2tier-key</code>）</td>
<td>SSH接続の認証鍵</td>
</tr>
<tr>
<td>認証</td>
<td>IAMロール（<code>my-ec2-2tier-role</code>）</td>
<td>EC2にSession Manager権限を付与</td>
</tr>
<tr>
<td>コンピュート</td>
<td>APサーバEC2（<code>my-ap-instance</code>）</td>
<td>Apacheを実行するWebサーバ（パブリックサブネット）</td>
</tr>
<tr>
<td>コンピュート</td>
<td>DBサーバEC2（<code>my-db-instance</code>）</td>
<td>MariaDBを実行するDBサーバ（プライベートサブネット）</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc6">全体の作業順序</span></h2>
<p>ネットワーク系リソースはEC2より先に作成する必要があります。</p>
<pre><code class="language-plaintext">⓪ 自分のIPアドレスを確認する
      ↓
① キーペアを作成する
      ↓
② IAMロールを作成する
      ↓
③ VPCを作成する
      ↓
④ インターネットゲートウェイを作成・アタッチする
      ↓
⑤ サブネットを作成する（パブリック・プライベート）
      ↓
⑥ ルートテーブルを設定する（S3 VPC Endpoint作成を含む）
      ↓
⑦ セキュリティグループを作成する（APサーバSG → DBサーバSGの順）
      ↓
⑧ APサーバEC2を起動する（パブリックサブネット）
      ↓
⑨ DBサーバEC2を起動する（プライベートサブネット）
      ↓
⑩ 動作確認
      ↓
⑪ リソースを削除する</code></pre>
<hr>
<h2><span id="toc7">【重要】⓪ 自分のIPアドレスを確認する</span></h2>
<pre><code class="language-cmd">curl https://checkip.amazonaws.com</code></pre>
<p>またはルーター管理画面（<code>http://192.168.0.1</code> など）の「WAN IPアドレス」で確認します。</p>
<p><strong>控えておく情報</strong>: 自分のIPアドレス（例: <code>203.0.113.1</code>）</p>
<hr>
<h2><span id="toc8">① キーペアの作成</span></h2>
<p>APサーバとDBサーバの両方で使用します。1つのキーペアを共用します。</p>
<p><strong>AWSコンソール → EC2 → キーペア → 「キーペアを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ec2-2tier-key</code></td>
</tr>
<tr>
<td>キーペアのタイプ</td>
<td><strong>RSA</strong></td>
</tr>
<tr>
<td>プライベートキーファイル形式</td>
<td><strong>.pem</strong></td>
</tr>
</tbody>
</table>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem</code></pre>
<hr>
<h2><span id="toc9">② IAMロールの作成</span></h2>
<p><strong>AWSコンソール → IAM → ロール → 「ロールを作成」</strong></p>
<table>
<thead>
<tr>
<th>ステップ</th>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>信頼されたエンティティタイプ</td>
<td><strong>AWSのサービス</strong></td>
</tr>
<tr>
<td>1</td>
<td>ユースケース</td>
<td><strong>EC2</strong></td>
</tr>
<tr>
<td>2</td>
<td>許可ポリシー</td>
<td><code>AmazonSSMManagedInstanceCore</code></td>
</tr>
<tr>
<td>3</td>
<td>ロール名</td>
<td><code>my-ec2-2tier-role</code></td>
</tr>
</tbody>
</table>
<p>「ロールを作成」をクリック。</p>
<hr>
<h2><span id="toc10">③ VPCの作成</span></h2>
<p><strong>AWSコンソール → VPC → 仮想プライベートクラウド → 「お使いのVPC」→ 「VPCを作成」</strong></p>
<blockquote>
<p><strong>VPCとは</strong>: AWS上に作るプライベートなネットワーク空間。この中にEC2などを置きます。CIDR（サイダー）でIPアドレスの範囲を指定します。<code>10.0.0.0/16</code> は <code>10.0.0.0 〜 10.0.255.255</code> の65536個のIPアドレスを表します。</p>
</blockquote>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>作成するリソース</td>
<td><strong>VPCのみ</strong></td>
</tr>
<tr>
<td>名前タグ</td>
<td><code>my-vpc</code></td>
</tr>
<tr>
<td>IPv4 CIDR</td>
<td><code>10.0.0.0/16</code></td>
</tr>
<tr>
<td>IPv6 CIDR ブロック</td>
<td><strong>なし</strong></td>
</tr>
<tr>
<td>テナンシー</td>
<td>デフォルト</td>
</tr>
</tbody>
</table>
<p>「VPCを作成」をクリック。</p>
<p><strong>控えておく情報</strong>: 作成された VPC ID（<code>vpc-xxxxxxxxxx</code>）</p>
<p><!-- ![VPC作成画面](images/vpc-create.jpg) --></p>
<hr>
<h2><span id="toc11">④ インターネットゲートウェイの作成・アタッチ</span></h2>
<blockquote>
<p><strong>インターネットゲートウェイ（IGW）とは</strong>: VPCとインターネットを接続する出入り口です。これをVPCにアタッチすることで、VPC内のEC2がインターネットと通信できるようになります。</p>
</blockquote>
<h3><span id="toc12">4-1. インターネットゲートウェイを作成する</span></h3>
<p><strong>AWSコンソール → VPC → インターネットゲートウェイ → 「インターネットゲートウェイの作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前タグ</td>
<td><code>my-igw</code></td>
</tr>
</tbody>
</table>
<p>「インターネットゲートウェイの作成」をクリック。</p>
<h3><span id="toc13">4-2. VPCにアタッチする</span></h3>
<p>作成直後の画面から「アクション」→「VPCにアタッチ」をクリック。</p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>使用可能なVPC</td>
<td><code>my-vpc</code> を選択</td>
</tr>
</tbody>
</table>
<p>「インターネットゲートウェイのアタッチ」をクリック。</p>
<p>ステータスが <strong>「Attached」</strong> になることを確認します。</p>
<hr>
<h2><span id="toc14">⑤ サブネットの作成</span></h2>
<blockquote>
<p><strong>サブネットとは</strong>: VPC内をさらに分割したネットワークです。パブリックサブネットはインターネットと通信でき、プライベートサブネットはVPC内部とのみ通信します。</p>
</blockquote>
<p><strong>AWSコンソール → VPC → サブネット → 「サブネットを作成」</strong></p>
<p>VPC ID で <code>my-vpc</code> を選択します。</p>
<h3><span id="toc15">5-1. パブリックサブネット</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>サブネット名</td>
<td><code>my-public-subnet</code></td>
</tr>
<tr>
<td>アベイラビリティーゾーン</td>
<td><code>ap-northeast-1a</code></td>
</tr>
<tr>
<td>IPv4 CIDR</td>
<td><code>10.0.1.0/24</code></td>
</tr>
</tbody>
</table>
<h3><span id="toc16">5-2. プライベートサブネット</span></h3>
<p>「新しいサブネットを追加」をクリックして2つ目のサブネットを設定します。</p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>サブネット名</td>
<td><code>my-private-subnet</code></td>
</tr>
<tr>
<td>アベイラビリティーゾーン</td>
<td><code>ap-northeast-1a</code></td>
</tr>
<tr>
<td>IPv4 CIDR</td>
<td><code>10.0.2.0/24</code></td>
</tr>
</tbody>
</table>
<p>「サブネットを作成」をクリック。</p>
<h3><span id="toc17">5-3. パブリックサブネットのパブリックIP自動割り当てを有効化</span></h3>
<p><strong>サブネット一覧 → <code>my-public-subnet</code> を選択 → 「アクション」→「サブネットの設定を編集」</strong></p>
<p>「パブリック IPv4 アドレスの自動割り当てを有効化」にチェックを入れる → 「保存」。</p>
<blockquote>
<p>APサーバEC2を起動したときに自動でパブリックIPが割り当てられるようになります。プライベートサブネットはこの設定をしません（DBサーバにパブリックIPを付与しない）。</p>
</blockquote>
<p><!-- ![サブネット作成画面](images/subnet-create.jpg) --></p>
<hr>
<h2><span id="toc18">⑥ ルートテーブルの設定</span></h2>
<blockquote>
<p><strong>ルートテーブルとは</strong>: サブネット内のEC2がパケットを送るときの「経路表」です。パブリックサブネットはインターネット向けのルート（→IGW）を持ち、プライベートサブネットは持ちません。</p>
</blockquote>
<h3><span id="toc19">6-1. パブリックルートテーブルを作成する</span></h3>
<p><strong>AWSコンソール → VPC → ルートテーブル → 「ルートテーブルを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-public-rt</code></td>
</tr>
<tr>
<td>VPC</td>
<td><code>my-vpc</code></td>
</tr>
</tbody>
</table>
<p>「ルートテーブルを作成」をクリック。</p>
<p><strong>インターネット向けルートを追加します:</strong></p>
<p><code>my-public-rt</code> を選択 → 「ルート」タブ → 「ルートを編集」→「ルートを追加」</p>
<table>
<thead>
<tr>
<th>送信先</th>
<th>ターゲット</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0.0.0.0/0</code></td>
<td><code>my-igw</code>（インターネットゲートウェイを選択）</td>
</tr>
</tbody>
</table>
<p>「変更を保存」をクリック。</p>
<blockquote>
<p><strong><code>0.0.0.0/0</code> とは</strong>: 「それ以外のすべての宛先」を意味します。VPC内向けのルートはデフォルトで存在するため、インターネット向けのルートだけ追加すれば OKです。</p>
</blockquote>
<p><strong>パブリックサブネットを関連付けます:</strong></p>
<p><code>my-public-rt</code> の「サブネットの関連付け」タブ → 「サブネットの関連付けを編集」→ <code>my-public-subnet</code> にチェック → 「関連付けを保存」。</p>
<h3><span id="toc20">6-2. プライベートルートテーブルを作成する</span></h3>
<p><strong>VPC → ルートテーブル → 「ルートテーブルを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-private-rt</code></td>
</tr>
<tr>
<td>VPC</td>
<td><code>my-vpc</code></td>
</tr>
</tbody>
</table>
<p>「ルートテーブルを作成」をクリック。</p>
<blockquote>
<p><strong>インターネット向けルートは追加しません</strong>。プライベートサブネットからインターネットへの経路を意図的に持たせないことで、DBサーバをインターネットから完全に隔離します。</p>
</blockquote>
<p><strong>プライベートサブネットを関連付けます:</strong></p>
<p><code>my-private-rt</code> の「サブネットの関連付け」タブ → 「サブネットの関連付けを編集」→ <code>my-private-subnet</code> にチェック → 「関連付けを保存」。</p>
<h3><span id="toc21">6-3. S3 VPC Gateway Endpointを作成する（重要）</span></h3>
<blockquote>
<p><strong>なぜ必要か</strong>: プライベートサブネットはインターネットに出られないため、EC2起動時の <code>dnf install</code> でパッケージをダウンロードできません。Amazon Linux 2023のパッケージリポジトリはS3上にあるため、S3だけインターネットを経由せずアクセスできるGateway Endpointを作成することで解決します。<strong>Gateway Endpointは無料</strong>です。</p>
</blockquote>
<p><strong>AWSコンソール → VPC → エンドポイント → 「エンドポイントを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前タグ</td>
<td><code>my-s3-endpoint</code></td>
</tr>
<tr>
<td>サービスカテゴリ</td>
<td><strong>AWSのサービス</strong></td>
</tr>
<tr>
<td>サービス</td>
<td>検索欄に <code>s3</code> と入力 → <code>com.amazonaws.ap-northeast-1.s3</code> の <strong>タイプ: Gateway</strong> を選択</td>
</tr>
<tr>
<td>VPC</td>
<td><code>my-vpc</code></td>
</tr>
<tr>
<td>ルートテーブル</td>
<td><strong><code>my-private-rt</code></strong> にチェックを入れる</td>
</tr>
</tbody>
</table>
<p>「エンドポイントを作成」をクリック。</p>
<p><strong>確認</strong>: <code>my-private-rt</code> の「ルート」タブを開くと、S3向けのルートが自動追加されていることを確認します。</p>
<p><!-- ![S3 VPC Endpoint作成画面](images/s3-endpoint-create.jpg) --></p>
<hr>
<h2><span id="toc22">⑦ セキュリティグループの作成</span></h2>
<blockquote>
<p><strong>注意</strong>: APサーバSGを先に作成します。DBサーバSGがAPサーバSGをSG参照するためです。</p>
</blockquote>
<h3><span id="toc23">7-1. APサーバSGの作成</span></h3>
<p><strong>EC2 → セキュリティグループ → 「セキュリティグループを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>セキュリティグループ名</td>
<td><code>my-ap-sg</code></td>
</tr>
<tr>
<td>説明</td>
<td><code>AP server SG (public subnet)</code></td>
</tr>
<tr>
<td>VPC</td>
<td><strong><code>my-vpc</code></strong>（デフォルトVPCではなく今回作成したVPCを選択）</td>
</tr>
</tbody>
</table>
<p><strong>インバウンドルール:</strong></p>
<table>
<thead>
<tr>
<th>タイプ</th>
<th>ポート</th>
<th>ソース</th>
<th>説明</th>
</tr>
</thead>
<tbody>
<tr>
<td>SSH</td>
<td>22</td>
<td><code>203.0.113.1/32</code>（自分のIP）</td>
<td>SSH from my IP</td>
</tr>
<tr>
<td>HTTP</td>
<td>80</td>
<td><code>203.0.113.1/32</code>（自分のIP）</td>
<td>HTTP from my IP</td>
</tr>
</tbody>
</table>
<p><strong>アウトバウンドルール</strong>: 「すべてのトラフィック / 0.0.0.0/0」があることを確認します。</p>
<p>「セキュリティグループを作成」をクリック。</p>
<h3><span id="toc24">7-2. DBサーバSGの作成</span></h3>
<p><strong>EC2 → セキュリティグループ → 「セキュリティグループを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>セキュリティグループ名</td>
<td><code>my-db-sg</code></td>
</tr>
<tr>
<td>説明</td>
<td><code>DB server SG (private subnet)</code></td>
</tr>
<tr>
<td>VPC</td>
<td><strong><code>my-vpc</code></strong></td>
</tr>
</tbody>
</table>
<p><strong>インバウンドルール（「ルールを追加」で2つ追加します）:</strong></p>
<p><strong>ルール1: SSH（APサーバ経由の踏み台接続）</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>タイプ</td>
<td>SSH</td>
</tr>
<tr>
<td>ソースタイプ</td>
<td>カスタム</td>
</tr>
<tr>
<td>ソース</td>
<td><code>my-ap-sg</code> を検索して選択</td>
</tr>
<tr>
<td>説明</td>
<td><code>SSH from AP server only (bastion)</code></td>
</tr>
</tbody>
</table>
<p><strong>ルール2: MySQL（APサーバからのDB接続）</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>タイプ</td>
<td>MySQL/Aurora</td>
</tr>
<tr>
<td>ソースタイプ</td>
<td>カスタム</td>
</tr>
<tr>
<td>ソース</td>
<td><code>my-ap-sg</code> を検索して選択</td>
</tr>
<tr>
<td>説明</td>
<td><code>MySQL from AP server only</code></td>
</tr>
</tbody>
</table>
<p><strong>アウトバウンドルール</strong>: 「すべてのトラフィック / 0.0.0.0/0」があることを確認します。</p>
<p>「セキュリティグループを作成」をクリック。</p>
<p><!-- ![DBサーバSG作成画面](images/db-sg-create.jpg) --></p>
<hr>
<h2><span id="toc25">⑧ APサーバEC2の起動（パブリックサブネット）</span></h2>
<p><strong>EC2 → インスタンス → 「インスタンスを起動」</strong></p>
<h3><span id="toc26">8-1. 基本設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ap-instance</code></td>
</tr>
<tr>
<td>AMI</td>
<td><strong>Amazon Linux 2023 AMI</strong>（デフォルトで選択済み）</td>
</tr>
<tr>
<td>インスタンスタイプ</td>
<td><strong>t2.micro</strong>（無料枠対象）</td>
</tr>
<tr>
<td>キーペア</td>
<td><code>my-ec2-2tier-key</code></td>
</tr>
</tbody>
</table>
<h3><span id="toc27">8-2. ネットワーク設定</span></h3>
<p>「ネットワーク設定」→「編集」をクリックして以下を設定します。</p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC</td>
<td><strong><code>my-vpc</code></strong></td>
</tr>
<tr>
<td>サブネット</td>
<td><strong><code>my-public-subnet</code></strong></td>
</tr>
<tr>
<td>パブリック IP の自動割り当て</td>
<td><strong>有効</strong></td>
</tr>
<tr>
<td>セキュリティグループ</td>
<td><strong>既存のセキュリティグループを選択</strong> → <code>my-ap-sg</code></td>
</tr>
</tbody>
</table>
<h3><span id="toc28">8-3. IAMロール・UserDataの設定</span></h3>
<p>「高度な詳細」を開きます。</p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>IAM インスタンスプロファイル</td>
<td><code>my-ec2-2tier-role</code></td>
</tr>
</tbody>
</table>
<p>「ユーザーデータ」に以下を貼り付けます。</p>
<pre><code class="language-bash">#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
cat &gt; /var/www/html/index.html &lt;&lt; 'HTMLEOF'
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;&lt;meta charset="UTF-8"&gt;&lt;title&gt;AP Server - Phase 1-4&lt;/title&gt;&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;AP Server (Public Subnet)&lt;/h1&gt;
&lt;p&gt;This AP server is in the PUBLIC subnet and can reach the DB server in the PRIVATE subnet.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
HTMLEOF</code></pre>
<p>「インスタンスを起動」をクリック。</p>
<p><strong>控えておく情報</strong>: APサーバのパブリックIPアドレス</p>
<p><!-- ![APサーバEC2起動後の画面](images/ap-ec2-running.jpg) --></p>
<hr>
<h2><span id="toc29">⑨ DBサーバEC2の起動（プライベートサブネット）</span></h2>
<p><strong>EC2 → インスタンス → 「インスタンスを起動」</strong></p>
<h3><span id="toc30">9-1. 基本設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-db-instance</code></td>
</tr>
<tr>
<td>AMI</td>
<td><strong>Amazon Linux 2023 AMI</strong></td>
</tr>
<tr>
<td>インスタンスタイプ</td>
<td><strong>t2.micro</strong></td>
</tr>
<tr>
<td>キーペア</td>
<td><code>my-ec2-2tier-key</code></td>
</tr>
</tbody>
</table>
<h3><span id="toc31">9-2. ネットワーク設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC</td>
<td><strong><code>my-vpc</code></strong></td>
</tr>
<tr>
<td>サブネット</td>
<td><strong><code>my-private-subnet</code></strong></td>
</tr>
<tr>
<td>パブリック IP の自動割り当て</td>
<td><strong>無効</strong>（プライベートサブネットのため）</td>
</tr>
<tr>
<td>セキュリティグループ</td>
<td><strong>既存のセキュリティグループを選択</strong> → <code>my-db-sg</code></td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>パブリックIPを付与しない</strong>: DBサーバはインターネットから直接アクセスされる必要がありません。プライベートサブネットに置き、パブリックIPを持たせないことで、インターネットから完全に隔離します。</p>
</blockquote>
<h3><span id="toc32">9-3. IAMロール・UserDataの設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>IAM インスタンスプロファイル</td>
<td><code>my-ec2-2tier-role</code></td>
</tr>
</tbody>
</table>
<p>「ユーザーデータ」に以下を貼り付けます。</p>
<pre><code class="language-bash">#!/bin/bash
dnf update -y
dnf install -y mariadb105-server mariadb105
systemctl start mariadb
systemctl enable mariadb
sudo mysql -u root &lt;&lt; 'SQLEOF'
SET PASSWORD FOR root@localhost = PASSWORD('Admin1234!');
CREATE USER IF NOT EXISTS 'handson'@'%' IDENTIFIED BY 'Handson1234!';
GRANT ALL PRIVILEGES ON *.* TO 'handson'@'%' WITH GRANT OPTION;
CREATE DATABASE IF NOT EXISTS sampledb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
FLUSH PRIVILEGES;
SQLEOF</code></pre>
<blockquote>
<p><strong>⑥-3でS3 VPC Endpointを作成済みの場合</strong>: <code>dnf install</code> はS3経由で正常に動作します。Endpointを作成せずにEC2を起動した場合はMariaDBがインストールされないため、踏み台SSH接続後に手動で <code>sudo dnf install -y mariadb105-server mariadb105</code> を実行してください。</p>
</blockquote>
<p>「インスタンスを起動」をクリック。</p>
<p><strong>控えておく情報</strong>: DBサーバのプライベートIPアドレス（パブリックIPはありません）</p>
<p>インスタンス詳細 → 「プライベート IPv4 アドレス」（例: <code>10.0.2.xxx</code>）を確認してメモします。</p>
<hr>
<h2><span id="toc33">⑩ 動作確認</span></h2>
<blockquote>
<p><strong>待機時間</strong>: EC2起動後、UserDataの完了まで数分かかります。APサーバは2〜3分、DBサーバは5〜8分待ちます。</p>
</blockquote>
<h3><span id="toc34">10-1. APサーバのWeb確認</span></h3>
<p>ブラウザで以下にアクセスします。</p>
<pre><code class="language-plaintext">http://（APサーバのパブリックIP）</code></pre>
<p><code>AP Server (Public Subnet)</code> が表示されれば成功です。</p>
<p><!-- ![APサーバWebページ確認](images/ap-web-browser.jpg) --></p>
<h3><span id="toc35">10-2. APサーバへのSSH接続</span></h3>
<pre><code class="language-cmd">ssh -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ec2-user@（APパブリックIP）</code></pre>
<h3><span id="toc36">10-3. キーペアをAPサーバにコピーする（踏み台SSH準備）</span></h3>
<p>APサーバを踏み台としてDBサーバにSSH接続するために、ローカルPCからAPサーバにキーペアをコピーします。</p>
<p><strong>ローカルPCの別ターミナルで実行します:</strong></p>
<pre><code class="language-cmd">scp -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
  C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
  ec2-user@（APパブリックIP）:~/.ssh/</code></pre>
<p>APサーバ上でキーペアのパーミッションを設定します。</p>
<pre><code class="language-bash">chmod 400 ~/.ssh/my-ec2-2tier-key.pem</code></pre>
<h3><span id="toc37">10-4. APサーバ経由でDBサーバにSSH接続（踏み台接続）</span></h3>
<p><strong>APサーバのSSHセッションから実行します:</strong></p>
<pre><code class="language-bash">ssh -i ~/.ssh/my-ec2-2tier-key.pem ec2-user@（DBプライベートIP）</code></pre>
<p><code>[ec2-user@ip-10-0-2-xxx ~]$</code> のプロンプトが表示されれば踏み台接続成功です。</p>
<pre><code class="language-bash">sudo systemctl status mariadb

# MariaDBに接続
mysql -u root -pAdmin1234!</code></pre>
<p>MariaDBのプロンプトで確認します。</p>
<pre><code class="language-sql">SHOW DATABASES;
EXIT;</code></pre>
<p>DBサーバから切断します。</p>
<pre><code class="language-bash">exit</code></pre>
<h3><span id="toc38">10-5. APサーバからMySQLに接続（AP→DB通信確認）</span></h3>
<p>APサーバのSSHセッションで実行します。</p>
<pre><code class="language-bash"># mysqlクライアントのインストール
sudo dnf install -y mariadb105

# DBサーバのプライベートIPにMySQL接続
mysql -h （DBプライベートIP） -u handson -pHandson1234! sampledb</code></pre>
<p>接続成功すれば <code>MariaDB [sampledb]&gt;</code> が表示されます。</p>
<pre><code class="language-sql">CREATE TABLE IF NOT EXISTS messages (id INT AUTO_INCREMENT PRIMARY KEY, text VARCHAR(100));
INSERT INTO messages (text) VALUES ('Hello from AP server!');
SELECT * FROM messages;
EXIT;</code></pre>
<p>APサーバから切断します。</p>
<pre><code class="language-bash">exit</code></pre>
<p><!-- ![踏み台SSHとMySQL接続確認](images/bastion-mysql-connect.jpg) --></p>
<hr>
<h2><span id="toc39">⑪ リソースの削除</span></h2>
<p><strong>課金を止めるために、ハンズオン完了後は必ず削除してください。削除する順番が重要です。</strong></p>
<blockquote>
<p><strong>CloudFormation版と比較</strong>: コンソール版はリソースの依存関係を意識して手動で削除する必要があります。CloudFormation版は <code>delete-stack</code> 1本で全て自動削除できます。</p>
</blockquote>
<h3><span id="toc40">削除順序</span></h3>
<p><strong>1. EC2インスタンスを終了する（2台）</strong></p>
<p><strong>EC2 → インスタンス → <code>my-ap-instance</code> と <code>my-db-instance</code> を選択 → 「インスタンスを終了」</strong></p>
<p>「終了済み」になるまで待ちます（2〜5分）。</p>
<p><strong>2. セキュリティグループを削除する（DBサーバSG → APサーバSGの順）</strong></p>
<p>DBサーバSGがAPサーバSGを参照しているため、DBサーバSGを先に削除します。</p>
<p>① <strong><code>my-db-sg</code></strong> を選択 → 「アクション」→「セキュリティグループを削除」</p>
<p>② <strong><code>my-ap-sg</code></strong> を選択 → 「アクション」→「セキュリティグループを削除」</p>
<p><strong>3. S3 VPC Endpointを削除する</strong></p>
<p><strong>VPC → エンドポイント → <code>my-s3-endpoint</code> を選択 → 「アクション」→「エンドポイントを削除」</strong></p>
<p><strong>4. ルートテーブルの関連付けを解除・削除する</strong></p>
<p>① <code>my-public-rt</code> を選択 → 「サブネットの関連付け」タブ → 「サブネットの関連付けを編集」→ チェックを外す → 「保存」</p>
<p>② <code>my-private-rt</code> も同様に関連付けを解除する</p>
<p>③ <code>my-public-rt</code> を選択 → 「ルート」タブ → 「ルートを編集」→ <code>0.0.0.0/0</code> のルートを削除 → 「保存」</p>
<p>④ <code>my-public-rt</code> を選択 → 「アクション」→「ルートテーブルの削除」</p>
<p>⑤ <code>my-private-rt</code> も同様に削除する</p>
<p><strong>5. サブネットを削除する（2つ）</strong></p>
<p><strong>VPC → サブネット → <code>my-public-subnet</code> → 「アクション」→「サブネットを削除」</strong></p>
<p>同様に <code>my-private-subnet</code> も削除します。</p>
<p><strong>6. インターネットゲートウェイをデタッチ・削除する</strong></p>
<p><strong>VPC → インターネットゲートウェイ → <code>my-igw</code> → 「アクション」→「VPCからデタッチ」</strong></p>
<p>デタッチ完了後、「アクション」→「インターネットゲートウェイの削除」。</p>
<p><strong>7. VPCを削除する</strong></p>
<p><strong>VPC → お使いのVPC → <code>my-vpc</code> → 「アクション」→「VPCを削除」</strong></p>
<p><strong>8. IAMロールを削除する</strong></p>
<p><strong>IAM → ロール → <code>my-ec2-2tier-role</code> → 「削除」</strong></p>
<p><strong>9. キーペアを削除する（任意）</strong></p>
<p><strong>EC2 → キーペア → <code>my-ec2-2tier-key</code> → 「削除」</strong></p>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem</code></pre>
<hr>
<h2><span id="toc41">CloudFormation版との比較</span></h2>
<table>
<thead>
<tr>
<th>作業</th>
<th>コンソール（手動）</th>
<th>CloudFormation</th>
</tr>
</thead>
<tbody>
<tr>
<td>VPC・IGW・サブネット・RTの設定</td>
<td>6画面・20ステップ以上</td>
<td>template.yaml に定義済み</td>
</tr>
<tr>
<td>S3 VPC Endpoint作成</td>
<td>画面でポチポチ</td>
<td>template.yaml に定義済み</td>
</tr>
<tr>
<td>EC2×2台の起動</td>
<td>2回インスタンス起動操作</td>
<td>コマンド1本（並列作成）</td>
</tr>
<tr>
<td>削除（依存関係あり）</td>
<td>8ステップ・手動管理</td>
<td><code>delete-stack</code> 1本</td>
</tr>
<tr>
<td>全体の所要時間</td>
<td>30〜40分</td>
<td>8〜12分</td>
</tr>
<tr>
<td>再現性</td>
<td>低い（手順漏れのリスク大）</td>
<td>高い</td>
</tr>
</tbody>
</table>
<p><strong>コンソール版で実感できたポイント:</strong></p>
<ul>
<li>VPC・IGW・サブネット・ルートテーブルの依存関係が視覚的に理解できる</li>
<li>プライベートサブネットにEC2を置くとパブリックIPが付かないことを実感できる</li>
<li>踏み台接続（APサーバ経由でDBサーバにSSH）の意味と手順が身につく</li>
<li>S3 VPC Endpointがなければ <code>dnf install</code> が失敗することを体験できる</li>
</ul>
<p><strong>CloudFormation版でも試してみる</strong>: <a href="https://caymezon.com/aws-handson-cloudformation-ec2-2tier/">CloudFormationでAP+DB 2層構成（VPC設計）を自動デプロイする手順</a></p>
<hr>
<h2><span id="toc42">トラブルシューティング</span></h2>
<table>
<thead>
<tr>
<th>症状</th>
<th>原因</th>
<th>対処</th>
</tr>
</thead>
<tbody>
<tr>
<td>APサーバのWebページが表示されない</td>
<td>UserDataが完了していない</td>
<td>2〜3分待ってリロード</td>
</tr>
<tr>
<td>DBサーバの <code>dnf install</code> が失敗する</td>
<td>S3 VPC Endpointが未作成</td>
<td>⑥-3の手順でEndpointを作成後、踏み台SSH接続して手動で <code>sudo dnf install -y mariadb105-server mariadb105</code> を実行</td>
</tr>
<tr>
<td>APサーバからDBサーバにSSH接続できない</td>
<td><code>my-db-sg</code> のSSHソースが <code>my-ap-sg</code> になっていない</td>
<td>DBサーバSGのインバウンドルールを確認</td>
</tr>
<tr>
<td>APサーバからMySQLに接続できない</td>
<td><code>my-db-sg</code> のMySQL(3306)ソースが <code>my-ap-sg</code> になっていない</td>
<td>DBサーバSGのインバウンドルールを確認</td>
</tr>
<tr>
<td>セキュリティグループが削除できない</td>
<td>EC2インスタンスがまだ「使用中」またはDBサーバSGを先に削除していない</td>
<td>EC2「終了済み」後に、DBサーバSG → APサーバSGの順で削除</td>
</tr>
<tr>
<td>VPCが削除できない</td>
<td>サブネット・IGW・RTが残っている</td>
<td>削除順序を守る（サブネット・RT・IGWを先に削除）</td>
</tr>
<tr>
<td>SGを作成するとき <code>my-vpc</code> のSGが選択できない</td>
<td>EC2起動時にVPCをデフォルトVPCにしている</td>
<td>ネットワーク設定でVPCを <code>my-vpc</code> に変更してから再選択</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc43">まとめ</span></h2>
<p>今回のハンズオンで体験できたこと：</p>
<table>
<thead>
<tr>
<th>確認項目</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>VPC設計</strong></td>
<td>カスタムVPC・パブリック/プライベートサブネット・IGW・ルートテーブルを一から構築</td>
</tr>
<tr>
<td><strong>ネットワーク分離</strong></td>
<td>DBサーバをプライベートサブネットに配置してインターネットから隔離</td>
</tr>
<tr>
<td><strong>S3 VPC Endpoint</strong></td>
<td>プライベートサブネットからインターネットなしでパッケージをインストール</td>
</tr>
<tr>
<td><strong>踏み台接続</strong></td>
<td>APサーバを中継してプライベートサブネットのDBサーバにSSH接続</td>
</tr>
<tr>
<td><strong>SG参照</strong></td>
<td>DBサーバSGのルールをIPアドレスではなくAPサーバSGで指定</td>
</tr>
<tr>
<td><strong>削除手順</strong></td>
<td>依存関係を意識して8ステップで全リソースを削除</td>
</tr>
</tbody>
</table>
<p>20ステップ以上の手動作業でリソースを一つひとつ作ると、CloudFormationが裏で何を自動化しているかが理解できます。ぜひ次は <a href="https://caymezon.com/aws-handson-cloudformation-ec2-2tier/">CloudFormation版</a> でコマンド1本の差を体感してみてください。</p>
<hr>
<h2><span id="toc44">関連記事</span></h2>
<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運用入門 改訂第2版 押さえておきたいAWSの基本と運用ノウハウ [AWS深掘りガイド]","b":"SBクリエイティブ","t":"","d":"https:\/\/m.media-amazon.com","c_p":"\/images\/I","p":["\/51AAOubymTL._SL500_.jpg","\/51VMG6YKHdL._SL500_.jpg","\/41EdPB8azAL._SL500_.jpg","\/41v2JFE-9jL._SL500_.jpg","\/41FEEqR-yDL._SL500_.jpg","\/41JfZAdnTPL._SL500_.jpg","\/41vGK0czQrL._SL500_.jpg","\/41-SnYtz2aL._SL500_.jpg","\/41sPrV5fi3L._SL500_.jpg","\/41p7JtvYJ1L._SL500_.jpg","\/4169GVNTs8L._SL500_.jpg","\/41BPI5HP3zL._SL500_.jpg","\/41QOyk60CYL._SL500_.jpg","\/41APjk6FphL._SL500_.jpg","\/41ezKUu7VRL._SL500_.jpg","\/41A1n3K+r5L._SL500_.jpg","\/41aY2T8lEOL._SL500_.jpg","\/419Ca1V6HZL._SL500_.jpg","\/41zQkYyLPzL._SL500_.jpg","\/41YpHcyxiTL._SL500_.jpg","\/41-tKN5mt6L._SL500_.jpg","\/419Mv6m55IL._SL500_.jpg"],"u":{"u":"https:\/\/www.amazon.co.jp\/dp\/4815631085","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\/4815631085","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%E9%81%8B%E7%94%A8%E5%85%A5%E9%96%80%20%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88%20%E6%8A%BC%E3%81%95%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E9%81%8B%E7%94%A8%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6%20%5BAWS%E6%B7%B1%E6%8E%98%E3%82%8A%E3%82%AC%E3%82%A4%E3%83%89%5D\/","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%E9%81%8B%E7%94%A8%E5%85%A5%E9%96%80%20%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88%20%E6%8A%BC%E3%81%95%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E9%81%8B%E7%94%A8%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6%20%5BAWS%E6%B7%B1%E6%8E%98%E3%82%8A%E3%82%AC%E3%82%A4%E3%83%89%5D","a_id":1466950,"p_id":1225,"pl_id":27061,"pc_id":1925,"s_n":"yahoo","u_so":3}],"eid":"E8MM1","s":"s"});</script></p>
<div id="msmaflink-E8MM1">リンク</div>
<p><!-- MoshimoAffiliateEasyLink END --> --></p><p>The post <a href="https://caymezon.com/aws-handson-console-ec2-2tier/">AWSコンソールでVPC設計からAP+DB 2層構成を構築する手順【踏み台SSH / CloudFormation版との比較付き】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://caymezon.com/aws-handson-console-ec2-2tier/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CloudFormationでAP+DB 2層構成（VPC設計）を自動デプロイする手順【踏み台SSH / コンソール版との比較付き】</title>
		<link>https://caymezon.com/aws-handson-cloudformation-ec2-2tier/</link>
					<comments>https://caymezon.com/aws-handson-cloudformation-ec2-2tier/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Sat, 04 Apr 2026 07:33:58 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></category>
		<category><![CDATA[2層構成]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWSCLI]]></category>
		<category><![CDATA[CloudFormation]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[IaC]]></category>
		<category><![CDATA[MariaDB]]></category>
		<category><![CDATA[SG参照]]></category>
		<category><![CDATA[VPC]]></category>
		<category><![CDATA[セキュリティグループ]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[パブリックサブネット]]></category>
		<category><![CDATA[プライベートサブネット]]></category>
		<category><![CDATA[初心者]]></category>
		<category><![CDATA[踏み台]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20323</guid>

					<description><![CDATA[<p>目次 はじめにCloudFormation vs コンソール：どれだけ違うかキーワード解説前提条件template.yaml の全文1. VpcId を指定した SecurityGroup2. S3 VPC Gatewa [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-cloudformation-ec2-2tier/">CloudFormationでAP+DB 2層構成（VPC設計）を自動デプロイする手順【踏み台SSH / コンソール版との比較付き】</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">CloudFormation vs コンソール：どれだけ違うか</a></li><li><a href="#toc3" tabindex="0">キーワード解説</a></li><li><a href="#toc4" tabindex="0">前提条件</a></li><li><a href="#toc5" tabindex="0">template.yaml の全文</a><ol><li><a href="#toc6" tabindex="0">1. VpcId を指定した SecurityGroup</a></li><li><a href="#toc7" tabindex="0">2. S3 VPC Gateway Endpoint（無料）</a></li><li><a href="#toc8" tabindex="0">3. DBInstance の DependsOn</a></li><li><a href="#toc9" tabindex="0">4. SubnetId でサブネットを指定</a></li></ol></li><li><a href="#toc10" tabindex="0">作業順序</a></li><li><a href="#toc11" tabindex="0">⓪ 自分のIPアドレスを確認する</a></li><li><a href="#toc12" tabindex="0">① キーペアの作成（コンソールで実施）</a></li><li><a href="#toc13" tabindex="0">② プロジェクトフォルダに移動する</a></li><li><a href="#toc14" tabindex="0">③ スタックの作成</a></li><li><a href="#toc15" tabindex="0">④ 作成完了・Outputsの確認</a><ol><li><a href="#toc16" tabindex="0">作成状況の確認</a></li><li><a href="#toc17" tabindex="0">Outputs の確認</a></li></ol></li><li><a href="#toc18" tabindex="0">⑤ 動作確認</a><ol><li><a href="#toc19" tabindex="0">5-1. APサーバのWeb確認</a></li><li><a href="#toc20" tabindex="0">5-2. APサーバへのSSH接続</a></li><li><a href="#toc21" tabindex="0">5-3. キーペアをAPサーバにコピーする（踏み台SSH準備）</a></li><li><a href="#toc22" tabindex="0">5-4. APサーバ経由でDBサーバにSSH接続（踏み台接続）</a></li><li><a href="#toc23" tabindex="0">5-5. APサーバからMySQLに接続（AP→DB通信確認）</a></li></ol></li><li><a href="#toc24" tabindex="0">⑥ スタックの削除</a></li><li><a href="#toc25" tabindex="0">コンソール版との比較</a></li><li><a href="#toc26" tabindex="0">トラブルシューティング</a></li><li><a href="#toc27" tabindex="0">まとめ</a><ol><li><a href="#toc28" tabindex="0">CloudFormationのメリットを実感できたポイント</a></li></ol></li><li><a href="#toc29" tabindex="0">コンソール版と比較してみる</a></li><li><a href="#toc30" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「コンソールで20ステップかかったVPC設計をコードで再現したい」——それを実現するのが <strong>AWS CloudFormation</strong> です。</p>
<p>この記事では、<code>template.yaml</code> 1ファイルにVPC・サブネット・ルートテーブル・セキュリティグループ・EC2（2台）を定義し、<strong>コマンド1本でAP+DB 2層構成を一括構築するハンズオン</strong>を紹介します。コンソール版（<a href="https://caymezon.com/aws-handson-console-ec2-2tier/">AWSコンソール版ハンズオン</a>）と全く同じ構成を、CloudFormationで自動化します。</p>
<pre><code class="language-plaintext">ローカル環境（VSCode）
  └── template.yaml + AWS CLI
        ↓ スタック作成（コマンド1本）
AWS環境
  └── VPC（10.0.0.0/16）
        ├── インターネットゲートウェイ
        │
        ├── [パブリックサブネット 10.0.1.0/24]
        │     ├── パブリックルートテーブル（0.0.0.0/0 → IGW）
        │     └── APサーバEC2（Apache / パブリックIP あり）
        │
        └── [プライベートサブネット 10.0.2.0/24]
              ├── プライベートルートテーブル（VPC内のみ）
              ├── S3 VPC Gateway Endpoint（dnf用・無料）
              └── DBサーバEC2（MariaDB / パブリックIP なし）</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li>VPC・サブネット・IGW・ルートテーブルを <code>template.yaml</code> 1ファイルで定義する方法</li>
<li>S3 VPC Gateway Endpoint の <code>DependsOn</code> による起動順序制御</li>
<li><code>SubnetId</code> でEC2の配置サブネットを明示する方法</li>
<li><code>aws cloudformation create-stack</code> コマンド1本での17リソース一括デプロイ</li>
<li><code>delete-stack</code> による複雑な依存関係を持つVPCリソースの一括削除</li>
</ul>
<p><strong>このハンズオンの特徴：</strong></p>
<ul>
<li>コンソール版では20ステップ以上・30〜40分かかった作業が、コマンド1本（8〜12分）で完了</li>
<li><code>delete-stack</code> 1本でVPC・サブネット・IGW・RTの依存関係を自動解決して削除</li>
</ul>
<hr>
<p><!-- ![CloudFormationスタック作成完了画面](images/cfn-create-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">CloudFormation vs コンソール：どれだけ違うか</span></h2>
<table>
<thead>
<tr>
<th>比較項目</th>
<th>CloudFormation</th>
<th>コンソール（手動）</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>VPC・IGW・サブネット・RTの設定</strong></td>
<td>template.yaml に定義済み</td>
<td>6画面・20ステップ以上</td>
</tr>
<tr>
<td><strong>S3 VPC Endpoint作成</strong></td>
<td>template.yaml に定義済み</td>
<td>画面でポチポチ</td>
</tr>
<tr>
<td><strong>EC2×2台の起動</strong></td>
<td>コマンド1本（並列作成）</td>
<td>2回インスタンス起動操作</td>
</tr>
<tr>
<td><strong>全体のデプロイ</strong></td>
<td>コマンド1本（8〜12分）</td>
<td>20ステップ以上（30〜40分）</td>
</tr>
<tr>
<td><strong>削除（依存関係あり）</strong></td>
<td><code>delete-stack</code> 1本（自動解決）</td>
<td>8ステップ・手動管理</td>
</tr>
<tr>
<td><strong>再現性</strong></td>
<td>高い（同じ構成を何度でも再現可能）</td>
<td>低い（手順漏れのリスク大）</td>
</tr>
<tr>
<td><strong>バージョン管理</strong></td>
<td>Gitで管理可能</td>
<td>不可</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc3">キーワード解説</span></h2>
<table>
<thead>
<tr>
<th>用語</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>CloudFormation</strong></td>
<td>AWSが提供するIaC（Infrastructure as Code）サービス</td>
</tr>
<tr>
<td><strong>スタック</strong></td>
<td>CloudFormationが管理するリソースのまとまり。今回は17リソースを1スタックで管理</td>
</tr>
<tr>
<td><strong><code>DependsOn</code></strong></td>
<td>CloudFormationでリソースの作成順序を明示するプロパティ</td>
</tr>
<tr>
<td><strong><code>SubnetId</code></strong></td>
<td>EC2インスタンスを特定のサブネットに配置するプロパティ</td>
</tr>
<tr>
<td><strong>S3 VPC Gateway Endpoint</strong></td>
<td>プライベートサブネットからS3にアクセスするための無料エンドポイント</td>
</tr>
<tr>
<td><strong><code>!Select [0, !GetAZs &#39;&#39;]</code></strong></td>
<td>リージョン内の最初のAZを自動取得するCloudFormation関数</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc4">前提条件</span></h2>
<table>
<thead>
<tr>
<th>ツール</th>
<th>確認コマンド</th>
<th>最低バージョン目安</th>
</tr>
</thead>
<tbody>
<tr>
<td>AWS CLI v2</td>
<td><code>aws --version</code></td>
<td>2.x</td>
</tr>
<tr>
<td>Git</td>
<td><code>git --version</code></td>
<td>2.x</td>
</tr>
<tr>
<td>VSCode</td>
<td>-</td>
<td>-</td>
</tr>
</tbody>
</table>
<p>AWS認証確認:</p>
<pre><code class="language-cmd">aws sts get-caller-identity</code></pre>
<hr>
<h2><span id="toc5">template.yaml の全文</span></h2>
<p>以下が今回使用する <code>template.yaml</code> の全文です（17リソース）。プロジェクトフォルダ（<code>ec2-2tier-web/</code>）直下に配置します。</p>
<blockquote>
<p><strong>⚠️ コピー前に確認</strong>: <code>Default: &#39;123.456.78.901/32&#39;</code> の箇所は<strong>ダミーIPです</strong>。このまま使うとスタック作成は成功しますが、SSHもWebもアクセスできません。<code>--parameters</code> でIPを上書きするか（推奨）、Defaultを自分のIPに書き換えてから使ってください。</p>
</blockquote>
<pre><code class="language-yaml">AWSTemplateFormatVersion: '2010-09-09'
Description: 'EC2 2-tier Architecture (AP + DB) with VPC public/private subnet separation (Phase 1-4)'

Parameters:
  KeyName:
    Type: String
    Default: 'my-ec2-2tier-key'
    Description: Name of an existing EC2 KeyPair

  MyIP:
    Type: String
    Default: '123.456.78.901/32'
    Description: Your IP address to allow SSH and HTTP access (CIDR format e.g. 203.0.113.1/32)

Resources:

  # VPC and Network
  # ============================================================

  # VPC: isolated network space for this hands-on
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: 'my-vpc'

  # Internet Gateway: connects the VPC to the internet
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: 'my-igw'

  # Attach Internet Gateway to VPC
  IGWAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Public Subnet: AP server goes here (internet accessible)
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: 'my-public-subnet'

  # Private Subnet: DB server goes here (no direct internet access)
  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: 'my-private-subnet'

  # Public Route Table: routes internet traffic via Internet Gateway
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: 'my-public-rt'

  # Default route for public subnet: all traffic -&gt; Internet Gateway
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: IGWAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  # Associate public subnet with public route table
  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  # Private Route Table: no internet route (local traffic only)
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: 'my-private-rt'

  # Associate private subnet with private route table
  PrivateSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet
      RouteTableId: !Ref PrivateRouteTable

  # S3 VPC Gateway Endpoint: allows private subnet to reach S3 (for dnf package downloads)
  # Gateway endpoints are FREE - no hourly charge
  S3VPCEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VPC
      ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
      VpcEndpointType: Gateway
      RouteTableIds:
        - !Ref PrivateRouteTable

  # ============================================================
  # IAM
  # ============================================================

  # IAM Role: allows EC2 to use Session Manager
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'my-ec2-2tier-role'
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Tags:
        - Key: Name
          Value: 'my-ec2-2tier-role'

  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: 'my-ec2-2tier-profile'
      Roles:
        - !Ref EC2Role

  # ============================================================
  # Security Groups
  # ============================================================

  # AP Server Security Group: SSH and HTTP from MyIP
  APSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'my AP server SG (public subnet)'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP
          Description: SSH from my IP
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP
          Description: HTTP from my IP
      Tags:
        - Key: Name
          Value: 'my-ap-sg'

  # DB Server Security Group: MySQL from AP SG only, SSH from AP SG (via bastion)
  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'my DB server SG (private subnet)'
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId
          Description: SSH from AP server only (bastion access)
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId
          Description: MySQL from AP server only (SG-to-SG control)
      Tags:
        - Key: Name
          Value: 'my-db-sg'

  # ============================================================
  # EC2 Instances
  # ============================================================

  # AP Server: Apache in public subnet
  APInstance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      SubnetId: !Ref PublicSubnet
      SecurityGroupIds:
        - !GetAtt APSecurityGroup.GroupId
      IamInstanceProfile: !Ref EC2InstanceProfile
      UserData:
        Fn::Base64: |
          #!/bin/bash
          dnf update -y
          dnf install -y httpd
          systemctl start httpd
          systemctl enable httpd
          cat &gt; /var/www/html/index.html &lt;&lt; 'HTMLEOF'
          &lt;!DOCTYPE html&gt;
          &lt;html&gt;
          &lt;head&gt;&lt;meta charset="UTF-8"&gt;&lt;title&gt;AP Server - Phase 1-4&lt;/title&gt;&lt;/head&gt;
          &lt;body&gt;
          &lt;h1&gt;AP Server (Public Subnet)&lt;/h1&gt;
          &lt;p&gt;This AP server is in the PUBLIC subnet and can reach the DB server in the PRIVATE subnet.&lt;/p&gt;
          &lt;/body&gt;
          &lt;/html&gt;
          HTMLEOF
      Tags:
        - Key: Name
          Value: 'my-ap-instance'

  # DB Server: MariaDB in private subnet (no public IP)
  DBInstance:
    Type: AWS::EC2::Instance
    DependsOn:
      - S3VPCEndpoint
      - PrivateSubnetRouteTableAssociation
    Properties:
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      SubnetId: !Ref PrivateSubnet
      SecurityGroupIds:
        - !GetAtt DBSecurityGroup.GroupId
      IamInstanceProfile: !Ref EC2InstanceProfile
      UserData:
        Fn::Base64: |
          #!/bin/bash
          dnf update -y
          dnf install -y mariadb105-server mariadb105
          systemctl start mariadb
          systemctl enable mariadb
          sudo mysql -u root &lt;&lt; 'SQLEOF'
          SET PASSWORD FOR root@localhost = PASSWORD('Admin1234!');
          CREATE USER IF NOT EXISTS 'handson'@'%' IDENTIFIED BY 'Handson1234!';
          GRANT ALL PRIVILEGES ON *.* TO 'handson'@'%' WITH GRANT OPTION;
          CREATE DATABASE IF NOT EXISTS sampledb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
          FLUSH PRIVILEGES;
          SQLEOF
      Tags:
        - Key: Name
          Value: 'my-db-instance'

Outputs:
  VPCId:
    Description: VPC ID
    Value: !Ref VPC

  APPublicIP:
    Description: AP server public IP (open in browser or SSH)
    Value: !GetAtt APInstance.PublicIp

  DBPrivateIP:
    Description: DB server private IP (connect via AP server bastion)
    Value: !GetAtt DBInstance.PrivateIp

  WebsiteURL:
    Description: AP server website URL
    Value: !Sub 'http://${APInstance.PublicIp}'

  APSSHCommand:
    Description: SSH command to AP server
    Value: !Sub 'ssh -i C:\Users\username\.ssh\${KeyName}.pem ec2-user@${APInstance.PublicIp}'

  DBSSHCommand:
    Description: SSH command to DB server (run this FROM the AP server)
    Value: !Sub 'ssh -i ~/.ssh/${KeyName}.pem ec2-user@${DBInstance.PrivateIp}'

  MySQLConnectCommand:
    Description: MySQL connect command (run this FROM the AP server)
    Value: !Sub 'mysql -h ${DBInstance.PrivateIp} -u handson -pHandson1234! sampledb'</code></pre>
<p><strong>template.yaml の重要ポイント:</strong></p>
<h3><span id="toc6">1. VpcId を指定した SecurityGroup</span></h3>
<p>カスタムVPCを使う場合は <code>VpcId</code> を明示します。<code>VpcId</code> を指定することで <code>!GetAtt APSecurityGroup.GroupId</code> が確実にSG IDを返します。</p>
<pre><code class="language-yaml">APSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    VpcId: !Ref VPC      # ← カスタムVPCを指定（必須）

DBSecurityGroup:
  SecurityGroupIngress:
    - SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId  # ← !Refではなく!GetAtt</code></pre>
<h3><span id="toc7">2. S3 VPC Gateway Endpoint（無料）</span></h3>
<p>プライベートサブネットのEC2は直接インターネットに出られませんが、Amazon Linux 2023のパッケージリポジトリはS3上にあります。S3 VPC Gateway EndpointをプライベートルートテーブルにアタッチするとS3経由で <code>dnf install</code> が動作します。</p>
<pre><code class="language-yaml">S3VPCEndpoint:
  Type: AWS::EC2::VPCEndpoint
  Properties:
    VpcEndpointType: Gateway     # Gatewayタイプは無料
    ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
    RouteTableIds:
      - !Ref PrivateRouteTable   # プライベートRTにS3ルートが追加される</code></pre>
<h3><span id="toc8">3. DBInstance の DependsOn</span></h3>
<p>DBサーバEC2のUserDataが <code>dnf install</code> を実行するとき、S3 VPC Endpointが有効になっている必要があります。</p>
<pre><code class="language-yaml">DBInstance:
  DependsOn:
    - S3VPCEndpoint
    - PrivateSubnetRouteTableAssociation</code></pre>
<h3><span id="toc9">4. SubnetId でサブネットを指定</span></h3>
<p>EC2インスタンスがどのサブネットに配置されるかを明示します。</p>
<pre><code class="language-yaml">APInstance:
  SubnetId: !Ref PublicSubnet   # パブリックサブネットに配置

DBInstance:
  SubnetId: !Ref PrivateSubnet  # プライベートサブネットに配置</code></pre>
<p><strong>構築されるリソース一覧（17個）:</strong></p>
<table>
<thead>
<tr>
<th>#</th>
<th>リソース</th>
<th>論理ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>VPC</td>
<td><code>VPC</code></td>
</tr>
<tr>
<td>2</td>
<td>インターネットゲートウェイ</td>
<td><code>InternetGateway</code></td>
</tr>
<tr>
<td>3</td>
<td>IGW-VPCアタッチ</td>
<td><code>IGWAttachment</code></td>
</tr>
<tr>
<td>4</td>
<td>パブリックサブネット</td>
<td><code>PublicSubnet</code></td>
</tr>
<tr>
<td>5</td>
<td>プライベートサブネット</td>
<td><code>PrivateSubnet</code></td>
</tr>
<tr>
<td>6</td>
<td>パブリックルートテーブル</td>
<td><code>PublicRouteTable</code></td>
</tr>
<tr>
<td>7</td>
<td>パブリックルート（→IGW）</td>
<td><code>PublicRoute</code></td>
</tr>
<tr>
<td>8</td>
<td>パブリックRT関連付け</td>
<td><code>PublicSubnetRouteTableAssociation</code></td>
</tr>
<tr>
<td>9</td>
<td>プライベートルートテーブル</td>
<td><code>PrivateRouteTable</code></td>
</tr>
<tr>
<td>10</td>
<td>プライベートRT関連付け</td>
<td><code>PrivateSubnetRouteTableAssociation</code></td>
</tr>
<tr>
<td>11</td>
<td>S3 VPC Gateway Endpoint</td>
<td><code>S3VPCEndpoint</code></td>
</tr>
<tr>
<td>12</td>
<td>IAMロール</td>
<td><code>EC2Role</code></td>
</tr>
<tr>
<td>13</td>
<td>インスタンスプロファイル</td>
<td><code>EC2InstanceProfile</code></td>
</tr>
<tr>
<td>14</td>
<td>APサーバSG</td>
<td><code>APSecurityGroup</code></td>
</tr>
<tr>
<td>15</td>
<td>DBサーバSG</td>
<td><code>DBSecurityGroup</code></td>
</tr>
<tr>
<td>16</td>
<td>APサーバEC2</td>
<td><code>APInstance</code></td>
</tr>
<tr>
<td>17</td>
<td>DBサーバEC2</td>
<td><code>DBInstance</code></td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc10">作業順序</span></h2>
<pre><code class="language-plaintext">⓪ 自分のIPアドレスを確認する
      ↓
① キーペアを作成する（コンソールで実施）
      ↓
② プロジェクトフォルダに移動する
      ↓
③ スタックを作成する（aws cloudformation create-stack）
      ↓
④ 作成完了・Outputsを確認する
      ↓
⑤ 動作確認（Web・踏み台SSH・MySQL接続）
      ↓
⑥ スタックを削除する（aws cloudformation delete-stack）</code></pre>
<hr>
<h2><span id="toc11">⓪ 自分のIPアドレスを確認する</span></h2>
<pre><code class="language-cmd">curl https://checkip.amazonaws.com</code></pre>
<p><strong>控えておく情報</strong>: 自分のIPアドレス（例: <code>203.0.113.1</code>）</p>
<hr>
<h2><span id="toc12">① キーペアの作成（コンソールで実施）</span></h2>
<p>キーペアのみコンソールで作成します。</p>
<p><strong>AWSコンソール → EC2 → キーペア → 「キーペアを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ec2-2tier-key</code></td>
</tr>
<tr>
<td>キーペアのタイプ</td>
<td><strong>RSA</strong></td>
</tr>
<tr>
<td>プライベートキーファイル形式</td>
<td><strong>.pem</strong></td>
</tr>
</tbody>
</table>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem</code></pre>
<hr>
<h2><span id="toc13">② プロジェクトフォルダに移動する</span></h2>
<pre><code class="language-cmd">cd C:\my-aws\aws-learning-projects\ec2-2tier-web</code></pre>
<pre><code class="language-cmd">dir template.yaml</code></pre>
<hr>
<h2><span id="toc14">③ スタックの作成</span></h2>
<p><code>203.0.113.1</code> は⓪で確認した自分のIPアドレスに置き換えてください。</p>
<pre><code class="language-cmd">aws cloudformation create-stack ^
  --stack-name my-ec2-2tier-stack ^
  --template-body file://template.yaml ^
  --region ap-northeast-1 ^
  --capabilities CAPABILITY_NAMED_IAM ^
  --parameters ^
    ParameterKey=KeyName,ParameterValue=my-ec2-2tier-key ^
    ParameterKey=MyIP,ParameterValue=203.0.113.1/32</code></pre>
<p><strong>各オプションの説明:</strong></p>
<table>
<thead>
<tr>
<th>オプション</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>--stack-name my-ec2-2tier-stack</code></td>
<td>スタック名（英字始まり）</td>
</tr>
<tr>
<td><code>--template-body file://template.yaml</code></td>
<td>使用するテンプレートファイル</td>
</tr>
<tr>
<td><code>--region ap-northeast-1</code></td>
<td>デプロイ先リージョン（東京）</td>
</tr>
<tr>
<td><code>--capabilities CAPABILITY_NAMED_IAM</code></td>
<td>名前付きIAMロール作成の明示的な許可</td>
</tr>
<tr>
<td><code>--parameters ...</code></td>
<td>テンプレートのParametersに渡す値</td>
</tr>
</tbody>
</table>
<p>成功するとStackIdが表示されます。</p>
<pre><code class="language-json">{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/my-ec2-2tier-stack/xxxxx"
}</code></pre>
<p><!-- ![スタック作成コマンドの実行結果](images/cfn-create-stack-cmd.jpg) --></p>
<hr>
<h2><span id="toc15">④ 作成完了・Outputsの確認</span></h2>
<p>スタック作成完了まで<strong>約8〜12分</strong>かかります（VPCリソース×10個 + EC2×2台 + MariaDBインストールの時間）。</p>
<h3><span id="toc16">作成状況の確認</span></h3>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-2tier-stack ^
  --query "Stacks[0].StackStatus" ^
  --output text</code></pre>
<table>
<thead>
<tr>
<th>ステータス</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CREATE_IN_PROGRESS</code></td>
<td>作成中（しばらく待つ）</td>
</tr>
<tr>
<td><code>CREATE_COMPLETE</code></td>
<td>作成完了</td>
</tr>
<tr>
<td><code>CREATE_FAILED</code></td>
<td>作成失敗（トラブルシューティングを参照）</td>
</tr>
<tr>
<td><code>ROLLBACK_COMPLETE</code></td>
<td>失敗してロールバック完了</td>
</tr>
</tbody>
</table>
<h3><span id="toc17">Outputs の確認</span></h3>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-2tier-stack ^
  --query "Stacks[0].Outputs" ^
  --output table</code></pre>
<p>以下のような出力が表示されます。</p>
<pre><code class="language-plaintext">--------------------------------------------------------------------------------------
|                                  DescribeStacks                                    |
+--------------------+---------------------------------------------------------------+
|  OutputKey         |  OutputValue                                                  |
+--------------------+---------------------------------------------------------------+
|  VPCId             |  vpc-xxxxxxxxxx                                              |
|  APPublicIP        |  x.x.x.x                                                    |
|  DBPrivateIP       |  10.0.2.xxx   ← APサーバからの接続に使用                    |
|  WebsiteURL        |  http://x.x.x.x                                             |
|  APSSHCommand      |  ssh -i ...pem ec2-user@x.x.x.x                            |
|  DBSSHCommand      |  ssh -i ~/.ssh/...pem ec2-user@10.0.2.xxx                  |
|  MySQLConnectCommand| mysql -h 10.0.2.xxx -u handson -pHandson1234! sampledb     |
+--------------------+---------------------------------------------------------------+</code></pre>
<p><strong>控えておく情報:</strong></p>
<ul>
<li><code>APPublicIP</code>: APサーバのパブリックIP</li>
<li><code>DBPrivateIP</code>: DBサーバのプライベートIP（<code>10.0.2.xxx</code> 形式）</li>
<li><code>APSSHCommand</code>: APサーバへのSSHコマンド</li>
<li><code>DBSSHCommand</code>: APサーバからDBサーバへのSSHコマンド</li>
<li><code>MySQLConnectCommand</code>: APサーバから実行するMySQL接続コマンド</li>
</ul>
<p><!-- ![Outputs確認コマンドの実行結果](images/cfn-outputs-table.jpg) --></p>
<hr>
<h2><span id="toc18">⑤ 動作確認</span></h2>
<h3><span id="toc19">5-1. APサーバのWeb確認</span></h3>
<p><code>WebsiteURL</code> をブラウザで開きます。<code>AP Server (Public Subnet)</code> が表示されれば成功です。</p>
<h3><span id="toc20">5-2. APサーバへのSSH接続</span></h3>
<p><code>APSSHCommand</code> を実行します（パスを実際のパスに修正します）。</p>
<pre><code class="language-cmd">ssh -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ec2-user@（APPublicIP）</code></pre>
<h3><span id="toc21">5-3. キーペアをAPサーバにコピーする（踏み台SSH準備）</span></h3>
<p><strong>ローカルPCの別ターミナルで実行します:</strong></p>
<pre><code class="language-cmd">scp -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
  C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
  ec2-user@（APPublicIP）:~/.ssh/</code></pre>
<p>APサーバのSSHセッションでパーミッションを設定します。</p>
<pre><code class="language-bash">chmod 400 ~/.ssh/my-ec2-2tier-key.pem</code></pre>
<h3><span id="toc22">5-4. APサーバ経由でDBサーバにSSH接続（踏み台接続）</span></h3>
<p><strong>APサーバのSSHセッションから実行します:</strong></p>
<pre><code class="language-bash">ssh -i ~/.ssh/my-ec2-2tier-key.pem ec2-user@（DBPrivateIP）</code></pre>
<p><code>[ec2-user@ip-10-0-2-xxx ~]$</code> が表示されれば踏み台接続成功です。</p>
<pre><code class="language-bash"># DBサーバ上でMariaDBの状態を確認
sudo systemctl status mariadb

# MariaDBに接続
mysql -u root -pAdmin1234! -e "SHOW DATABASES;"

exit</code></pre>
<h3><span id="toc23">5-5. APサーバからMySQLに接続（AP→DB通信確認）</span></h3>
<p>APサーバのSSHセッションに戻り、<code>MySQLConnectCommand</code> をそのまま実行します。</p>
<pre><code class="language-bash"># mysqlクライアントをインストール
sudo dnf install -y mariadb105

# OutputsのMySQLConnectCommandをそのまま使う
mysql -h （DBPrivateIP） -u handson -pHandson1234! sampledb</code></pre>
<pre><code class="language-sql">CREATE TABLE IF NOT EXISTS messages (id INT AUTO_INCREMENT PRIMARY KEY, text VARCHAR(100));
INSERT INTO messages (text) VALUES ('Hello from AP server!');
SELECT * FROM messages;
EXIT;</code></pre>
<pre><code class="language-bash">exit</code></pre>
<p><!-- ![踏み台SSHとMySQL接続確認](images/bastion-mysql-connect.jpg) --></p>
<hr>
<h2><span id="toc24">⑥ スタックの削除</span></h2>
<p><strong>課金を止めるために、ハンズオン完了後は必ず削除してください。</strong></p>
<p>CloudFormationはVPC・サブネット・IGW・RT・SG・EC2の依存関係を自動解決して正しい順序で削除します。</p>
<pre><code class="language-cmd">aws cloudformation delete-stack ^
  --stack-name my-ec2-2tier-stack ^
  --region ap-northeast-1</code></pre>
<p>削除完了まで<strong>約8〜12分</strong>かかります。</p>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-2tier-stack ^
  --query "Stacks[0].StackStatus" ^
  --output text</code></pre>
<table>
<thead>
<tr>
<th>ステータス</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DELETE_IN_PROGRESS</code></td>
<td>削除中（しばらく待つ）</td>
</tr>
<tr>
<td><code>DELETE_FAILED</code></td>
<td>削除失敗（トラブルシューティングを参照）</td>
</tr>
</tbody>
</table>
<p>削除完了の確認（以下のエラーが表示されれば削除完了）。</p>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-2tier-stack ^
  --region ap-northeast-1</code></pre>
<pre><code class="language-plaintext">An error occurred (ValidationError) when calling the DescribeStacks operation:
Stack with id my-ec2-2tier-stack does not exist</code></pre>
<p>キーペアは手動で削除します。</p>
<p><strong>EC2 → キーペア → <code>my-ec2-2tier-key</code> → 「削除」</strong></p>
<hr>
<h2><span id="toc25">コンソール版との比較</span></h2>
<p>コンソール版で20ステップ以上かかった作業が、CloudFormationでは <code>template.yaml</code> に定義されています。</p>
<table>
<thead>
<tr>
<th>CFnの記述</th>
<th>コンソールでやること</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>VPC</code></td>
<td>VPC → VPCを作成</td>
</tr>
<tr>
<td><code>InternetGateway</code> + <code>IGWAttachment</code></td>
<td>IGWを作成 → VPCにアタッチ（2ステップ）</td>
</tr>
<tr>
<td><code>PublicSubnet</code> + <code>PrivateSubnet</code></td>
<td>サブネットを2つ作成</td>
</tr>
<tr>
<td><code>PublicRouteTable</code> + <code>PublicRoute</code> + <code>PublicSubnetRouteTableAssociation</code></td>
<td>パブリックRTを作成・ルート追加・サブネット関連付け（3ステップ）</td>
</tr>
<tr>
<td><code>PrivateRouteTable</code> + <code>PrivateSubnetRouteTableAssociation</code></td>
<td>プライベートRTを作成・サブネット関連付け（2ステップ）</td>
</tr>
<tr>
<td><code>S3VPCEndpoint</code></td>
<td>VPCエンドポイントを作成</td>
</tr>
<tr>
<td><code>APSecurityGroup</code> + <code>DBSecurityGroup</code></td>
<td>SGを2つ作成（APサーバSG → DBサーバSGの順）</td>
</tr>
<tr>
<td><code>APInstance</code> + <code>DBInstance</code></td>
<td>EC2を2回起動（各5〜10分）</td>
</tr>
<tr>
<td><code>delete-stack</code></td>
<td>8ステップの手動削除（依存関係を手動管理）</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc26">トラブルシューティング</span></h2>
<table>
<thead>
<tr>
<th>症状</th>
<th>原因</th>
<th>対処</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CREATE_FAILED</code> になる</td>
<td>キーペアが存在しない</td>
<td>コンソールでキーペアを確認・作成</td>
</tr>
<tr>
<td><code>CREATE_FAILED</code> になる</td>
<td>同名のIAMロールが既に存在する</td>
<td>IAMコンソールでロールを削除してから再実行</td>
</tr>
<tr>
<td><code>stackName failed to satisfy regular expression</code></td>
<td>スタック名が数字始まり</td>
<td>CloudFormationのスタック名は<strong>英字で始まる</strong>必要がある</td>
</tr>
<tr>
<td><code>Unable to load paramfile</code> エラー</td>
<td>template.yaml に日本語が含まれている</td>
<td>template.yaml のコメントは<strong>英語のみ</strong>で記述する</td>
</tr>
<tr>
<td>DBサーバのMariaDBが起動していない</td>
<td>S3 VPC EndpointのRouteTableへの反映が遅延</td>
<td>DBサーバに踏み台接続して <code>sudo dnf install -y mariadb105-server</code> を手動実行</td>
</tr>
<tr>
<td>APサーバからDBにSSH接続できない</td>
<td>DBサーバSGのSSHソースが正しくない</td>
<td>CloudFormationのイベントログで <code>CREATE_FAILED</code> を確認</td>
</tr>
<tr>
<td><code>DELETE_FAILED</code> になる</td>
<td>VPC内のリソースが残っている</td>
<td>コンソールで <code>my-vpc</code> 内の残存リソースを確認して手動削除</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc27">まとめ</span></h2>
<p>今回のハンズオンで実現できたこと：</p>
<table>
<thead>
<tr>
<th>確認項目</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>VPCリソースのIaC化</strong></td>
<td>VPC・IGW・サブネット・RT 10リソースを <code>template.yaml</code> 1ファイルで定義</td>
</tr>
<tr>
<td><strong>S3 VPC Endpoint</strong></td>
<td><code>DependsOn</code> でDBサーバEC2の起動前にEndpointが有効になることを保証</td>
</tr>
<tr>
<td><strong>一括デプロイ</strong></td>
<td><code>create-stack</code> 1本で17リソースを8〜12分で構築</td>
</tr>
<tr>
<td><strong>依存関係の自動解決</strong></td>
<td><code>delete-stack</code> 1本でVPC内のリソースを正しい順序で自動削除</td>
</tr>
<tr>
<td><strong>Outputs活用</strong></td>
<td><code>DBPrivateIP</code>・<code>MySQLConnectCommand</code> が自動生成されるため手動でコマンドを組み立てる必要なし</td>
</tr>
</tbody>
</table>
<h3><span id="toc28">CloudFormationのメリットを実感できたポイント</span></h3>
<ul>
<li>コンソール版では20ステップ以上・30〜40分かかった作業がコマンド1本（8〜12分）で完了</li>
<li>VPC・サブネット・RT・SGの複雑な削除順序をCloudFormationが自動管理</li>
<li><code>template.yaml</code> をGitで管理することで、ネットワーク設計の変更履歴が残せる</li>
</ul>
<hr>
<h2><span id="toc29">コンソール版と比較してみる</span></h2>
<p>CloudFormationが裏で何をやっているか、同じ構成をAWSコンソールのみで構築する手順をまとめました。VPCリソースの作成・削除順序や依存関係を視覚的に確認できます。</p>
<p><a href="https://caymezon.com/aws-handson-console-ec2-2tier/">AWSコンソールでVPC設計からAP+DB 2層構成を構築する手順</a></p>
<hr>
<h2><span id="toc30">関連記事</span></h2>
<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運用入門 改訂第2版 押さえておきたいAWSの基本と運用ノウハウ [AWS深掘りガイド]","b":"SBクリエイティブ","t":"","d":"https:\/\/m.media-amazon.com","c_p":"\/images\/I","p":["\/51AAOubymTL._SL500_.jpg","\/51VMG6YKHdL._SL500_.jpg","\/41EdPB8azAL._SL500_.jpg","\/41v2JFE-9jL._SL500_.jpg","\/41FEEqR-yDL._SL500_.jpg","\/41JfZAdnTPL._SL500_.jpg","\/41vGK0czQrL._SL500_.jpg","\/41-SnYtz2aL._SL500_.jpg","\/41sPrV5fi3L._SL500_.jpg","\/41p7JtvYJ1L._SL500_.jpg","\/4169GVNTs8L._SL500_.jpg","\/41BPI5HP3zL._SL500_.jpg","\/41QOyk60CYL._SL500_.jpg","\/41APjk6FphL._SL500_.jpg","\/41ezKUu7VRL._SL500_.jpg","\/41A1n3K+r5L._SL500_.jpg","\/41aY2T8lEOL._SL500_.jpg","\/419Ca1V6HZL._SL500_.jpg","\/41zQkYyLPzL._SL500_.jpg","\/41YpHcyxiTL._SL500_.jpg","\/41-tKN5mt6L._SL500_.jpg","\/419Mv6m55IL._SL500_.jpg"],"u":{"u":"https:\/\/www.amazon.co.jp\/dp\/4815631085","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\/4815631085","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%E9%81%8B%E7%94%A8%E5%85%A5%E9%96%80%20%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88%20%E6%8A%BC%E3%81%95%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E9%81%8B%E7%94%A8%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6%20%5BAWS%E6%B7%B1%E6%8E%98%E3%82%8A%E3%82%AC%E3%82%A4%E3%83%89%5D\/","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%E9%81%8B%E7%94%A8%E5%85%A5%E9%96%80%20%E6%94%B9%E8%A8%82%E7%AC%AC2%E7%89%88%20%E6%8A%BC%E3%81%95%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%A8%E9%81%8B%E7%94%A8%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6%20%5BAWS%E6%B7%B1%E6%8E%98%E3%82%8A%E3%82%AC%E3%82%A4%E3%83%89%5D","a_id":1466950,"p_id":1225,"pl_id":27061,"pc_id":1925,"s_n":"yahoo","u_so":3}],"eid":"E8MM1","s":"s"});</script></p>
<div id="msmaflink-E8MM1">リンク</div>
<p><!-- MoshimoAffiliateEasyLink END --> --></p><p>The post <a href="https://caymezon.com/aws-handson-cloudformation-ec2-2tier/">CloudFormationでAP+DB 2層構成（VPC設計）を自動デプロイする手順【踏み台SSH / コンソール版との比較付き】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://caymezon.com/aws-handson-cloudformation-ec2-2tier/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
