<?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>Apache - CayTech Lab</title>
	<atom:link href="https://caymezon.com/tag/apache/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>Apache - 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>
		<item>
		<title>AWSコンソールでEC2 + Apacheウェブサーバーを構築する手順【EC2ハンズオン / CloudFormation版との比較付き】</title>
		<link>https://caymezon.com/aws-handson-console-ec2-apache/</link>
					<comments>https://caymezon.com/aws-handson-console-ec2-apache/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Mon, 23 Mar 2026 08:38:56 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWSコンソール]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[UserData]]></category>
		<category><![CDATA[Webサーバー]]></category>
		<category><![CDATA[セキュリティグループ]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20289</guid>

					<description><![CDATA[<p>目次 はじめにキーワード解説使用するAWSサービス構築するリソース全体の作業順序【重要】⓪ 自分のIPアドレスを確認する方法A: ルーター管理画面で確認（推奨）方法B: コマンドで確認① キーペアの作成ダウンロードしたキ [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-console-ec2-apache/">AWSコンソールでEC2 + Apacheウェブサーバーを構築する手順【EC2ハンズオン / 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-6" checked><label class="toc-title" for="toc-checkbox-6">目次</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">使用するAWSサービス</a></li><li><a href="#toc4" tabindex="0">構築するリソース</a></li><li><a href="#toc5" tabindex="0">全体の作業順序</a></li><li><a href="#toc6" tabindex="0">【重要】⓪ 自分のIPアドレスを確認する</a><ol><li><a href="#toc7" tabindex="0">方法A: ルーター管理画面で確認（推奨）</a></li><li><a href="#toc8" tabindex="0">方法B: コマンドで確認</a></li></ol></li><li><a href="#toc9" tabindex="0">① キーペアの作成</a><ol><li><a href="#toc10" tabindex="0">ダウンロードしたキーペアを保存する</a></li></ol></li><li><a href="#toc11" tabindex="0">② IAMロールの作成</a><ol><li><a href="#toc12" tabindex="0">ステップ1: エンティティタイプとユースケースの選択</a></li><li><a href="#toc13" tabindex="0">ステップ2: 許可ポリシーのアタッチ</a></li><li><a href="#toc14" tabindex="0">ステップ3: ロール名の設定</a></li></ol></li><li><a href="#toc15" tabindex="0">③ EC2インスタンスの起動</a><ol><li><a href="#toc16" tabindex="0">3-1. 基本設定</a></li><li><a href="#toc17" tabindex="0">3-2. セキュリティグループの設定</a></li><li><a href="#toc18" tabindex="0">3-3. IAMロールの設定</a></li><li><a href="#toc19" tabindex="0">3-4. UserDataの設定（Apacheの自動インストール）</a></li><li><a href="#toc20" tabindex="0">3-5. インスタンスを起動する</a></li></ol></li><li><a href="#toc21" tabindex="0">④ 動作確認</a><ol><li><a href="#toc22" tabindex="0">Webブラウザで確認</a></li><li><a href="#toc23" tabindex="0">SSHで接続して確認</a></li><li><a href="#toc24" tabindex="0">【接続できない場合】IPアドレスが異なる可能性</a></li></ol></li><li><a href="#toc25" tabindex="0">⑤ リソースの削除</a><ol><li><a href="#toc26" tabindex="0">1. EC2インスタンスを終了する</a></li><li><a href="#toc27" tabindex="0">2. セキュリティグループを削除する</a></li><li><a href="#toc28" tabindex="0">3. IAMロールを削除する</a></li><li><a href="#toc29" tabindex="0">4. キーペアを削除する（任意）</a></li></ol></li><li><a href="#toc30" tabindex="0">CloudFormation版との比較</a></li><li><a href="#toc31" tabindex="0">トラブルシューティング</a></li><li><a href="#toc32" tabindex="0">まとめ</a></li><li><a href="#toc33" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「EC2インスタンスを立ち上げてWebサーバーを動かしたい」——AWSを学ぶうえで避けて通れない基本中の基本です。</p>
<p>この記事では、<strong>AWSコンソール（GUI）のみ</strong>を使って、Apacheウェブサーバーが動作するEC2インスタンスをゼロから手動で構築するハンズオンを紹介します。</p>
<pre><code class="language-plaintext">インターネット
  ↓ HTTP（ポート80）    ← ブラウザでアクセス
  ↓ SSH（ポート22）     ← ターミナルで接続
セキュリティグループ（ファイアウォール）
  ↓ 自分のIPのみ通過させる
EC2インスタンス（t2.micro / Amazon Linux 2023）
  ├── Apache httpd（UserDataで自動インストール）
  │     └── /var/www/html/index.html を返す
  └── IAMロール（Session Manager接続用）</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li>EC2インスタンスの基本操作（起動・設定・終了）</li>
<li>セキュリティグループによるポートアクセス制御（SSH:22 / HTTP:80）</li>
<li>UserData を使った初回起動時の Apache 自動インストール</li>
<li>IAMロールによる EC2 への権限付与の仕組み</li>
</ul>
<p><strong>このハンズオンの特徴：</strong></p>
<ul>
<li>キーペア・IAMロール・セキュリティグループ・EC2インスタンスを画面操作で1つずつ作成する</li>
<li>手動操作を通じて、各リソースの役割と依存関係を視覚的に理解できる</li>
</ul>
<hr>
<blockquote>
<p><strong>この記事は <a href="https://caymezon.com/aws-handson-cloudformation-ec2-apache/">CloudFormation版ハンズオン</a> の比較記事です。</strong><br />コンソール操作でEC2・Apache・セキュリティグループの連携を視覚的に学び、CloudFormationと何が違うのかを比較したい方向けです。</p>
</blockquote>
<hr>
<p><!-- ![ハンズオン完成後のWebページ表示](images/ec2-apache-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>EC2（Elastic Compute Cloud）</strong></td>
<td>AWSの仮想サーバーサービス。今回はここにApacheをインストールする</td>
</tr>
<tr>
<td><strong>Apache（httpd）</strong></td>
<td>世界で最も広く使われているWebサーバーソフト。ブラウザからのHTTPリクエストを受け取りHTMLを返す</td>
</tr>
<tr>
<td><strong>セキュリティグループ</strong></td>
<td>EC2への通信を制御するファイアウォール。ポートごとにアクセス元IPを制限できる</td>
</tr>
<tr>
<td><strong>UserData</strong></td>
<td>EC2の初回起動時のみ自動実行されるシェルスクリプト。今回はApacheのインストールに使う</td>
</tr>
<tr>
<td><strong>IAMロール</strong></td>
<td>EC2にAWSサービスを利用する権限を付与する仕組み。今回はSession Manager接続に使う</td>
</tr>
<tr>
<td><strong>キーペア</strong></td>
<td>SSHでEC2に接続するための鍵ペア（公開鍵＋秘密鍵）</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc3">使用するAWSサービス</span></h2>
<table>
<thead>
<tr>
<th>サービス</th>
<th>役割</th>
<th>料金</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>EC2</strong></td>
<td>Apacheが動作するWebサーバー本体（t2.micro）</td>
<td>月750時間まで無料枠あり</td>
</tr>
<tr>
<td><strong>セキュリティグループ</strong></td>
<td>SSH/HTTPのアクセス制御</td>
<td>無料</td>
</tr>
<tr>
<td><strong>IAM</strong></td>
<td>EC2へのSession Manager接続権限</td>
<td>無料</td>
</tr>
<tr>
<td><strong>EBS</strong></td>
<td>EC2にアタッチされるストレージ（デフォルト8GB）</td>
<td>月30GBまで無料枠あり</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>注意</strong>: 無料枠はAWSアカウント開設から12ヶ月間です。期間終了後はEC2インスタンス稼働時間に課金されます。ハンズオン後は必ずリソースを削除してください。</p>
</blockquote>
<hr>
<h2><span id="toc4">構築するリソース</span></h2>
<table>
<thead>
<tr>
<th>リソース</th>
<th>役割</th>
</tr>
</thead>
<tbody>
<tr>
<td>キーペア</td>
<td>SSHでEC2に接続するための認証鍵</td>
</tr>
<tr>
<td>IAMロール</td>
<td>EC2にSession Manager接続の権限を付与</td>
</tr>
<tr>
<td>セキュリティグループ</td>
<td>SSH(22)・HTTP(80)のアクセス制御</td>
</tr>
<tr>
<td>EC2インスタンス</td>
<td>Apacheが動作するWebサーバー本体</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc5">全体の作業順序</span></h2>
<p>依存関係があるため、必ずこの順番で作成します。</p>
<pre><code class="language-plaintext">⓪ 自分のIPアドレスを確認する（重要）
      ↓
① キーペアを作成する
      ↓
② IAMロールを作成する
      ↓
③ EC2インスタンスを起動する
  （セキュリティグループ・UserDataも同時に設定）
      ↓
④ 動作確認（Web・SSH）
      ↓
⑤ リソースを削除する</code></pre>
<hr>
<h2><span id="toc6">【重要】⓪ 自分のIPアドレスを確認する</span></h2>
<p>セキュリティグループで自分のIPだけを許可するために、<strong>正確なIPアドレス</strong>を事前に確認します。</p>
<blockquote>
<p><strong>注意</strong>: <code>curl https://checkip.amazonaws.com</code> で表示されるIPと、EC2への実際の接続元IPが<strong>一致しない場合</strong>があります（ISPやプロキシの経路の違いによる）。最も確実な方法はルーター管理画面での確認です。</p>
</blockquote>
<h3><span id="toc7">方法A: ルーター管理画面で確認（推奨）</span></h3>
<ol>
<li>ブラウザで以下のURLにアクセスします（ルーターによって異なります）
<pre><code class="language-plaintext">http://192.168.0.1  または  http://192.168.1.1</code></pre>
</li>
<li>「ネットワークマップ」または「インターネット」項目を開く</li>
<li>**「インターネットIPアドレス」または「WAN IPアドレス」**の値を控えます</li>
</ol>
<h3><span id="toc8">方法B: コマンドで確認</span></h3>
<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="toc9">① キーペアの作成</span></h2>
<p>キーペアはSSHでEC2に接続するための鍵です。EC2起動時に指定する必要があるため、最初に作成します。</p>
<p><strong>AWSコンソール → EC2 → ネットワーク＆セキュリティ → キーペア → 「キーペアを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ec2-apache-key</code></td>
</tr>
<tr>
<td>キーペアのタイプ</td>
<td><strong>RSA</strong></td>
</tr>
<tr>
<td>プライベートキーファイル形式</td>
<td><strong>.pem</strong></td>
</tr>
</tbody>
</table>
<p>「キーペアを作成」をクリックすると、自動的に <code>my-ec2-apache-key.pem</code> がダウンロードされます。</p>
<h3><span id="toc10">ダウンロードしたキーペアを保存する</span></h3>
<p>ダウンロードされた <code>my-ec2-apache-key.pem</code> を以下の場所に移動します。</p>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-apache-key.pem</code></pre>
<blockquote>
<p><strong>注意</strong>: <code>.pem</code> ファイルは<strong>再ダウンロードできません</strong>。紛失した場合は新しいキーペアを作成する必要があります。</p>
</blockquote>
<p><!-- ![キーペア作成画面](images/keypair-create.jpg) --></p>
<hr>
<h2><span id="toc11">② IAMロールの作成</span></h2>
<p>Session Manager（ブラウザからEC2に接続できるAWS機能）を使えるようにするためのIAMロールを作成します。</p>
<blockquote>
<p><strong>なぜIAMロールが必要か</strong>: EC2がAWSのサービス（Session Manager）を利用するには、そのEC2自身に「このサービスを使う権限」を付与する必要があります。この権限の設定がIAMロールです。</p>
</blockquote>
<p><strong>AWSコンソール → IAM → ロール → 「ロールを作成」</strong></p>
<h3><span id="toc12">ステップ1: エンティティタイプとユースケースの選択</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>信頼されたエンティティタイプ</td>
<td><strong>AWSのサービス</strong></td>
</tr>
<tr>
<td>ユースケース</td>
<td><strong>EC2</strong></td>
</tr>
</tbody>
</table>
<p>「次へ」をクリック。</p>
<h3><span id="toc13">ステップ2: 許可ポリシーのアタッチ</span></h3>
<p>検索ボックスに <code>AmazonSSMManagedInstanceCore</code> と入力してチェックを入れます。</p>
<p>「次へ」をクリック。</p>
<h3><span id="toc14">ステップ3: ロール名の設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>ロール名</td>
<td><code>my-ec2-apache-role</code></td>
</tr>
</tbody>
</table>
<p>「ロールを作成」をクリック。</p>
<p><!-- ![IAMロール作成画面](images/iam-role-create.jpg) --></p>
<hr>
<h2><span id="toc15">③ EC2インスタンスの起動</span></h2>
<p>キーペアとIAMロールを作成したあと、EC2インスタンスを起動します。<br />セキュリティグループとUserData（Apache自動インストール）も同時に設定します。</p>
<p><strong>AWSコンソール → EC2 → インスタンス → 「インスタンスを起動」</strong></p>
<h3><span id="toc16">3-1. 基本設定</span></h3>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ec2-apache-instance</code></td>
</tr>
<tr>
<td>アプリケーションおよびOSイメージ</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-apache-key</code></td>
</tr>
</tbody>
</table>
<p><!-- ![EC2インスタンス起動画面 - 基本設定](images/ec2-launch-basic.jpg) --></p>
<h3><span id="toc17">3-2. セキュリティグループの設定</span></h3>
<p>「ネットワーク設定」→「セキュリティグループを作成する」を選択します。</p>
<p><strong>セキュリティグループ名と説明を設定:</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>セキュリティグループ名</td>
<td><code>my-ec2-apache-sg</code></td>
</tr>
<tr>
<td>説明</td>
<td><code>EC2 Apache hands-on SG</code></td>
</tr>
</tbody>
</table>
<p><strong>「インバウンドセキュリティグループのルールを追加」ボタンで以下の2ルールを追加します。</strong></p>
<p><strong>ルール1: SSH接続の許可</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>203.0.113.1/32</code>（⓪で確認した自分のIP + /32）</td>
</tr>
</tbody>
</table>
<p><strong>ルール2: HTTPアクセスの許可</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>タイプ</td>
<td>HTTP</td>
</tr>
<tr>
<td>ソースタイプ</td>
<td>カスタム</td>
</tr>
<tr>
<td>ソース</td>
<td><code>203.0.113.1/32</code>（⓪で確認した自分のIP + /32）</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>/32 とは</strong>: 「このIPアドレス1つだけ」という意味のCIDR表記です。<code>0.0.0.0/0</code> は全世界に開放することになりセキュリティリスクが高いため、必ず自分のIPのみに制限します。</p>
</blockquote>
<p><!-- ![セキュリティグループ設定画面](images/security-group-create.jpg) --></p>
<h3><span id="toc18">3-3. IAMロールの設定</span></h3>
<p>「高度な詳細」を開く → 「IAM インスタンスプロファイル」→ <code>my-ec2-apache-role</code> を選択します。</p>
<h3><span id="toc19">3-4. UserDataの設定（Apacheの自動インストール）</span></h3>
<p>「高度な詳細」の一番下にある「ユーザーデータ」に以下を貼り付けます。</p>
<pre><code class="language-bash">#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "&lt;h1&gt;Hello from Amazon Linux 2023!&lt;/h1&gt;" &gt; /var/www/html/index.html
echo "&lt;p&gt;Instance ID: $(ec2-metadata --instance-id | cut -d ' ' -f 2)&lt;/p&gt;" &gt;&gt; /var/www/html/index.html
echo "&lt;p&gt;Availability Zone: $(ec2-metadata --availability-zone | cut -d ' ' -f 2)&lt;/p&gt;" &gt;&gt; /var/www/html/index.html</code></pre>
<p><strong>各コマンドの説明:</strong></p>
<table>
<thead>
<tr>
<th>コマンド</th>
<th>意味</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>yum update -y</code></td>
<td>OSのパッケージを最新化する</td>
</tr>
<tr>
<td><code>yum install -y httpd</code></td>
<td>Apache（httpd）をインストールする</td>
</tr>
<tr>
<td><code>systemctl start httpd</code></td>
<td>Apacheを起動する</td>
</tr>
<tr>
<td><code>systemctl enable httpd</code></td>
<td>OS起動時にApacheが自動起動するよう設定する</td>
</tr>
<tr>
<td><code>echo &quot;...&quot; &gt; /var/www/html/index.html</code></td>
<td>Apacheが返すテスト用HTMLを作成する</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>UserDataとは</strong>: インスタンスの<strong>初回起動時のみ</strong>自動実行されるシェルスクリプトです。この仕組みを使うことで、EC2起動と同時にApacheのインストールまで自動化できます。</p>
</blockquote>
<h3><span id="toc20">3-5. インスタンスを起動する</span></h3>
<p>「インスタンスを起動」ボタンをクリック。</p>
<p>起動完了まで約2〜3分待ちます。インスタンスの「状態」が「実行中」になったことを確認します。</p>
<p><strong>控えておく情報: インスタンスのパブリックIPアドレス</strong></p>
<p>インスタンス一覧 → 作成したインスタンスをクリック → 「パブリック IPv4 アドレス」を確認してメモします。</p>
<p><!-- ![EC2インスタンス起動後の画面](images/ec2-running.jpg) --></p>
<hr>
<h2><span id="toc21">④ 動作確認</span></h2>
<h3><span id="toc22">Webブラウザで確認</span></h3>
<p>ブラウザで以下のURLにアクセスします。</p>
<pre><code class="language-plaintext">http://（パブリックIPアドレス）</code></pre>
<p>以下のように表示されれば成功です。</p>
<pre><code class="language-plaintext">Hello from Amazon Linux 2023!
Instance ID: i-0123456789abcdef0
Availability Zone: ap-northeast-1a</code></pre>
<blockquote>
<p><strong>表示されない場合</strong>: UserDataのApacheインストールが完了するまで2〜3分かかります。少し待ってからリロードしてください。</p>
</blockquote>
<p><!-- ![ブラウザでのWebページ確認](images/apache-web-browser.jpg) --></p>
<h3><span id="toc23">SSHで接続して確認</span></h3>
<p>ローカルPCのターミナル（VSCode CMD）で実行します。</p>
<pre><code class="language-cmd">ssh -i C:\Users\ユーザー名\.ssh\my-ec2-apache-key.pem ec2-user@（パブリックIPアドレス）</code></pre>
<p>初回接続時に以下の確認が出ます。<code>yes</code> を入力します。</p>
<pre><code class="language-plaintext">Are you sure you want to continue connecting (yes/no)? yes</code></pre>
<p>接続成功するとAmazon Linux 2023のプロンプトが表示されます。以下で動作確認をします。</p>
<pre><code class="language-bash">sudo systemctl status httpd

# Apacheが返しているHTMLファイルを確認
cat /var/www/html/index.html

# ApacheのドキュメントルートをApacheの設定ファイルで確認
cat /etc/httpd/conf/httpd.conf | grep DocumentRoot

# EC2から切断
exit</code></pre>
<p><strong>Apacheのディレクトリ構成:</strong></p>
<table>
<thead>
<tr>
<th>パス</th>
<th>役割</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>/var/www/html/</code></td>
<td>Webコンテンツの置き場所（ドキュメントルート）</td>
</tr>
<tr>
<td><code>/etc/httpd/conf/httpd.conf</code></td>
<td>Apacheのメイン設定ファイル</td>
</tr>
<tr>
<td><code>/var/log/httpd/access_log</code></td>
<td>Apacheアクセスログ</td>
</tr>
<tr>
<td><code>/var/log/httpd/error_log</code></td>
<td>Apacheエラーログ</td>
</tr>
</tbody>
</table>
<p><!-- ![SSH接続後のApache動作確認](images/ssh-apache-status.jpg) --></p>
<h3><span id="toc24">【接続できない場合】IPアドレスが異なる可能性</span></h3>
<p><code>curl</code> で確認したIPを設定したが接続できない場合、実際の接続元IPが異なる可能性があります。</p>
<p><strong>一時的に全開放して真のIPを確認する方法:</strong></p>
<p>コンソール → EC2 → セキュリティグループ → <code>my-ec2-apache-sg</code> → 「インバウンドルールを編集」</p>
<p>SSHのルールを一時的に <code>0.0.0.0/0</code> に変更してSSH接続し、以下を実行します。</p>
<pre><code class="language-bash">echo $SSH_CLIENT
# 出力例: 203.0.113.1 17508 22
# 先頭の値が真の接続元IP</code></pre>
<p>このIPをメモしてSSH接続を切断し、セキュリティグループのSSHルールを <code>真のIP/32</code> に戻します。</p>
<hr>
<h2><span id="toc25">⑤ リソースの削除</span></h2>
<p><strong>課金を止めるために、ハンズオン完了後は必ず削除してください。削除する順番が重要です。</strong></p>
<h3><span id="toc26">1. EC2インスタンスを終了する</span></h3>
<p><strong>EC2 → インスタンス → <code>my-ec2-apache-instance</code> を選択 → 「インスタンスの状態」→「インスタンスを終了」</strong></p>
<p>確認ダイアログで「終了」をクリック。状態が「終了済み」になるまで待ちます（2〜5分）。</p>
<blockquote>
<p><strong>「停止」と「終了」の違い</strong>: 「停止」は一時停止（EBSストレージ課金は続く）。「終了」は完全削除（課金停止）。学習後は「終了」を選びます。</p>
</blockquote>
<h3><span id="toc27">2. セキュリティグループを削除する</span></h3>
<p><strong>EC2 → セキュリティグループ → <code>my-ec2-apache-sg</code> を選択 → 「アクション」→「セキュリティグループを削除」</strong></p>
<blockquote>
<p>インスタンス終了が完了している必要があります。「使用中」エラーが出る場合はインスタンスが「終了済み」状態になるまで待ってください。</p>
</blockquote>
<h3><span id="toc28">3. IAMロールを削除する</span></h3>
<p><strong>IAM → ロール → <code>my-ec2-apache-role</code> を選択 → 「削除」→ ロール名を入力して確認</strong></p>
<h3><span id="toc29">4. キーペアを削除する（任意）</span></h3>
<p>他のEC2でも使い回す場合は残してよいです。不要な場合は削除します。</p>
<p><strong>EC2 → キーペア → <code>my-ec2-apache-key</code> を選択 → 「アクション」→「削除」→ 確認テキストを入力</strong></p>
<p>ローカルの <code>.pem</code> ファイルも手動で削除します。</p>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-apache-key.pem</code></pre>
<hr>
<h2><span id="toc30">CloudFormation版との比較</span></h2>
<p>コンソール版を体験したら、次は同じ構成を CloudFormation（コード）で再現してみましょう。何が自動化されるのかがよくわかります。</p>
<table>
<thead>
<tr>
<th>作業</th>
<th>コンソール（手動）</th>
<th>CloudFormation</th>
</tr>
</thead>
<tbody>
<tr>
<td>IAMロール作成</td>
<td>画面でポチポチ（5クリック以上）</td>
<td>template.yaml に定義済み</td>
</tr>
<tr>
<td>セキュリティグループ作成</td>
<td>画面でポチポチ</td>
<td>template.yaml に定義済み</td>
</tr>
<tr>
<td>EC2起動（UserData含む）</td>
<td>画面でポチポチ</td>
<td>template.yaml に定義済み</td>
</tr>
<tr>
<td>デプロイ全体</td>
<td>複数画面を行き来（15〜20分）</td>
<td>コマンド1本（5分）</td>
</tr>
<tr>
<td>削除</td>
<td>リソースを個別に依存関係順で手動削除</td>
<td><code>delete-stack</code> 1本</td>
</tr>
<tr>
<td>再現性</td>
<td>低い（手動ミスのリスクがある）</td>
<td>高い（同じ環境を何度でも再現可能）</td>
</tr>
<tr>
<td>バージョン管理</td>
<td>不可</td>
<td>Gitで管理可能</td>
</tr>
</tbody>
</table>
<p><strong>コンソール版で実感できたポイント:</strong></p>
<ul>
<li>キーペア・IAMロール・セキュリティグループ・EC2の依存関係が視覚的に理解できる</li>
<li>セキュリティグループのインバウンドルールを手動設定することで、ポートとCIDRの意味が身につく</li>
<li>UserData の仕組みを実際に設定することで、EC2の初期化フローが理解できる</li>
</ul>
<p><strong>CloudFormation版でも試してみる</strong>: <a href="https://caymezon.com/aws-handson-cloudformation-ec2-apache/">AWS CloudFormationでEC2 + ApacheウェブサーバーをIaC化しよう</a></p>
<hr>
<h2><span id="toc31">トラブルシューティング</span></h2>
<table>
<thead>
<tr>
<th>症状</th>
<th>原因</th>
<th>対処</th>
</tr>
</thead>
<tbody>
<tr>
<td>Webページが表示されない（起動直後）</td>
<td>UserDataのApacheインストールが未完了</td>
<td>2〜3分待ってからリロード</td>
</tr>
<tr>
<td>SSH接続タイムアウト</td>
<td>セキュリティグループのIP設定誤り</td>
<td>⓪のIP確認方法で真のIPを再確認</td>
</tr>
<tr>
<td>SSHエラー「WARNING: UNPROTECTED PRIVATE KEY FILE!」</td>
<td>.pemファイルの権限が広すぎる（Linux/Mac）</td>
<td><code>chmod 400 ~/.ssh/my-ec2-apache-key.pem</code> を実行</td>
</tr>
<tr>
<td>セキュリティグループが削除できない</td>
<td>EC2インスタンスがまだ使用中</td>
<td>インスタンス「終了済み」状態になってから再試行</td>
</tr>
<tr>
<td>Apacheは起動しているのにページが見えない</td>
<td>セキュリティグループのHTTP(80)設定ミス</td>
<td>SGのインバウンドルールでHTTP:80が追加されているか確認</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc32">まとめ</span></h2>
<p>今回のハンズオンで体験できたこと：</p>
<table>
<thead>
<tr>
<th>確認項目</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>キーペア作成</strong></td>
<td>SSH接続に必要な鍵ペアをコンソールで作成し、.pemファイルをローカルに保存</td>
</tr>
<tr>
<td><strong>IAMロール作成</strong></td>
<td>AmazonSSMManagedInstanceCoreポリシーをEC2にアタッチして接続権限を付与</td>
</tr>
<tr>
<td><strong>セキュリティグループ</strong></td>
<td>SSH(22)/HTTP(80)を自分のIPのみに制限してEC2を保護</td>
</tr>
<tr>
<td><strong>UserDataによる自動化</strong></td>
<td>Apacheのインストールと起動を初回起動時のスクリプトで自動化</td>
</tr>
<tr>
<td><strong>Webサーバー確認</strong></td>
<td>ブラウザとSSHの両方でApache動作を確認</td>
</tr>
<tr>
<td><strong>リソース削除</strong></td>
<td>依存関係順に4つのリソースを手動で削除</td>
</tr>
</tbody>
</table>
<p>手動操作でひとつひとつ作ると、CloudFormationが裏で何を自動化しているかが理解できます。ぜひ次は <a href="https://caymezon.com/aws-handson-cloudformation-ec2-apache/">CloudFormation版</a> で同じ構成をコードで再現してみてください。</p>
<hr>
<h2><span id="toc33">関連記事</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-apache/">AWSコンソールでEC2 + Apacheウェブサーバーを構築する手順【EC2ハンズオン / 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-apache/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AWS CloudFormationでEC2 + ApacheウェブサーバーをIaC化しよう【EC2ハンズオン / コンソール版との比較付き】</title>
		<link>https://caymezon.com/aws-handson-cloudformation-ec2-apache/</link>
					<comments>https://caymezon.com/aws-handson-cloudformation-ec2-apache/#respond</comments>
		
		<dc:creator><![CDATA[caymezon]]></dc:creator>
		<pubDate>Mon, 23 Mar 2026 08:38:50 +0000</pubDate>
				<category><![CDATA[AWS Basic]]></category>
		<category><![CDATA[Cloud & Infra]]></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[IAM]]></category>
		<category><![CDATA[UserData]]></category>
		<category><![CDATA[Webサーバー]]></category>
		<category><![CDATA[セキュリティグループ]]></category>
		<category><![CDATA[ハンズオン]]></category>
		<category><![CDATA[初心者]]></category>
		<guid isPermaLink="false">https://caymezon.com/?p=20287</guid>

					<description><![CDATA[<p>目次 はじめにCloudFormation vs コンソール：どれだけ違うかキーワード解説前提条件template.yaml の全文作業順序【重要】⓪ 自分のIPアドレスを確認する方法A: ルーター管理画面で確認（推奨） [&#8230;]</p>
<p>The post <a href="https://caymezon.com/aws-handson-cloudformation-ec2-apache/">AWS CloudFormationでEC2 + ApacheウェブサーバーをIaC化しよう【EC2ハンズオン / コンソール版との比較付き】</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-8" checked><label class="toc-title" for="toc-checkbox-8">目次</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></li><li><a href="#toc6" tabindex="0">作業順序</a></li><li><a href="#toc7" tabindex="0">【重要】⓪ 自分のIPアドレスを確認する</a><ol><li><a href="#toc8" tabindex="0">方法A: ルーター管理画面で確認（推奨）</a></li><li><a href="#toc9" tabindex="0">方法B: コマンドで確認</a></li></ol></li><li><a href="#toc10" tabindex="0">① キーペアの作成（コンソールで実施）</a></li><li><a href="#toc11" tabindex="0">② プロジェクトフォルダに移動する</a></li><li><a href="#toc12" tabindex="0">③ スタックの作成</a></li><li><a href="#toc13" tabindex="0">④ 作成完了・Outputsの確認</a><ol><li><a href="#toc14" tabindex="0">作成状況の確認</a></li><li><a href="#toc15" tabindex="0">Outputs（接続情報）の確認</a></li></ol></li><li><a href="#toc16" tabindex="0">⑤ 動作確認</a><ol><li><a href="#toc17" tabindex="0">Webブラウザで確認</a></li><li><a href="#toc18" tabindex="0">SSHで接続して確認</a></li><li><a href="#toc19" tabindex="0">【接続できない場合】真のIPアドレスを確認する</a></li></ol></li><li><a href="#toc20" tabindex="0">⑥ スタックの削除</a></li><li><a href="#toc21" tabindex="0">コンソール版との比較</a></li><li><a href="#toc22" tabindex="0">トラブルシューティング</a></li><li><a href="#toc23" tabindex="0">まとめ</a><ol><li><a href="#toc24" tabindex="0">CloudFormationのメリットを実感できたポイント</a></li></ol></li><li><a href="#toc25" tabindex="0">コンソール版と比較してみる</a></li><li><a href="#toc26" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2><span id="toc1">はじめに</span></h2>
<p>「コンソールで手動構築できた構成を、コードで再現したい」——それを実現するのが <strong>AWS CloudFormation</strong> です。</p>
<p>この記事では、<code>template.yaml</code> 1ファイルにリソース構成を定義し、<strong>コマンド1本でEC2 + Apache環境を一括構築するハンズオン</strong>を紹介します。コンソール版（<a href="#">AWSコンソール版ハンズオン</a>）と全く同じ構成を、CloudFormationで自動化します。</p>
<pre><code class="language-plaintext">ローカル環境（VSCode）
  ├── template.yaml（CloudFormationテンプレート）
  └── AWS CLI コマンド
        ↓ スタック作成（コマンド1本）
AWS環境
  ├── IAMロール（SSM接続用）         ← template.yamlで定義
  ├── セキュリティグループ（SSH22・HTTP80）← template.yamlで定義
  └── EC2インスタンス（t2.micro / Amazon Linux 2023 + Apache）← template.yamlで定義</code></pre>
<p><strong>このハンズオンで体験できること：</strong></p>
<ul>
<li><code>template.yaml</code> へのリソース定義（IAMロール・セキュリティグループ・EC2インスタンス）</li>
<li><code>!Ref</code> / <code>!Sub</code> / <code>!GetAtt</code> を使ったリソース間参照</li>
<li><code>aws cloudformation create-stack</code> コマンド1本での全リソース一括デプロイ</li>
<li><code>aws cloudformation delete-stack</code> コマンド1本での全リソース一括削除</li>
</ul>
<p><strong>このハンズオンの特徴：</strong></p>
<ul>
<li>コンソール版では15〜20分かかった手動作業が、コマンド1本（約5分）で完了する</li>
<li><code>delete-stack</code> 1本で依存関係を考慮した順番で全リソースを自動削除できる</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>IAMロール作成</strong></td>
<td><code>--parameters</code> で値を渡すだけ</td>
<td>画面でポチポチ（5クリック以上）</td>
</tr>
<tr>
<td><strong>セキュリティグループ作成</strong></td>
<td>同上</td>
<td>画面でポチポチ</td>
</tr>
<tr>
<td><strong>EC2起動（UserData含む）</strong></td>
<td>同上</td>
<td>画面でポチポチ</td>
</tr>
<tr>
<td><strong>全リソースのデプロイ</strong></td>
<td>コマンド1本（3〜5分）</td>
<td>複数画面を行き来（15〜20分）</td>
</tr>
<tr>
<td><strong>リソース削除</strong></td>
<td><code>delete-stack</code> 1本</td>
<td>依存関係順に個別削除（4ステップ）</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）サービス。YAMLテンプレートでリソースをコード化する</td>
</tr>
<tr>
<td><strong>スタック</strong></td>
<td>CloudFormationが管理するリソースのまとまり。作成・削除・更新をまとめて操作できる</td>
</tr>
<tr>
<td><strong><code>!Ref</code></strong></td>
<td>CloudFormation組み込み関数。パラメータの値やリソースのIDを参照する</td>
</tr>
<tr>
<td><strong><code>!Sub</code></strong></td>
<td>CloudFormation組み込み関数。文字列内の <code>${変数}</code> を展開する</td>
</tr>
<tr>
<td><strong><code>!GetAtt</code></strong></td>
<td>CloudFormation組み込み関数。リソースの属性値（ARNなど）を取得する</td>
</tr>
<tr>
<td><strong>CAPABILITY_NAMED_IAM</strong></td>
<td>名前付きIAMリソースを作成する場合に必要な明示的な許可フラグ</td>
</tr>
<tr>
<td><strong>UserData</strong></td>
<td>EC2の初回起動時のみ自動実行されるシェルスクリプト</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>
<p>アカウントIDが表示されれば認証設定済みです。</p>
<hr>
<h2><span id="toc5">template.yaml の全文</span></h2>
<p>以下が今回使用する <code>template.yaml</code> の全文です。プロジェクトフォルダ（<code>ec2-apache-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 + Apache Web Server Hands-on (Phase 1-1)'

Parameters:
  KeyName:
    Type: String
    Default: 'my-ec2-apache-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:
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: 'my-ec2-apache-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-apache-role'

  # Instance Profile: wrapper that attaches the IAM role to EC2
  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: 'my-ec2-apache-profile'
      Roles:
        - !Ref EC2Role

  # Security Group: allow SSH(22) and HTTP(80) from MyIP only
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: 'my EC2 Apache hands-on SG'
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP
          Description: SSH access from my IP
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP
          Description: HTTP access from my IP
      Tags:
        - Key: Name
          Value: 'my-ec2-apache-sg'

  # EC2 Instance: Amazon Linux 2023 + Apache (installed via UserData)
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      # Automatically fetches the latest Amazon Linux 2023 AMI ID from SSM Parameter Store
      ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'
      InstanceType: t2.micro
      KeyName: !Ref KeyName
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      IamInstanceProfile: !Ref EC2InstanceProfile
      # UserData: shell script executed automatically on first boot
      UserData:
        Fn::Base64: |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "&lt;h1&gt;Hello from Amazon Linux 2023!&lt;/h1&gt;" &gt; /var/www/html/index.html
          echo "&lt;p&gt;Instance ID: $(ec2-metadata --instance-id | cut -d ' ' -f 2)&lt;/p&gt;" &gt;&gt; /var/www/html/index.html
          echo "&lt;p&gt;Availability Zone: $(ec2-metadata --availability-zone | cut -d ' ' -f 2)&lt;/p&gt;" &gt;&gt; /var/www/html/index.html
      Tags:
        - Key: Name
          Value: 'my-ec2-apache-instance'

Outputs:
  InstanceId:
    Description: EC2 Instance ID
    Value: !Ref EC2Instance

  PublicIP:
    Description: Public IP Address
    Value: !GetAtt EC2Instance.PublicIp

  WebsiteURL:
    Description: Website URL (open in browser)
    Value: !Sub 'http://${EC2Instance.PublicIp}'

  SSHCommand:
    Description: SSH command (update the .pem path as needed)
    Value: !Sub 'ssh -i C:\Users\username\.ssh\${KeyName}.pem ec2-user@${EC2Instance.PublicIp}'</code></pre>
<p><strong><code>!Ref</code> と <code>!Sub</code> の使い分け:</strong></p>
<table>
<thead>
<tr>
<th>関数</th>
<th>意味</th>
<th>例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>!Ref パラメータ名</code></td>
<td>パラメータの値を参照する</td>
<td><code>!Ref MyIP</code> → <code>203.0.113.1/32</code></td>
</tr>
<tr>
<td><code>!Ref リソースID</code></td>
<td>リソースのIDを参照する</td>
<td><code>!Ref EC2SecurityGroup</code> → <code>sg-xxxxx</code></td>
</tr>
<tr>
<td><code>!Sub &#39;文字列&#39;</code></td>
<td>文字列内の <code>${変数}</code> を展開する</td>
<td><code>!Sub &#39;http://${EC2Instance.PublicIp}&#39;</code> → <code>http://x.x.x.x</code></td>
</tr>
<tr>
<td><code>!GetAtt リソース.属性</code></td>
<td>リソースの属性値を取得する</td>
<td><code>!GetAtt EC2Instance.PublicIp</code> → IPアドレス</td>
</tr>
</tbody>
</table>
<p><strong>構築されるリソースと論理ID:</strong></p>
<table>
<thead>
<tr>
<th>リソース</th>
<th>template.yaml上の論理ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>IAMロール</td>
<td><code>EC2Role</code></td>
</tr>
<tr>
<td>インスタンスプロファイル</td>
<td><code>EC2InstanceProfile</code></td>
</tr>
<tr>
<td>セキュリティグループ</td>
<td><code>EC2SecurityGroup</code></td>
</tr>
<tr>
<td>EC2インスタンス</td>
<td><code>EC2Instance</code></td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc6">作業順序</span></h2>
<pre><code class="language-plaintext">⓪ 自分のIPアドレスを確認する（重要）
      ↓
① キーペアを作成する（コンソールで実施）
      ↓
② プロジェクトフォルダに移動する
      ↓
③ スタックを作成する（aws cloudformation create-stack）
      ↓
④ 作成状況・Outputsを確認する
      ↓
⑤ 動作確認（Web・SSH）
      ↓
⑥ スタックを削除する（aws cloudformation delete-stack）</code></pre>
<hr>
<h2><span id="toc7">【重要】⓪ 自分のIPアドレスを確認する</span></h2>
<p>セキュリティグループで自分のIPのみを許可するために、<strong>正確なIPアドレス</strong>を事前に確認します。</p>
<blockquote>
<p><strong>注意</strong>: <code>curl https://checkip.amazonaws.com</code> で表示されるIPと、EC2への実際の接続元IPが<strong>一致しない場合</strong>があります（ISPやプロキシの経路の違いによる）。</p>
</blockquote>
<h3><span id="toc8">方法A: ルーター管理画面で確認（推奨）</span></h3>
<ol>
<li>ブラウザで以下のURLにアクセスします
<pre><code class="language-plaintext">http://192.168.0.1  または  http://192.168.1.1</code></pre>
</li>
<li>「ネットワークマップ」または「インターネット」項目を開く</li>
<li>**「インターネットIPアドレス」または「WAN IPアドレス」**の値を控えます</li>
</ol>
<h3><span id="toc9">方法B: コマンドで確認</span></h3>
<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="toc10">① キーペアの作成（コンソールで実施）</span></h2>
<p>キーペアのみコンソールで作成します。CloudFormationではキーペアのダウンロードが行えないためです。</p>
<p><strong>AWSコンソール → EC2 → キーペア → 「キーペアを作成」</strong></p>
<table>
<thead>
<tr>
<th>設定項目</th>
<th>値</th>
</tr>
</thead>
<tbody>
<tr>
<td>名前</td>
<td><code>my-ec2-apache-key</code></td>
</tr>
<tr>
<td>キーペアのタイプ</td>
<td><strong>RSA</strong></td>
</tr>
<tr>
<td>プライベートキーファイル形式</td>
<td><strong>.pem</strong></td>
</tr>
</tbody>
</table>
<p>ダウンロードされた <code>my-ec2-apache-key.pem</code> を保存します。</p>
<pre><code class="language-plaintext">C:\Users\ユーザー名\.ssh\my-ec2-apache-key.pem</code></pre>
<hr>
<h2><span id="toc11">② プロジェクトフォルダに移動する</span></h2>
<p>VSCodeのターミナル（CMD）を開き、プロジェクトフォルダに移動します。</p>
<pre><code class="language-cmd">cd C:\my-aws\aws-learning-projects\ec2-apache-web</code></pre>
<p><code>template.yaml</code> があることを確認します。</p>
<pre><code class="language-cmd">dir template.yaml</code></pre>
<hr>
<h2><span id="toc12">③ スタックの作成</span></h2>
<p>以下のコマンドを実行します。<code>203.0.113.1</code> は⓪で確認した自分のIPアドレスに置き換えてください。</p>
<pre><code class="language-cmd">aws cloudformation create-stack ^
  --stack-name my-ec2-apache-stack ^
  --template-body file://template.yaml ^
  --region ap-northeast-1 ^
  --capabilities CAPABILITY_NAMED_IAM ^
  --parameters ^
    ParameterKey=KeyName,ParameterValue=my-ec2-apache-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-apache-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>
<blockquote>
<p><strong><code>^</code> について</strong>: Windowsのコマンドプロンプトで長いコマンドを複数行に分けるための改行エスケープ文字です。1行で書いても動作します。</p>
</blockquote>
<p>成功すると以下のようなStackIdが表示されます。</p>
<pre><code class="language-json">{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/my-ec2-apache-stack/xxxxx"
}</code></pre>
<p><!-- ![スタック作成コマンドの実行結果](images/cfn-create-stack-cmd.jpg) --></p>
<hr>
<h2><span id="toc13">④ 作成完了・Outputsの確認</span></h2>
<p>スタック作成は完了まで<strong>約3〜5分</strong>かかります。</p>
<h3><span id="toc14">作成状況の確認</span></h3>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-apache-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="toc15">Outputs（接続情報）の確認</span></h3>
<p><code>CREATE_COMPLETE</code> になったら以下を実行します。</p>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-apache-stack ^
  --query "Stacks[0].Outputs" ^
  --output table</code></pre>
<p>以下のような出力が表示されます。</p>
<pre><code class="language-plaintext">------------------------------------------------------------------------------------
|                              DescribeStacks                                      |
+----------------+-----------------------------------------------------------------+
|  OutputKey     |  OutputValue                                                    |
+----------------+-----------------------------------------------------------------+
|  InstanceId    |  i-0123456789abcdef0                                           |
|  PublicIP      |  x.x.x.x                                                       |
|  WebsiteURL    |  http://x.x.x.x                                                |
|  SSHCommand    |  ssh -i C:\Users\...\.ssh\my-ec2-apache-key.pem ec2-user@x.x.x.x |
+----------------+-----------------------------------------------------------------+</code></pre>
<p><strong>控えておく情報</strong>: <code>PublicIP</code> と <code>WebsiteURL</code></p>
<p><!-- ![Outputs確認コマンドの実行結果](images/cfn-outputs-table.jpg) --></p>
<hr>
<h2><span id="toc16">⑤ 動作確認</span></h2>
<h3><span id="toc17">Webブラウザで確認</span></h3>
<p>Outputsに表示された <code>WebsiteURL</code>（<code>http://x.x.x.x</code>）をブラウザで開きます。</p>
<pre><code class="language-plaintext">Hello from Amazon Linux 2023!
Instance ID: i-0123456789abcdef0
Availability Zone: ap-northeast-1a</code></pre>
<p>が表示されれば成功です。</p>
<blockquote>
<p><strong>表示されない場合</strong>: UserDataのApacheインストールが完了するまで2〜3分かかります。少し待ってからリロードしてください。</p>
</blockquote>
<p><!-- ![ブラウザでのWebページ確認](images/apache-web-browser.jpg) --></p>
<h3><span id="toc18">SSHで接続して確認</span></h3>
<p>Outputsに表示された <code>SSHCommand</code> のコマンドを実行します（パスは実際のパスに修正します）。</p>
<pre><code class="language-cmd">ssh -i C:\Users\ユーザー名\.ssh\my-ec2-apache-key.pem ec2-user@（PublicIP）</code></pre>
<p>初回接続時の確認には <code>yes</code> を入力します。</p>
<pre><code class="language-bash"># Apacheの動作状態を確認（active (running) と表示されれば正常）
sudo systemctl status httpd

# ApacheのHTMLファイルを確認
cat /var/www/html/index.html

# EC2から切断
exit</code></pre>
<h3><span id="toc19">【接続できない場合】真のIPアドレスを確認する</span></h3>
<p><code>curl</code> で確認したIPを設定したが接続できない場合、実際の接続元IPが異なる可能性があります。</p>
<p><strong>セキュリティグループIDを取得:</strong></p>
<pre><code class="language-cmd">aws cloudformation describe-stack-resources ^
  --stack-name my-ec2-apache-stack ^
  --query "StackResources[?ResourceType=='AWS::EC2::SecurityGroup'].PhysicalResourceId" ^
  --output text</code></pre>
<p><strong>SSH全開放（一時的・テスト用）:</strong></p>
<pre><code class="language-cmd">aws ec2 authorize-security-group-ingress ^
  --group-id sg-XXXXXXXXX ^
  --protocol tcp ^
  --port 22 ^
  --cidr 0.0.0.0/0 ^
  --region ap-northeast-1</code></pre>
<p>SSH接続して真のIPを確認します。</p>
<pre><code class="language-bash">echo $SSH_CLIENT
# 出力例: 203.0.113.1 17508 22
# 先頭の値が真の接続元IP
exit</code></pre>
<p>確認後、全開放を削除して真のIPで制限し直します。</p>
<pre><code class="language-cmd">rem 全開放を削除
aws ec2 revoke-security-group-ingress ^
  --group-id sg-XXXXXXXXX ^
  --protocol tcp ^
  --port 22 ^
  --cidr 0.0.0.0/0 ^
  --region ap-northeast-1

rem 真のIPで再制限
aws ec2 authorize-security-group-ingress ^
  --group-id sg-XXXXXXXXX ^
  --protocol tcp ^
  --port 22 ^
  --cidr 真のIP/32 ^
  --region ap-northeast-1</code></pre>
<hr>
<h2><span id="toc20">⑥ スタックの削除</span></h2>
<p><strong>課金を止めるために、ハンズオン完了後は必ず削除してください。</strong></p>
<p>CloudFormationはスタック削除で全リソースを一括削除できます。手動でリソースを1つ1つ削除する必要はありません。</p>
<pre><code class="language-cmd">aws cloudformation delete-stack ^
  --stack-name my-ec2-apache-stack ^
  --region ap-northeast-1</code></pre>
<p>削除の進行状況を確認します（完了まで約3〜5分）。</p>
<pre><code class="language-cmd">aws cloudformation describe-stacks ^
  --stack-name my-ec2-apache-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-apache-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-apache-stack does not exist</code></pre>
<p>このメッセージが表示されれば削除完了です。キーペアはCloudFormationで管理していないため、手動で削除します。</p>
<p><strong>EC2 → キーペア → <code>my-ec2-apache-key</code> を選択 → 「アクション」→「削除」</strong></p>
<p>ローカルの <code>.pem</code> ファイルも削除します。</p>
<hr>
<h2><span id="toc21">コンソール版との比較</span></h2>
<p>コンソール版でIAMロール・セキュリティグループ・EC2を手動作成した手順が、CloudFormationではすべて <code>template.yaml</code> に定義されています。</p>
<table>
<thead>
<tr>
<th>SAM/CFnの記述</th>
<th>コンソールでやること</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>EC2Role</code>（IAMロール定義）</td>
<td>IAM → ロールを作成（AmazonSSMManagedInstanceCore付与）</td>
</tr>
<tr>
<td><code>EC2SecurityGroup</code>（SGルール定義）</td>
<td>EC2 → セキュリティグループを作成（SSH/HTTP各ルール追加）</td>
</tr>
<tr>
<td><code>EC2Instance</code>（UserData含む）</td>
<td>EC2 → インスタンスを起動（UserData貼り付け・キーペア選択）</td>
</tr>
<tr>
<td><code>--parameters MyIP=...</code></td>
<td>セキュリティグループのインバウンドルールに自分のIPを入力</td>
</tr>
<tr>
<td><code>delete-stack</code></td>
<td>インスタンス終了 → SG削除 → IAMロール削除（順番が重要）</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>コンソール版で詰まりやすいポイント:</strong><br />セキュリティグループ削除時に「使用中」エラーが出るのは、EC2インスタンスが「終了済み」になっていないためです。<br />CloudFormationなら削除順序を自動で解決してくれるので、このエラーは発生しません。</p>
</blockquote>
<hr>
<h2><span id="toc22">トラブルシューティング</span></h2>
<table>
<thead>
<tr>
<th>症状</th>
<th>原因</th>
<th>対処</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>CREATE_FAILED</code> になる</td>
<td>キーペアが存在しない</td>
<td>コンソールでキーペアを作成し、<code>--parameters KeyName=...</code> の値を確認</td>
</tr>
<tr>
<td><code>CREATE_FAILED</code> になる</td>
<td><code>CAPABILITY_NAMED_IAM</code> が不足</td>
<td>コマンドに <code>--capabilities CAPABILITY_NAMED_IAM</code> が含まれているか確認</td>
</tr>
<tr>
<td><code>stackName failed to satisfy regular expression pattern</code></td>
<td>スタック名が数字始まり</td>
<td>CloudFormationのスタック名は<strong>英字で始まる</strong>必要がある</td>
</tr>
<tr>
<td><code>Unable to load paramfile, text contents could not be decoded</code></td>
<td>template.yaml に日本語が含まれている</td>
<td>template.yaml のコメント・説明文を<strong>すべて英語</strong>で記述する（Windows環境の既知の問題）</td>
</tr>
<tr>
<td>SSH接続タイムアウト</td>
<td>セキュリティグループのIP設定誤り</td>
<td>「真のIPアドレスを確認する」手順を実行</td>
</tr>
<tr>
<td>Webページが表示されない（起動直後）</td>
<td>ApacheのUserDataが未完了</td>
<td>2〜3分待ってからリロード</td>
</tr>
<tr>
<td><code>DELETE_FAILED</code> になる</td>
<td>手動でリソースを変更したためCFnが管理できない</td>
<td>コンソールで該当リソースを確認して手動削除後、<code>delete-stack</code> を再実行</td>
</tr>
<tr>
<td><code>ValidationError: Template format error</code></td>
<td>template.yamlのインデントが崩れている</td>
<td>YAMLはインデントが厳格。スペース2つ単位でインデントを確認する</td>
</tr>
</tbody>
</table>
<hr>
<h2><span id="toc23">まとめ</span></h2>
<p>今回のハンズオンで実現できたこと：</p>
<table>
<thead>
<tr>
<th>確認項目</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>IaCの体験</strong></td>
<td>template.yaml 1ファイルにIAMロール・SG・EC2をコードで定義</td>
</tr>
<tr>
<td><strong>一括デプロイ</strong></td>
<td><code>create-stack</code> コマンド1本でコンソール版と同じ構成を5分で構築</td>
</tr>
<tr>
<td><strong>Outputs活用</strong></td>
<td>デプロイ後にIPアドレス・SSHコマンドを <code>describe-stacks</code> で自動取得</td>
</tr>
<tr>
<td><strong>一括削除</strong></td>
<td><code>delete-stack</code> 1本でリソースの依存関係を自動解決して全削除</td>
</tr>
</tbody>
</table>
<h3><span id="toc24">CloudFormationのメリットを実感できたポイント</span></h3>
<ul>
<li>コンソール版では15〜20分かかった作業がコマンド1本（5分）で完了した</li>
<li><code>delete-stack</code> で依存関係を気にせず全リソースを一括削除できた</li>
<li><code>template.yaml</code> をGitで管理することで、環境構成の変更履歴が残せる</li>
</ul>
<hr>
<h2><span id="toc25">コンソール版と比較してみる</span></h2>
<p>CloudFormationが裏で何をやっているか、同じ構成をAWSコンソールのみで構築する手順をまとめました。コンソール版ではキーペア・IAMロール・セキュリティグループ・EC2を依存関係順に手動で作成する必要があり、各リソースの役割と繋がりが視覚的に理解できます。</p>
<p><!-- TODO: コンソール版記事へのリンクを追加 --></p>
<hr>
<h2><span id="toc26">関連記事</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-apache/">AWS CloudFormationでEC2 + ApacheウェブサーバーをIaC化しよう【EC2ハンズオン / コンソール版との比較付き】</a> first appeared on <a href="https://caymezon.com">CayTech Lab</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://caymezon.com/aws-handson-cloudformation-ec2-apache/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
