<?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>AWS  |  ナギ＠氷河期SEの知見録</title>
	<atom:link href="https://sys-univ.com/category/aws/feed/" rel="self" type="application/rss+xml" />
	<link>https://sys-univ.com</link>
	<description>クラウド移行・基盤設計・運用設計で見落としやすい実務の落とし穴を、若手SEにも分かる形で整理します。</description>
	<lastBuildDate>Mon, 22 Jun 2026 09:08:42 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>
<atom:link rel="hub" href="https://websubhub.com/hub"/>
<atom:link rel="self" href="https://sys-univ.com/category/aws/feed/"/>
	<item>
		<title>【第2部・前編】クラウドリフトPoCで「動いた」は確認できた。しかし業務では使えなかった｜10の設計リスク① 可用性・性能・ストレージ・バックアップ・監視</title>
		<link>https://sys-univ.com/dev/cloudlift-poc-risk-1/</link>
					<comments>https://sys-univ.com/dev/cloudlift-poc-risk-1/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Thu, 18 Jun 2026 15:04:41 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[システム開発]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=2561</guid>

					<description><![CDATA[※この記事は途中まで無料でお読みいただけます。続きはnote（有料）で公開しています。 「PoCでは問題なかったのに、構築に入ったら次々と課題が出てきた」 「接続確認はできていたのに、業務処理を流すと性能が出ない」 「バ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">※この記事は途中まで無料でお読みいただけます。続きはnote（有料）で公開しています。</p>
<p>「PoCでは問題なかったのに、構築に入ったら次々と課題が出てきた」</p>


<p class="wp-block-paragraph">「接続確認はできていたのに、業務処理を流すと性能が出ない」</p>


<p class="wp-block-paragraph">「バックアップは成功していたのに、戻す手順や時間を詰めていなかった」</p>


<p class="wp-block-paragraph">「共有ストレージとして使えると思ったのに、既存アプリのファイル更新方式と合わなかった」</p>


<p class="wp-block-paragraph">クラウドリフトでは、こうしたことが実際に起こります。</p>


<p class="wp-block-paragraph">PoCでEC2上のアプリは起動した。EFS上のファイルは読み書きできた。FSx経由のファイル共有も確認した。RDS上で主要なアプリ機能も動いた。CloudWatch Logsにもログは出力された。バックアップジョブも正常終了した。</p>


<p class="wp-block-paragraph">しかし、それだけでは、クラウドリフトPoCとしては足りません。</p>


<p class="wp-block-paragraph">「動いた」という確認は、業務が回るという確認とは別だからです。</p>


<p class="wp-block-paragraph">クラウドリフトで本当に怖いのは、PoCで「動いた」と判断したあとに、設計・構築・試験・運用の段階で後から手戻りになることです。</p>


<p class="wp-block-paragraph">性能が出ない。名前解決が想定どおりに動かない。Auto Scaling後に監視やジョブ実行対象として認識されない。EFS上のファイル更新方式が既存アプリと合わない。CloudWatch LogsのS3エクスポートが運用時間内に終わらない。バックアップの保持期間が業務要件とずれる。ライセンスやデータ転送量のコストが見積から漏れている。</p>


<p class="wp-block-paragraph">こうした問題は、現場では個別の設定ミスや確認不足に見えます。</p>


<p class="wp-block-paragraph">しかし、多くのプロジェクトで、PoCや設計段階で潰すべきリスクが残ったまま後工程へ進み、結果として大きな手戻りや追加対応につながる場面を見てきました。</p>


<p class="wp-block-paragraph">この記事は、クラウドリフトPoCを扱う全3部作の第2部前編です。</p>


<p class="wp-block-paragraph">第1部では、クラウドリフトの失敗が構築後ではなく、構築前のPoC不足から始まることを整理しました。</p>


<p class="wp-block-paragraph"><a href="https://sys-univ.com/dev/cloudlift/" target="_blank">【第1部】クラウドリフトの失敗は構築前に始まっている｜PoC不足が手戻り・コスト超過・納期遅延を招く理由</a></p>


<p class="wp-block-paragraph">第2部では、その続きとして、クラウドリフトPoCで見落とすと手戻りになりやすい10の設計リスクを整理します。</p>


<p class="wp-block-paragraph">第2部は、前編と後編に分けています。</p>


<p class="wp-block-paragraph">前編で扱うのは、クラウド基盤として業務を受け止めるために必要な、次の5項目です。</p>


<p class="wp-block-paragraph">１.可用性・信頼性<br />
２.性能・キャパシティ<br />
３.ストレージ<br />
４.バックアップ<br />
５.運用・監視</p>


<p class="wp-block-paragraph">後編では、構築後に運用・保守・統制・コスト管理で詰まりやすい、次の5項目を扱います。</p>


<p class="wp-block-paragraph">６.ジョブ管理・アプリ配布<br />
７.セキュリティ・アクセス管理<br />
８.ライセンス・製品サポート<br />
９.DB・OS・ミドルウェア互換性<br />
１０.コスト・キャパシティ管理</p>


<p class="wp-block-paragraph">つまり第2部では、「PoCで動いたか」ではなく、「その方式で設計・試験・運用・見積まで成立するか」を、10の観点から確認していきます。</p>


<p class="wp-block-paragraph">この記事で整理する設計リスクは、机上で作ったチェックリストではありません。</p>


<p class="wp-block-paragraph">大規模なクラウドリフト案件で、PoCを実施し、有識者も交えてリスクを潰しにいった中で見えてきた論点をもとにしています。</p>


<p class="wp-block-paragraph">RDS for OracleのDBA権限制約、EFS上での複数ノードによるファイル更新の競合、FSxのKerberos/SPN認証、名前解決経路とTTLの切替挙動、マネージドサービスのパッチ適用と自社セキュリティルールの整合などは、PoCで事前に確認しておくべき代表的な論点です。</p>


<p class="wp-block-paragraph">一方で、事前に検証していても、後工程で表面化した問題もありました。</p>


<p class="wp-block-paragraph">別AZ起動後のOS内ルート情報による通信不能、CloudWatch LogsのS3エクスポート制約、EBSの容量縮小、S3クロスアカウントのオブジェクト所有者問題、RHELとAmazon LinuxのOS設定差分、cloud-initによるSSH設定上書き、Auto Scalingの意図しないEC2再作成などです。</p>


<p class="wp-block-paragraph">「PoCで潰せたこと」と「PoCで潰しきれなかったこと」。</p>


<p class="wp-block-paragraph">その両方を踏まえて、現時点でクラウドリフトPoCに必要なチェック観点を整理したのが、この第2部です。</p>


<p class="wp-block-paragraph">PoCは、AWSサービスが使えるかを確認する作業ではありません。</p>


<p class="wp-block-paragraph">既存業務の処理方式、運用方式、復旧方式、名前解決、バックアップ、監視、ジョブ、ファイル更新方式、DB運用、ライセンス、コストが、クラウド上の構成で成立するかを確認する作業です。</p>


<p class="wp-block-paragraph">以下の図は、クラウドリフトPoCで見るべき10の設計リスクを整理したものです。</p>


<figure id="2118ca12-0523-4f8e-a747-7e39994cfe58" class="wp-block-image"><a href="https://assets.st-note.com/img/1781148756-H1k5XfuGSpOYVE7oC6cMPLbD.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1781148756-H1k5XfuGSpOYVE7oC6cMPLbD.png?width=1200" alt="画像" /></a></figure>


<p class="wp-block-paragraph">それぞれ、単なるチェックリストではありません。</p>


<p class="wp-block-paragraph">見落とすと、設計、試験、運用、見積、スケジュールにどう跳ね返るのかまで含めて整理します。</p>


<p>&nbsp;</p>



  <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">PoC観点を強化するきっかけになった個別事例</a></li><li><a href="#toc2" tabindex="0">1. 可用性・信頼性</a></li><li><a href="#toc3" tabindex="0">2. 性能・キャパシティ</a></li><li><a href="#toc4" tabindex="0">3. ストレージ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">PoC観点を強化するきっかけになった個別事例</span></h2>


<p class="wp-block-paragraph">以下は、クラウドリフトPoCの観点を見直すきっかけになった個別事例です。</p>


<p class="wp-block-paragraph">本記事では、これらの個別事例に加え、PoCで事前に潰せた設計論点も含めて、クラウドリフトPoCで見るべきリスクを整理しています。</p>

<ul>
	<li><a href="https://sys-univ.com/aws/addroute/">【AWS】別AZで起動したWindowsが通信不能に｜原因はVPCではなく「OS内のルート情報」だった</a></li>
	<li><a href="https://sys-univ.com/aws/cloudwatch-logs-export-concurrency/">CloudWatch Logsのログエクスポートが失敗した話｜「ジョブは動く」と「運用で回る」は別物</a></li>
	<li><a href="https://sys-univ.com/incident/awsbackup/">バックアップ設定の「5日保存」は、5営業日分とは限らない｜AWS Backupの保持期間から考える、詳細設計の落とし穴</a></li>
	<li><a href="https://sys-univ.com/incident/ebsresize/">EBSは増やせても、簡単には減らせない｜RHEL環境で見落とした「容量縮小＝ディスク移行」という現実</a></li>
	<li><a href="https://sys-univ.com/incident/s3-cross-account-object-owner/">S3バケットにあるのに取得できない｜クロスアカウント構成で見落とした「オブジェクト所有者」の罠</a></li>
	<li><a href="https://sys-univ.com/aws/mtusetting/">RHELで使えた設定方法が、Amazon Linuxでは使えなかった｜MTU設定に見る、OS差分と永続化確認の落とし穴</a></li>
	<li><a href="https://sys-univ.com/aws/mounterr/">EBSは見えているのにマウントできない？｜AMIコピーで起きた落とし穴</a></li>
	<li><a href="https://sys-univ.com/incident/sshfail/">AMIからRHELインスタンスを起動したらSSHログインできなくなった｜cloud-initが上書きする設定を知らないと、復旧以前に入れなくなる</a></li>
	<li><a href="https://sys-univ.com/aws/ec2autoscaling/">EC2を止めただけなのに再作成？Auto Scaling運用の落とし穴｜クラウドの自動化は、作業者の意図までは読んでくれない</a></li>
</ul>
<ul id="1a0e441c-ac89-4f07-8ad7-b95fc4b0bfcb" class="wp-block-list"><!-- /wp:post-content --></ul>
<!-- /wp:list -->
<!-- wp:paragraph -->
<p>なお、後編では購入者特典として、10項目全体を整理したExcel資料「クラウドリフトPoC設計リスクチェックリスト」も添付します。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoC計画、設計レビュー、リスク洗い出しのたたき台として使えるようにしています。</p>
<!-- /wp:paragraph -->
<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity" /><!-- /wp:separator -->
<!-- wp:heading -->
<h2 class="wp-block-heading"><span id="toc2">1. 可用性・信頼性</span></h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><strong>EC2が起動しただけでは、業務復旧とは言えない</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>クラウドリフトでは、可用性設計が軽く見られることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>EC2は再作成できる。<br />
RDSはMulti-AZにできる。<br />
Auto Scalingを使えば復旧できる。<br />
ロードバランサー配下に置けば切り替えられる。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>マネージドサービスがすべてやってくれるように見えるからです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、業務システムの復旧は、EC2が起動することではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>業務処理が再開できることです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Auto Scalingを使う場合でも、EC2が新しく作られれば終わりではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>実際の復旧方式では、障害ノードをロードバランサー配下から切り離し、AMIから新規EC2を作成し、cloud-initやUser Dataを使って初期設定を反映し、ホスト名を付与し、DNSに登録し、監視エージェントやミドルウェアを起動する、といった一連の処理が必要になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここで重要なのは、単にスクリプトを書けるかどうかではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>実行タイミングです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ホスト名の付与が監視エージェントやミドルウェアの起動より後になると、誤ったホスト名でサービスが起動し、監視登録やジョブ実行対象の認識がずれることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>そのため、cloud-initのどの段階で設定を反映するのか、User Dataで実行するのか、設定ファイル側で制御するのか、サービス起動順序をどうするのかまで確認しなければなりません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>さらに、ロードバランサーのヘルスチェックに戻す条件、監視対象への再登録、ジョブ実行対象としての認識、ログ収集先の切替、障害解析のために旧EC2を残すかどうかも決める必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>Auto Scalingは復旧方式の一部であって、復旧方式そのものではありません。</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>AWS側が支援してくれるのは、インスタンスの再作成、ロードバランサーのヘルスチェック、マネージドサービスの切替といった基盤機能の部分です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>一方で、作り直されたEC2を業務システムとして使える状態に戻す設計は、利用者側の責任です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ホスト名、DNS登録、監視エージェント、ミドルウェア起動順序、ジョブ実行対象への再登録、ログ収集先の切替、復旧後の業務確認は、クラウドが自動で判断してくれるわけではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCでは、EC2が作られるかではなく、作られたEC2が業務システムの構成要素として正しく組み込まれるかを確認する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この復旧の流れは、文章だけでは見落とされやすいため、図に整理すると次のようになります。</p>
<!-- /wp:paragraph -->
<!-- wp:image {"linkDestination":"custom","anchor":"c5cb7384-ed8c-4dc6-bb8e-908714d3ea47"} -->
<figure id="c5cb7384-ed8c-4dc6-bb8e-908714d3ea47" class="wp-block-image"><a href="https://assets.st-note.com/img/1780912470-JUEa2GQSfdWHXsqlP8ToN5OD.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780912470-JUEa2GQSfdWHXsqlP8ToN5OD.png?width=1200" alt="画像" /></a></figure>
<!-- /wp:image -->
<!-- wp:paragraph -->
<p><strong>保守停止と障害検知は分けて考える</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Auto Scalingでは、EC2が意図せず停止した場合に、期待する台数を維持するため、新しいEC2が作られることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>これは可用性の観点では便利です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、運用の観点では注意が必要です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>保守作業としてEC2を停止したいだけでも、停止方法や事前の切り離し手順が適切でなければ、Auto Scaling側では障害や不足状態として扱われることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>作業者は「保守のために止めた」と思っている。<br />
しかし、Auto Scalingは期待台数を維持する仕組みとして、元の台数へ戻そうとします。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>その結果、意図しないEC2が作られ、監視、ジョブ、ログ、ライセンス、コストの前提が崩れることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>このようなことが起こります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>つまり、Auto Scalingを使うなら、障害時にどう復旧するかだけでなく、保守時にどう止めるかも設計しなければなりません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>保守作業時には、Auto Scalingグループの期待台数を変更するのか。<br />
インスタンス保護を使うのか。<br />
スケーリングを一時停止するのか。<br />
ロードバランサーから切り離して作業するのか。<br />
作業後にどう戻すのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この運用手順を決めずにAuto Scalingを使うと、「自動復旧」が「作業者の意図しない再作成」になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>クラウドの自動化は、作業者の意図までは読んでくれません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCでは、障害時の自動復旧だけでなく、保守停止、再起動、切り離し、再登録、戻し忘れの検知まで確認する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>別AZで起動できても、通信できるとは限らない</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>別AZでEC2を起動できたとしても、通信できるとは限りません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>VPC、サブネット、ルートテーブル、Security Groupが正しく見えていても、OS内に残っている静的ルート、永続ルート、NIC設定、メトリック設定が移行後のネットワーク構成と合わないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>その場合、AWS側のネットワーク設定だけを見ても原因にたどり着けません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>クラウド移行では、ネットワークの問題を見るときに、どうしてもVPC側へ目が向きます。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ルートテーブルは正しいか。<br />
Security Groupは開いているか。<br />
NACLで落ちていないか。<br />
サブネットの関連付けは正しいか。<br />
Transit GatewayやVPN経路は正しいか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>もちろん、それらは重要です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、OS内に固定で設定されていたルート情報、古いネットワークアダプタ前提の設定、特定AZや特定サブネットのIPを前提にした設定が残っていると、AWS側のネットワークが正しくても通信できないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>特にWindowsサーバでは、GUI上のネットワーク設定だけでなく、永続ルート、メトリック、複数NIC構成、過去に追加した静的経路などが影響することがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCでは、EC2が起動するか、疎通確認が一度通るかだけでなく、OS内のルート情報、再起動後の永続化、AZ変更後の通信経路まで確認する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>「AWS側の設定は正しいのに通信できない」という状態は、原因調査に時間がかかります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>だからこそ、PoCの段階で、OS内のネットワーク前提まで確認しておく必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>名前解決は、クラウドリフトにおける最重要設計論点</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>クラウドリフトでは、名前解決が非常に重要です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>オンプレでは、サーバ名、IPアドレス、DNS登録、参照経路が長期間固定されている前提で運用されていることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、クラウドでは、EC2の再作成、AZ変更、復旧方式、切替方式によって、同じIPアドレス、同じ物理名、同じ参照経路で戻ってくるとは限りません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>そのため、必要に応じてDNSやRoute 53のレコードを書き換える設計が必要になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここで注意すべきなのは、「DNSを書き換えればよい」という単純な話ではないことです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>参照元がAWS内のEC2なのか。<br />
別VPCなのか。<br />
オンプレミスのクライアントなのか。<br />
AD DNSを見ているのか。<br />
オンプレDNSからRoute 53へフォワードしているのか。<br />
Route 53 Private Hosted Zoneを直接見ているのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この経路によって、復旧時に変更すべき場所が変わります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>特にハイブリッド構成では、Route 53 ResolverのInbound endpoint、Outbound endpoint、転送ルールの設計も重要になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>オンプレ側からAWS内の名前を解決するのか。<br />
AWS側からオンプレDNSへ問い合わせるのか。<br />
どのドメインを、どのDNSへフォワードするのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>また、名前解決は成功するか失敗するかだけでなく、問い合わせにどれくらい時間がかかるかも重要です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>オンプレDNS、Route 53 Resolver、AD DNS、別VPCのDNSをまたぐ構成では、フォワード先の設定、再帰問い合わせ、リトライ挙動によって、名前解決の遅延がアプリケーションの応答時間やタイムアウトに影響することがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この設計を誤ると、AWS側では名前解決できているのに、オンプレ端末や業務サーバからは名前解決できない、という状態になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>場合によっては、クラウド側のレコードを変更したつもりでも、参照元が別のDNSサーバを見ていて、期待した名前解決にならないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここを知らずに進むと、基盤結合試験まで発見されないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>システムテストのユースケースが甘いと、本番切替後に初めて通信できない、接続先が違う、名前解決できない、という形で発覚する可能性があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>クラウドリフトでは、DNSは単なる付帯設定ではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>復旧方式、切替方式、運用方式そのものに関わる設計要素です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>DNSキャッシュとTTLも見落としやすい</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>切替直後は、クライアントやアプリケーションが古い名前解決結果をキャッシュしているため、一見すると通信できているように見えることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、TTLが切れて再度名前解決が行われたタイミングで、参照先DNS、Route 53、オンプレDNS、Resolver経路、レコード状態のどこかに不整合があると、名前解決エラーや接続先誤りとして表面化します。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>また、OS、JVM、ミドルウェア、接続プール、プロキシなどが名前解決結果や接続先情報を保持していると、Route 53側のTTLだけを見ていても切替挙動を説明できません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>DNS再解決を契機に接続先が変わり、TLS証明書のホスト名検証、DB接続、認証処理、接続プールの再接続で失敗することもあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>特にアプリケーションサーバやバッチ処理では、起動時に解決した接続先情報をプロセス内で保持し続けることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>その場合、DNSレコードを変更しても、アプリケーションが再起動されるまで新しい接続先を見に行かないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>逆に、TTL経過後に再解決された瞬間に、今まで見えていた接続先と別の接続先へ向かい、初めて問題が出ることもあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCでは、切替直後だけでなく、TTL経過後、キャッシュクリア後、アプリ再起動後、接続プール再作成後の挙動まで確認しておく必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>DNSは、切替直後に疎通できればよいわけではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>TTLが切れた後、キャッシュが消えた後、アプリが再接続した後に、同じように業務が継続できるかを見る必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>RDS Multi-AZも「切り替われば終わり」ではない</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>RDSがフェイルオーバーして待機系へ切り替わった場合、DBとしては復旧していても、Web/APサーバとのAZ配置が変わることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>Web/APはAZ-A中心に残り、RDSのプライマリだけAZ-Bへ切り替わると、Web/APからDBへの通信がAZまたぎになります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>実務では、切替直後は一時的な縮退状態として許容し、業務影響を見ながらフェイルバックする方針を取ることもあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>また、DBがフェイルオーバーしても、アプリケーション側が正しく再接続できるとは限りません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>コネクションプールが古い接続を保持したままになる。<br />
接続リトライの回数や間隔が足りない。<br />
DNS再解決が走らない。<br />
一時的な接続断をアプリが異常終了として扱う。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>このような場合、RDSとしては復旧していても、アプリケーションは接続エラーを出し続けることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCや障害試験では、DBの切替だけでなく、アプリ側の再接続、リトライ、コネクションプールの挙動まで確認する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここで重要なのは、切り替わるかどうかではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>切り替わった後の配置で、画面応答、バッチ処理、帳票処理、データ転送量、運用手順に問題が出ないかを確認することです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>PoCで見るべき観点</strong></p>
<!-- /wp:paragraph -->
<!-- wp:list {"anchor":"df12add0-1e3a-46b1-9e18-b4c01a835530"} -->
<ul id="df12add0-1e3a-46b1-9e18-b4c01a835530" class="wp-block-list"><!-- wp:list-item -->
	<li>障害時に、どの単位で、どこまで自動復旧するのか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>そのEC2は、自動で作り直してよいサーバなのか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>Auto Scaling後に、ホスト名、DNS登録、OS設定、監視エージェント、ミドルウェア起動まで再現できるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>cloud-initやUser Dataの実行タイミングが、サービス起動順序と矛盾していないか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>ロードバランサーのヘルスチェック、切り離し、復帰の条件は明確か</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>保守作業としてEC2を停止した場合と、障害として停止した場合を、Auto Scalingがどう扱うか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>保守時にスケーリング停止、期待台数変更、インスタンス保護などの運用手順が必要か</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>別AZ起動後に、OS内の静的ルート、永続ルート、NIC設定、メトリック設定が移行後の構成と合っているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>参照元ごとに、どのDNSサーバを経由して名前解決しているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>DNS問い合わせの遅延、リトライ、再帰問い合わせがアプリケーション応答やタイムアウトに影響しないか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>Route 53 ResolverのInbound/Outbound endpoint、転送ルールがハイブリッド構成に合っているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>EC2再作成、AZ変更、切替後に、DNSやRoute 53のレコード変更が必要になるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>DNSキャッシュやTTL経過後に、参照元から再度正しく名前解決できるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>OS、JVM、ミドルウェア、接続プール、プロキシが独自に名前解決結果を保持していないか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>RDSがフェイルオーバーした後、Web/APとのAZ配置や通信経路に問題が出ないか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>DB切替後に、アプリ側の再接続、リトライ、コネクションプールの再作成が正しく行われるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>縮退状態を許容するのか、フェイルバックするのか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>復旧後に何を確認すれば業務再開と言えるのか</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->
<!-- wp:paragraph -->
<p>可用性は、サーバが再起動することではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>自動復旧できるものと、手動で戻すべきものを切り分けること。<br />
切り替わった後の配置、性能、縮退運用、フェイルバック方針まで確認すること。<br />
そして、業務が再開できる状態を説明できること。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここまで見て、初めてクラウドリフトにおける可用性設計です。</p>
<!-- /wp:paragraph -->
<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity" /><!-- /wp:separator -->
<!-- wp:heading -->
<h2 class="wp-block-heading"><span id="toc3">2. 性能・キャパシティ</span></h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><strong>動いたことと、業務時間内に処理できることは違う</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>性能面において最も危険なのは、単純な正常系テストで『動いた』と満足してしまうことです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>EC2上でアプリが起動した。<br />
DBに接続できた。<br />
バッチが1回流れた。<br />
ファイルを読み書きできた。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>しかし、それだけでは性能要件を満たしたことにはなりません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>現場では、日次の夜間バッチだけが重いとは限りません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>週次処理、月次処理、締め処理、大量帳票、ファイル集計、洗い替え処理など、特定日だけ極端に重くなる処理があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>通常日の軽いデータや単発の小さな検証だけで判断すると危険です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>性能が出るかどうかは、インスタンスタイプ選定とも切り離せません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>オンプレからクラウドへ移行する場合、既存サーバのCPU、メモリ、ディスクI/O、ネットワーク使用量をそのまま見ても、クラウド上の適切なインスタンスタイプが自動的に決まるわけではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>オンプレ環境では、CPU性能をSPECintや独自の換算指標で見ていたとしても、AWS上ではインスタンスタイプごとにvCPU数、メモリ量、ネットワーク性能、EBS帯域、CPU世代、ファミリー特性が異なります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>そのため、単純に「CPUが何個あるからこのタイプ」「メモリが何GBあるからこのタイプ」と決めるのは危険です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>バッチサーバのように、大量データを読み込み、ソートし、一時領域を使い、一定時間内にまとめて処理するサーバでは、CPUだけでなくメモリやI/Oが効いてくることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>一方で、Web/APサーバのように、1件あたりの処理は軽くても、多数のリクエストやトランザクションをさばくサーバでは、vCPU数、同時実行性能、スレッド数、コネクションプールの設計が効いてくることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>CPUが足りないのか。<br />
メモリが足りないのか。<br />
I/Oが詰まっているのか。<br />
ネットワークが詰まっているのか。<br />
同時実行数に対してスレッドやコネクションプールが足りないのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここを見ずにインスタンスタイプだけを上げると、コストだけが増えて、性能問題が解消しないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>また、拡張性を残すことも重要です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>最初からそのファミリーの最大サイズ、または上限に近いタイプを選んでしまうと、負荷が増えたときに同じ考え方でスケールアップできません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>「性能が足りなければタイプを上げればよい」と考えていたのに、すでに上限に近いタイプを選んでいたため、設計変更、構成変更、スケールアウト方式の見直しが必要になることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCでは、今の負荷を処理できるかだけでなく、将来の増加分をどこまで同じ構成で吸収できるかも確認しておく必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>同じファミリー内のサイズ変更で対応できるのか。<br />
メモリ最適化、コンピューティング最適化、汎用系など、ファミリー選定から見直す必要があるのか。<br />
スケールアップではなく、スケールアウトや処理分散を考えるべきなのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この判断は、性能設計であり、同時にコスト見積やキャパシティ管理の前提にもなります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>PoCで見るべきなのは、単に「このタイプで動いたか」ではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>このタイプで本番負荷に耐えられるのか。<br />
将来の増加に対して拡張余地があるのか。<br />
同じファミリー内で上げればよいのか、ファミリー選定から見直すべきなのか。<br />
見積、性能試験計画、キャパシティ管理の前提として説明できるのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここまで確認しないと、設計段階でインスタンスタイプを決められず、試験やサービス開始後に「タイプを変えれば済むと思っていたのに、そう簡単ではなかった」という状態になります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>EFSを使う場合、標準的なバースト前提では、重いバッチ処理を安定して処理できないことがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>EFSのバーストスループットは、クレジットの蓄積と消費で動きます。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>軽い処理を続けている間はクレジットが回復しますが、重いバッチを集中的に流すとクレジットを一気に使い切り、ベースラインスループットまで落ちることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>また、EFSの性能を見るときは、単純な転送量だけでは不十分です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>読み取り中心なのか、書き込み中心なのか。<br />
大きなファイルを少数扱うのか、小さなファイルを大量に扱うのか。<br />
`ls`、`find`、属性確認、ディレクトリ走査のようなメタデータ操作が多いのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>この違いによって、同じデータ量でもボトルネックの出方は変わります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>特に小さなファイルが大量にあり、バッチ処理でディレクトリを再帰的に走査するような場合、データ転送量よりもメタデータ操作が効いてくることがあります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>そのため、通常日のPoCでは問題なかったのに、月次締め処理や大量ファイル処理だけ極端に遅い、という現象が起こります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>バッチ処理がEFSから大量のファイルを読み込み、CPUとI/Oを同時に使い切るような処理であれば、エラスティックスループットやプロビジョンドスループットを検討する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>重要なのは、単に性能が出るかどうかではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>最も重い処理を、最も重い条件で流したときに、どのスループットモードが必要なのか。<br />
一時的に性能を上げる運用が可能なのか。<br />
処理後に下げられるのか。<br />
変更に制約はないのか。<br />
戻し忘れた場合にどれだけ課金されるのか。<br />
見積上、その運用を説明できるのか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここまで含めて検証する必要があります。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>もし、インフラ側の調整だけでは性能要件を満たせない場合は、バッチ処理の分割、コミット単位の見直し、ソート処理の方式、DBアクセス方式、ログ出力方式など、アプリケーションや処理方式の見直しに波及します。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>性能PoCの最大のポイントは、軽い処理で「動いた」と確認することではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>最も重い処理を、最も重い条件で流し、必要な性能、構成、課金、運用手順、そしてアプリ改修要否まで判断することです。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p><strong>PoCで見るべき観点</strong></p>
<!-- /wp:paragraph -->
<!-- wp:list {"anchor":"0b5ddee6-6393-432f-87fa-1917fed911ec"} -->
<ul id="0b5ddee6-6393-432f-87fa-1917fed911ec" class="wp-block-list"><!-- wp:list-item -->
	<li>週次・月次・締め処理など最も重いバッチを本番相当データで流せるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>既存サーバのCPU、メモリ、I/O、ネットワーク使用量をもとに、アプリケーション特性に合ったインスタンスタイプやファミリーを選べているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>バッチサーバ、Web/APサーバ、DBサーバなど、役割ごとにvCPU、メモリ、I/O、ネットワークの見方を分けているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>最初から最大サイズや上限に近いタイプを選んでおらず、将来のスケールアップ余地を残しているか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>同じファミリー内のサイズ変更で足りるのか、ファミリー変更やスケールアウト設計まで必要になるのか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>EFS、EBS、DB、ネットワーク、EC2インスタンスのどこがボトルネックになるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>EFSを使う場合、バースト、エラスティック、プロビジョンドのどのスループットモードが必要か</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>一時的に性能を上げ、処理後に下げる運用が現実的にできるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>インフラ側の性能調整で足りない場合、アプリ改修や処理方式変更が必要になるか</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
	<li>読み取り/書き込み比率、大量小ファイル、`ls`/`find`などのメタデータ操作が性能ボトルネックにならないか</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->
<!-- wp:paragraph -->
<p>性能は、CPUやメモリの数字だけで決まるものではありません。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>業務処理が、必要な時間内に、必要な量を、安定して処理できるか。<br />
そして、その性能を必要なときだけ使い、不要なときにはコストを抑える運用ができるか。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ここまで見て、初めてクラウドリフトにおける性能設計です。</p>
<!-- /wp:paragraph -->
<!-- wp:separator -->
<hr class="wp-block-separator has-alpha-channel-opacity" /><!-- /wp:separator -->
<!-- wp:heading -->
<h2 class="wp-block-heading"><span id="toc4">3. ストレージ</span></h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><strong>共有できることと、業務で使えることは違う</strong></p>
<!-- /wp:paragraph -->
<!-- wp:paragraph -->
<p>ストレージは、クラウドリフトPoCで大きな手戻りになりやすい領域です。</p>
<!-- /wp:paragraph -->
<!-- wp:paragraph --><!-- /wp:paragraph -->
<div style="margin: 16px 0;"><a style="display: block; border: 1px solid #1D9E75; border-radius: 6px; padding: 12px 16px; text-decoration: none; color: #333; background: #f9fffc;" href="https://note.com/k_s7906/n/n742f150cf39c"><br />
<span style="font-size: 12px; color: #1d9e75;">続きはnoteで読む ¥500</span><br />
<span style="font-size: 14px; font-weight: bold;">ストレージ以降（リスク3〜5）の解説はこちら →</span><br />
</a></div>]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/dev/cloudlift-poc-risk-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>EBSは増やせても、簡単には減らせない｜RHEL環境で見落とした「容量縮小＝ディスク移行」という現実</title>
		<link>https://sys-univ.com/incident/ebsresize/</link>
					<comments>https://sys-univ.com/incident/ebsresize/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Fri, 30 Sep 2022 02:49:29 +0000</pubDate>
				<category><![CDATA[トラブル]]></category>
		<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1246</guid>

					<description><![CDATA[EBSは、容量を増やすのは比較的簡単です。 しかし、同じ感覚で「小さくできる」と考えると、実務では詰まります。 今回扱うのは、Red Hat Enterprise Linuxを利用しているEC2で、EBSの容量縮小を検討 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="ec6425f2-f27b-4e37-8f1c-a1d3f3017c60">EBSは、容量を増やすのは比較的簡単です。</p>
<p id="f1dcb598-3020-4299-8390-ccf6efe19094">しかし、同じ感覚で「小さくできる」と考えると、実務では詰まります。</p>
<p id="d388ef88-b6ed-45d0-88d1-4e5d4d5a9d20">今回扱うのは、Red Hat Enterprise Linuxを利用しているEC2で、EBSの容量縮小を検討したときの話です。</p>
<p id="991a736e-9e02-4957-b536-63c87c05bb28">容量拡張であれば、AWS側でEBSボリュームサイズを拡張し、OS側でパーティションやファイルシステムを拡張することで対応できます。</p>
<p id="f3dcd6c0-8e04-4dd2-97ec-a6dd11d9a8d2">一方で、容量縮小は同じ考え方では進みません。</p>
<p id="531b13c0-51dc-4621-88d6-c47cb8600ff2">なぜなら、EBSの容量縮小は、既存ディスクのサイズを小さくする作業ではないからです。</p>
<p id="7d0cfc3a-aab4-4f33-98b5-528c029e9989">実態としては、小容量ディスクを新しく作り、必要なデータを移して切り替える作業です。</p>
<p id="f1853fee-d6c3-404e-b1c0-7b927eb214a7"><strong>つまり、容量縮小に見えても、考えるべきことはディスク移行です。</strong></p>
<p id="8a498814-9c87-46c6-b2e6-383116b4e320">今回は、EBS縮小にあたって検討した3つの案と、最終的にどのような考え方で対応したのかを整理します。</p>

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-4" checked><label class="toc-title" for="toc-checkbox-4">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">そもそも、なぜ認識がズレるのか</a></li><li><a href="#toc2" tabindex="0">容量拡張は比較的素直にできる</a></li><li><a href="#toc3" tabindex="0">しかし縮小は、同じ考え方ではできない</a></li><li><a href="#toc4" tabindex="0">検討した3つの案</a></li><li><a href="#toc5" tabindex="0">今回、何が甘かったのか</a></li><li><a href="#toc6" tabindex="0">手順の前に、作業の性質を見極める</a></li><li><a href="#toc7" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 id="ed8b704f-77f1-442d-8340-4fb6d7ebd63e" tabindex="-1"><span id="toc1">そもそも、なぜ認識がズレるのか</span></h2>
<p id="edfa8666-8517-431b-8f8f-89703d65c89f">まず最初に確認しておきたいのは、「縮小しようとしたこと」自体が悪いわけではない、ということです。</p>
<p id="c12b2898-8597-4bef-a85a-95f33661814f">コスト削減や容量適正化の観点から、過剰に確保されたディスク容量を見直すことは当然あります。</p>
<p id="b2668c62-f3d0-4715-ab46-eb344d79c30b">問題は、容量縮小を「単なるサイズ変更」と捉えてしまうことです。</p>
<p id="7e74584a-3ed5-4023-83fd-6fb6d4207c89">クラウドストレージは柔軟に見えます。</p>
<p id="f6f00392-89d6-4376-afde-8352ce1b8a64">実際、EBSの拡張は比較的やりやすいです。</p>
<p id="d7bc0e90-337d-4297-ac3c-8e1c8feec2f0">AWS側でボリュームサイズを拡張し、OS側でその拡張分を認識させれば、既存の領域を広げることができます。</p>
<p id="b0b4437d-64fa-41c4-9c05-5210ef0286a0">しかし、縮小は違います。</p>
<p id="b79eff45-a5ba-4661-b439-aab51431dbf1">AWSのEBSにおいて、拡張と縮小は非対称です。</p>
<ul id="3f5a40a0-b1a9-477b-8428-7825f3f54ff4">
<li>
<p id="498dc1d5-66b4-4ed5-97ef-1e425d0d9045">拡張方向：既存のボリュームを大きくできる</p>
</li>
<li>
<p id="47f20736-c6e9-4c07-b1d4-5ee017e4579d">縮小方向：既存のボリュームをそのまま小さくする操作はできない</p>
</li>
</ul>
<p id="7392f131-a15f-433d-a4b5-3301e31404ed">ここを誤解すると、設計や作業計画の段階でズレます。</p>
<p id="4969ad33-5c4c-4449-b706-346b4221d3ec">「クラウドだから柔軟に変えられる」</p>
<p id="12b20d07-47a5-494e-b1d0-f4b46bf0fa17">この感覚は、拡張方向にはある程度当てはまります。</p>
<p id="0e2d1667-9ea9-4513-988b-9723be7b5412">しかし、縮小方向にはそのまま当てはまりません。</p>
<p id="d595e370-1bdb-44f6-baf3-df0b2fc793a1">この非対称性を理解していなかったことが、今回のつまずきの根本でした。</p>
<h2 id="68999f34-471e-46a0-af33-ef1bc99d0495" tabindex="-1"><span id="toc2">容量拡張は比較的素直にできる</span></h2>
<p id="1b6b61e9-fdaa-4c51-a1c8-1291b057d021">EBSの容量拡張であれば、作業の考え方は比較的明確です。</p>
<p id="0f9e5785-accd-4b15-8c76-780ae70cebb5">RHEL環境であれば、流れはおおむね次のようになります。</p>
<ol id="bf23abcc-af50-4b3f-9cc4-4b40c0ffcc58">
<li>
<p id="7fec4c10-a914-4ab8-b6f7-6073a3b6d293">AWS側で既存EBSボリュームのサイズを拡張する</p>
</li>
<li>
<p id="a4691e8a-0f14-4c57-8443-817542fc9cd3">Linux OS上でパーティションを拡張する</p>
</li>
<li>
<p id="423207ca-a14f-4cf8-8447-bb60a1456746">必要に応じてLVM側の設定を拡張する</p>
</li>
<li>
<p id="98dd6675-cb87-499f-b6a5-87892af29a3d">ファイルシステムを拡張する</p>
</li>
</ol>
<p id="5b952b9d-2b7a-4cc7-8833-8819f6d92b31">この流れを図にすると、以下のようになります。</p>
<figure id="ea63d8f7-4b0e-4107-9dc3-f134a1eb90a7"><a href="https://assets.st-note.com/img/1780378608-PoTZYAD2zm9LujSbsl0OkrqQ.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img fetchpriority="high" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780378608-PoTZYAD2zm9LujSbsl0OkrqQ.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption>（図：EBS容量拡張の基本フロー）</figcaption></figure>
<p id="ddca3fdf-fc61-4691-8ea3-5b837a68b00f">容量拡張は、既存の構成を保ったまま、ディスク領域を順番に広げていく作業です。</p>
<p id="095c086e-46bb-4ae3-a563-b6ee57850221">EBSを拡張し、OS側でパーティションやLVM、ファイルシステムに反映していく。</p>
<p id="70f8c329-8b6f-4072-bf8b-fd151bf269ec">つまり、拡張は「今ある領域を広げる」作業として整理できます。</p>
<p id="6d99d092-3757-4922-8a78-d25535ac67b3">もちろん、実務では事前バックアップを取得したうえで作業します。</p>
<p id="86d29f3b-6859-4e5b-81d9-0e29511b0084">それでも、容量拡張は「既存構成を壊さずに広げる」方向の作業として成立しやすいです。</p>
<h2 id="a8870c31-9cfa-47d3-9e3b-bb2500d9ef5f" tabindex="-1"><span id="toc3">しかし縮小は、同じ考え方ではできない</span></h2>
<p id="52ff9a2b-a62b-4de3-a10e-a8868dc1f230">問題は、容量縮小です。</p>
<p id="7b1029c7-a3a9-4fc0-bd5f-67b20799ae0c">容量縮小も、拡張と同じ感覚で考えたくなります。</p>
<p id="9ab347d9-c67e-4816-852d-f75f3cf52d9e">「AWS側でサイズを小さくして、OS側でも縮小すればよい」</p>
<p id="a7f7d4a9-c01f-483c-bb9d-5fdc1f960fad">一見、自然に見えます。</p>
<p id="28f45f21-6086-4463-a3b6-7562f4ed3551">しかし、これはできません。</p>
<p id="fe2c2203-837c-4835-b8bc-37632e56783f">EBSは、既存ボリュームを直接縮小する操作を提供していません。</p>
<p id="12289f34-4028-4160-94e7-343e4eee0dfe">つまり、容量縮小は「既存ディスクを小さく加工する」作業ではないのです。</p>
<p id="ba332ccd-bd11-48ca-a375-d15e6e900f5b">実務上の考え方は、こうなります。</p>
<p id="03e4bda3-7fb4-4503-adc3-9b5bcb396d21"><strong>縮小するのではなく、小容量EBSを新しく作り、必要なデータだけを移す。</strong></p>
<p id="3943ce61-9944-4230-bebf-1e6dab205b0c">これはディスク縮小ではありません。</p>
<p id="1075e753-51a3-495d-a9fa-449347b30a67"><strong>小容量ディスクへの移行</strong>です。</p>
<p id="8862c4e6-3e51-4e1a-9777-78a8df14e814">この発想の切り替えが必要です。</p>
<p id="8b444347-63be-4517-8cc5-75b4a2dbbfd3">また、OSのファイルシステムとしてXFSを使用している場合、ファイルシステム自体を縮小することはできません。</p>
<p id="f8f12ce0-2179-4084-95f5-7d201cd10a98">そのため、バックアップ、ファイルシステムの再作成、リストアという流れで考える必要があります。</p>
<p id="41e2fe11-4237-416f-9938-4465063f366b">ここで必要なのは、縮小コマンドを探すことではありません。</p>
<p id="c65d6e32-7a8e-442c-aa34-a330c4e5c938"><strong>「これは移行作業である」と捉え直すことです。</strong></p>
<p id="f2c9fcc5-2bc1-495a-9d36-2b1ee6d737a9">拡張と縮小の違いを、あえてシンプルに図にするとこうなります。</p>
<figure id="b9c1a9e2-c9e1-4a41-8b19-f9e56204e2d4"><a href="https://assets.st-note.com/img/1780378640-3VCOPbMkX09aUnJDLs2x7Biv.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780378640-3VCOPbMkX09aUnJDLs2x7Biv.png?width=1200" alt="画像" width="620" height="349" data-modal="true" /></a><figcaption>（図：EBS容量縮小は「縮小」ではなく「データ移行」）</figcaption></figure>
<p id="c3313779-7ddd-4b2c-b322-9a4fdaf50bec">ポイントは、縮小が「既存ディスクを小さくする作業」ではないことです。</p>
<p id="aeea4242-acef-4c27-a43a-2473afe0b87e">小容量EBSを新しく作り、必要なデータを移し、切り替える。</p>
<p id="06bda8ca-447a-4ee2-ab3a-1bbb161565c4">この時点で、容量縮小はサイズ変更ではなく、移行作業として考える必要があります。</p>
<h2 id="f87cc0d0-cb60-407e-a540-bc9a096f7857" tabindex="-1"><span id="toc4">検討した3つの案</span></h2>
<p id="7dc28702-e8ee-4399-8ecd-d6c206962abc">今回、実際に検討した案は次の3つです。</p>
<p id="00c14797-71da-4a53-9cb6-c1ab01d933e6"><strong>案1：既存EBSを直接縮小する</strong></p>
<p id="cfa4b3e0-ce44-4594-bb5a-7a0a23200790"><strong>結論：不可</strong></p>
<p id="8d110fad-d1ed-4025-be45-ec5881705d43">EBSボリューム自体を直接縮小することはできません。</p>
<p id="9a35f405-33af-4950-bd39-779afde205bd">無理に考えると、OS上のパーティションやファイルシステムとの整合性が崩れ、データ破損につながるリスクがあります。</p>
<p id="7e0fe556-23c0-4c81-96de-553b0edd0576"><strong>案2：AMIから小容量EBSへ復元する</strong></p>
<p id="35d315ba-4a38-4dcd-b31f-8e3e26a67a0b"><strong>結論：今回は不可</strong></p>
<p id="f5bdf897-98fe-461f-94d7-9df2dd8f86c4">AMIからの復元そのものが悪いわけではありません。</p>
<p id="5383f78d-2648-4fe7-9dbd-9a290e6d74f6">しかし、元ディスクの構成を、そのまま小容量EBSへ復元する前提では整合性が取れません。</p>
<p id="fdad1bdc-d323-4b25-aa91-af339d025513">EBSは、元のボリュームより小さいサイズへ単純に戻すことはできません。</p>
<p id="e79e0ef0-4b24-4dc5-97eb-5b5976a5940e">また、OS領域、パーティション構成、LVM、ファイルシステムの状態を踏まえずに小容量EBSへ戻そうとすると、容量不足や構成不整合が発生します。</p>
<p id="25277df4-9c2d-4edf-b284-c5acd5192d21">特にXFSのように縮小できないファイルシステムを使っている場合、LVMだけを見て小さくできるとは判断できません。</p>
<p id="71d1835e-3c5b-4be9-bbb5-49e081ca0709">そのため、今回の対策としては採用できませんでした。</p>
<p id="9c58da56-640b-484a-b918-0ccb793c9aba"><strong>案3：OS上でバックアップ・リストアする</strong></p>
<p id="f6ad301b-44fe-4de8-867c-a89c4ec3b7c3"><strong>結論：採用</strong></p>
<p id="514bb38a-d047-4148-a5b8-de1d3e21ffa8">小容量EBSを新規作成し、OS上でデータを退避・復元する方法です。</p>
<p id="f17bd868-53f0-40d4-a81e-e2e9eb1ba2e6">ただし、OS上の使用容量が、縮小後のEBS容量より小さいことが前提です。</p>
<p id="1255433a-d5b9-4be2-b0a2-701576e4b5d2">つまり、EBSを直接縮小するのではなく、小容量ディスクへ必要なデータを移す、という考え方です。</p>
<p id="77ded4c1-8018-45d9-b5e1-60ed57264fd8">文章だけだと少し分かりにくいので、3つの案をイメージで並べると以下のようになります。</p>
<figure id="becbaeb2-c971-454b-b53f-7d28c164952b"><a href="https://assets.st-note.com/img/1780378669-FdIirlG0Kx2tXBL1AanckwNf.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780378669-FdIirlG0Kx2tXBL1AanckwNf.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption>（図：EBS縮小で検討した3つの案）</figcaption></figure>
<p id="ba237bc3-c28b-4188-91dc-931852d08640">案1は、既存EBSを直接小さくしようとする考え方です。</p>
<p id="5a4c38cb-945a-4a15-9397-c456fea7af43">案2は、AMIから小容量EBSへ戻そうとする考え方です。</p>
<p id="4c2611a1-5d0e-4ed4-89db-19499ec6d40a">案3は、小容量EBSを新規作成し、必要なデータを移す考え方です。</p>
<p id="6242814b-a3f7-4059-9611-594d6a91041b">今回採用したのは、案3でした。</p>
<p id="93b7e61a-88a8-452a-8fcd-c45dedee0d36">ここからは、それぞれの案で何が問題だったのかを見ていきます。</p>
<p id="fc6a541f-3b1b-4f3b-a1b8-b0f342a94067"><strong>案1：既存EBSをそのまま縮小する</strong></p>
<p id="08752a81-97b9-4917-9efe-79409b349b86">最初に考えたのは、既存EBSを直接小さくできないか、という案です。</p>
<p id="ead85753-1f23-49d6-80c5-5632cd3c7afd">容量拡張の逆で、既存ボリュームのサイズを小さい値に変更できないか、という発想です。</p>
<p id="cc28b7fb-c17e-44f9-a6e1-7a5cf9904f56">しかし、これは採用できませんでした。</p>
<p id="373e8563-3c03-4cd8-8064-9fe4709a7754">理由は単純です。</p>
<p id="f8c5d812-fa09-4ec8-8470-399a1fba660c">EBSには、既存ボリュームを直接縮小する操作がないためです。</p>
<p id="1586bae0-94dc-4d41-a82e-12fbe9fa2065">容量拡張はできます。</p>
<p id="80aa4289-b20e-4f92-82ca-23ecea65d9f9">しかし、容量縮小はできません。</p>
<p id="62ef71f7-3ac0-4beb-91aa-2efde27286dd">ここで重要なのは、EBSのサイズだけを見てはいけないということです。</p>
<p id="ddb40e63-dbce-4327-a2bc-4b4e17972110">EC2から見れば、EBSはディスクです。</p>
<p id="71bc1492-28bb-40e0-9638-3b5b1a76cec5">その上にはパーティションがあり、場合によってはLVMがあり、その上にファイルシステムがあります。</p>
<p id="22a57b6c-fb29-449a-81e0-92d98a090e01">仮にディスクの外側だけを小さくできたとしても、OS上のパーティションやファイルシステムとの整合性が崩れれば、データ破損につながります。</p>
<p id="db0d6882-e983-423e-b371-8575dd2522fe">つまり、既存EBSをそのまま小さくするという発想自体が危険です。</p>
<p id="097b6636-6be5-4cdc-bb0d-846aa190dcc6"><strong>案2：AMIから小容量EBSへ復元する</strong></p>
<p id="75a764a7-b12e-437e-b2bd-95bd5ded9f8e">次に考えたのは、既存インスタンスからAMIを取得し、小容量EBS構成で復元する案です。</p>
<p id="3ae5036e-487d-48b7-be9e-53865bdec5a4">バックアップから新しい環境を作り直すだけなので、一見うまくいきそうに見えます。</p>
<p id="2088cca9-1de9-404d-a751-022c9f70cd34">しかし、これも今回の条件では採用できませんでした。</p>
<p id="351451de-53e8-4ec5-80b3-feb2fb74ea02">問題は、元ディスクの構成と、復元先ディスクの容量の整合性です。</p>
<p id="9c72475f-b59c-407f-aac9-4cbc216e5560">AMIから復元する場合、元のブロックデバイス構成、パーティション構成、ファイルシステムの状態が前提になります。</p>
<p id="d345f37f-9bc9-4bb1-8a2b-67595a019e93">その構成を、元より小容量EBSへそのまま復元しようとすると、容量不足や構成不整合が発生します。</p>
<p id="87a2ecc5-9bd6-4352-81ed-8e8a86f8e62d">ここで誤解してはいけないのは、「AMIが使えない」という話ではないことです。</p>
<p id="76d002bf-5b6d-4905-ab60-04331ff3d688">AMIはバックアップや環境複製の手段として有効です。</p>
<p id="64f4e2bb-e64b-4397-99d1-37c3318a2ac5">ただし、今回のように「元より小容量ディスクへそのまま戻す」前提では、単純には成立しません。</p>
<p id="a4b22c78-6d54-449a-8795-385785f69192">OS領域、パーティション構成、LVM構成、ファイルシステムの状態を踏まえずに、</p>
<p id="b6c06530-a732-46e0-b552-9995ec585592">「AMIを取って、小容量EBSで戻せばよい」</p>
<p id="d8b7bca4-f4fa-4a6f-8854-d3dc21d7e3d8">と考えるのは危険です。</p>
<p id="1f8ca2c6-2cd5-447f-ad3f-97b50535dd73"><strong>案3：OS上でバックアップ・リストアする</strong></p>
<p id="def3937d-840b-4eb6-9458-62a42808bc9e">最終的に採用したのは、Linux OS上でデータをバックアップし、小容量EBSを新規作成して、そこへリストアする方法です。</p>
<p id="56e59917-45a6-4ab8-9e3d-cd9918c01f6e">ここで重要なのは、EBSを縮小しているわけではない、ということです。</p>
<p id="b5dc5fcd-d84e-4dd7-8cc8-91fec8bd21f2">小容量EBSを新しく作る。</p>
<p id="cd54b8bd-756f-43bd-ad77-7f49b324876f">そこに必要なデータを戻す。</p>
<p id="f5dc26de-4624-43d1-864e-6f882cc8651f">つまり、これはディスク縮小ではなく、ディスク移行です。</p>
<p id="6d8321a3-f3f9-48eb-8895-19a22a1bb2b4">ただし、この方法にも重要な前提があります。</p>
<p id="869136e5-7ea1-4ef8-a95a-645cc9d52439"><strong>OS上の使用容量が、縮小後のEBS容量よりも小さいこと。</strong></p>
<p id="bf991720-6ed8-4c22-957e-09e7e1be82be">これが満たされない場合、この方法も採用できません。</p>
<p id="e8152cf0-887a-4250-8d4d-99b53cb36e76">たとえば、100GBのEBSを50GBにしたい場合、実際にOS上で使用している容量が50GBを超えていれば、当然ながら移行先に入りません。</p>
<p id="0d997042-5467-4c1a-97ad-8450e4c74a90">「EBSの見かけ上の容量」ではなく、「実際に使用している容量」を確認する必要があります。</p>
<p id="2e1684e5-f127-451e-aecd-57fa08df45c1">XFSを利用している環境では、ファイルシステム単位のバックアップ・リストアとして、`xfsdump` / `xfsrestore`を使う方法があります。</p>
<p id="4703a7bf-87e9-4dbd-a007-a70d8c6c00b8">単純なファイルコピーではなく、ファイルシステムの属性や構造を踏まえて退避・復元したい場合に検討する方法です。</p>
<p id="bdfac2df-eb43-42a0-b69c-cefdf0867d9f">ただし、実際に採用するバックアップ方式は、対象がOS領域なのか、データ領域なのか、停止可能時間、整合性要件、アプリケーション要件によって変わります。</p>
<p id="3ce5d816-2cf8-4fdf-ad10-99d926ac0533">「XFSなら必ずこの方法」という話ではありません。</p>
<p id="74613399-0641-4269-bd23-38367b775cd8">あくまで、今回の条件において選択した方法です。</p>
<p id="dc9b9539-f554-496f-8d7a-da3d1b766ec4">作業の全体像は、以下のようになります。</p>
<ol id="2734fc87-b519-4c1d-86c0-bdabaea27284">
<li>
<p id="059be6e8-f11a-4643-80e0-338172fdd8fe">Linux OS上でデータをバックアップする</p>
</li>
<li>
<p id="372af1ca-ba63-4b9c-a65c-80ba208e6796">小容量EBSを新規作成する</p>
</li>
<li>
<p id="2cf69c06-48b7-4014-83a9-7da321e4d116">Linux OS上でパーティションを設定する</p>
</li>
<li>
<p id="eadb4286-c71b-4c11-a072-851c250c5704">必要に応じてLVMを設定する</p>
</li>
<li>
<p id="f375fab3-ad92-4b77-b262-3180111fcc0f">ファイルシステムを作成する</p>
</li>
<li>
<p id="04d24928-7b83-4faf-a3c2-eccbe9bda0f2">バックアップデータをリストアする</p>
</li>
<li>
<p id="7548cf80-aff8-404c-8504-e74caa27f22e">マウント設定やサービス起動を確認する</p>
</li>
<li>
<p id="c364843e-9363-4b9a-9a6e-6e4a0ef83fcd">アプリケーションの動作確認を行う</p>
</li>
</ol>
<p id="df8b91da-f1dc-4b77-9855-2ff42094e396">ここで大事なのは、バックアップして戻せば終わりではない、ということです。</p>
<p id="45017a22-5a3b-4f8b-a1de-9f01f87c82f7">特に注意したいのが、UUIDとマウント設定です。</p>
<p id="9673d116-3acd-4b91-8610-b4a6367e082f">小容量EBSを新規作成すると、既存EBSとは別のディスクになります。</p>
<p id="5e0cccc8-26c5-40b1-93e2-23a39cecf978">そのため、ファイルシステムのUUIDが変わる場合があります。</p>
<p id="44255ed7-f0ce-4898-9b0c-4ea06e2def3f">`/etc/fstab` でUUIDで指定している場合、移行後のUUIDと設定が一致していないと、OS起動時にマウントできない、起動が遅延する、あるいは起動時にエラーになることがあります。</p>
<p id="f42f873d-2fb6-471b-95c0-87c426957576">また、マウントできたとしても、それだけで作業完了とは言えません。</p>
<p id="bb839123-b5ef-472f-94d7-013079b7dd3e">アプリケーションの起動、ログ出力先、ジョブの出力先、監視・バックアップ対象などは、環境によって確認観点が変わります。</p>
<p id="3f782327-46d3-4834-97d0-b3353025eb6f">そのため、単に「リストアできたか」ではなく、自社の運用定義に合わせて確認観点を整理しておく必要があります。</p>
<h2 id="3b3d1b74-e147-4f0b-87e7-e92b938f2a04" tabindex="-1"><span id="toc5">今回、何が甘かったのか</span></h2>
<p id="0ce75b4c-1f95-4e4b-b57f-4aaaba1c08db">今回の反省点は、単に「EBS縮小の手順を知らなかった」ことではありません。</p>
<p id="6b7ed7b2-fe2d-4d02-8d74-24e7abac720c">もっと根本的には、容量縮小という作業の捉え方が甘かったことです。</p>
<p id="86e71998-93a0-46a9-a91a-ea0a44a52cba"><strong>甘かった点①：削減作業を、移行作業として計画していなかった</strong></p>
<p id="7897e92c-52d9-4285-820f-2c13df46183a">これが一番大きいです。</p>
<p id="6c949cac-baaf-498a-859a-c0baf56fbe13">容量縮小は、見た目にはコスト削減作業です。</p>
<p id="ff74b33b-c25a-4380-ba34-22ce6a9bfa00">不要に大きく確保されたディスク容量を見直し、適正なサイズにする。</p>
<p id="f16b7ac3-6c8e-42e5-b678-38b88b25ff13">そう考えると、単なる設定変更やリソース変更のように見えます。</p>
<p id="2711ad02-b003-4334-8cff-a51497750c06">しかし実態は違います。</p>
<p id="2c002638-11b6-4909-95a4-881063806934">容量縮小は、小容量ディスクへの移行作業です。</p>
<p id="b167c794-a431-420f-87d0-20c0e37ccada">移行作業として捉えていれば、最初から次の観点を計画に入れます。</p>
<ul id="2a6ef46d-7fae-40d4-92c5-da1de173bb5c">
<li>
<p id="2b70893f-cb72-494b-83ab-4ae4b13a0929">どのデータを退避するのか</p>
</li>
<li>
<p id="d7057b67-dbe3-4680-9503-9184adec6108">どの方式でバックアップするのか</p>
</li>
<li>
<p id="6cf169b4-45ad-46d0-99bf-653f598c4358">どれくらい停止時間が必要なのか</p>
</li>
<li>
<p id="bcd5945b-f72a-4ed0-9d83-f456b6760f4c">復元後に何を確認するのか</p>
</li>
<li>
<p id="3094833b-25bb-4639-af4c-33fecbfd0347">失敗した場合、どう切り戻すのか</p>
</li>
<li>
<p id="0b0a12ce-b856-4e55-8228-db4baa243ff7">アプリケーションや運用にどの影響があるのか</p>
</li>
</ul>
<p id="1b00718e-1845-49de-aa56-e9d5ecff4b64">しかし、「縮小作業」とだけ捉えていると、これらの検討が後回しになります。</p>
<p id="25f1a0be-0bcf-4714-aa09-796543a32703">そして作業直前になって、</p>
<p id="80376dd5-ca89-435d-a85a-9df5632c5a7c">「どうやって戻すのか」</p>
<p id="6f6b70ad-d88c-4f99-a8f6-31d0776e4397">「切戻しはどうするのか」</p>
<p id="8716ddfd-52bd-4df7-8cdb-f66084e17bcd">「業務影響はどこまであるのか」</p>
<p id="e33db2be-9ece-4b8c-9677-25e1b3f7a80f">という話になります。</p>
<p id="f45fb439-8c00-46b6-811e-012839a68c0e">これは、かなり危険です。</p>
<p id="c7c1b057-986b-4642-a21e-55fa3614b9cb">容量縮小は、削減作業である前に移行作業です。</p>
<p id="79dce001-7793-4e63-985b-1abc60c7225a">ここを間違えると、作業計画そのものが甘くなります。</p>
<p id="103e698d-727b-4a4d-b9d2-9cfd7af1e27c"><strong>甘かった点②：EBSは増やせるから減らせる、と思い込んでいた</strong></p>
<p id="5c5c1ca1-0ed7-48c9-bd70-c1d6d07a6a5e">次に甘かったのは、拡張と縮小を同じ種類の作業だと考えていたことです。</p>
<p id="252c35b8-11a5-426b-806b-d3bd86ff155e">クラウドのストレージは柔軟に見えます。</p>
<p id="c26203bb-3182-4121-8197-0cefea739e6c">しかし、柔軟なのは主に拡張方向です。</p>
<p id="263883cf-6e61-4b1e-a5f7-38876c22992f">容量を増やす場合は、既存領域を広げる方向の作業になります。</p>
<p id="d69c62cf-61a6-46e0-aea3-4be419c33630">一方で、容量を減らす場合は、既存領域を削るのではありません。</p>
<p id="11109da2-620d-4aee-b998-f825abf5bf23">小さい領域を新しく作り、必要なデータを移す作業になります。</p>
<p id="4c19759f-b1c3-4dae-b035-ebcc69479b6c">この違いを理解していないと、</p>
<p id="e817e6e1-f9b7-49d7-a96e-8c764b78b159">「AWS側でサイズを小さくできないのか」</p>
<p id="1c3756bc-6bb8-41e3-90e1-b66a29c01d6e">「OS側でファイルシステムを縮められないのか」</p>
<p id="e0fe5a14-9042-4969-8dd1-4be8b6e898b5">「AMIで戻せばよいのではないか」</p>
<p id="9cab90e2-586b-41be-9ef4-0268a47fef94">という発想になります。</p>
<p id="f9641ff1-73cc-468f-ab5e-16facfdb81a7">しかし、実務で必要なのは、縮小操作を探すことではありません。</p>
<p id="f45da037-1452-414d-bd18-f6ab4663b1f5">移行方式を設計することです。</p>
<p id="658672a7-de1b-4d8e-bd9b-130973596e7a"><strong>甘かった点③：OS・パーティション・ファイルシステムの関係を軽く見ていた</strong></p>
<p id="15653b14-ca08-4891-ba50-3cf31c2a658f">EBSの容量を変える作業は、AWS側だけでは完結しません。</p>
<p id="a0685030-bf46-407f-96a0-da63628fa6fb">EC2から見れば、EBSはディスクです。</p>
<p id="a451e767-7f2e-4484-995a-59593ae290d1">その上にはパーティションがあります。</p>
<p id="39b8a950-46db-4b3e-b63c-980f7862cc0e">場合によってはLVMがあります。</p>
<p id="af8935c2-627b-407b-ac98-645a1c89f49f">その上にファイルシステムがあります。</p>
<p id="c5edcb8c-2238-4df3-85db-eff68b7eec18">そして、そのファイルシステム上にOSやアプリケーションのデータがあります。</p>
<p id="c4a55cf7-9941-4939-ab01-cd7d276bfafb">この階層を意識せずに作業すると、どこを変更しているのか分からなくなります。</p>
<p id="5a5bdc85-2971-4738-acef-67ad4425136f">EBSを変更しているのか。</p>
<p id="c40243ec-72d5-49ce-83b8-40291fe113aa">パーティションを変更しているのか。</p>
<p id="48a6a549-e744-4a72-a803-59fa5c39ddab">LVMを変更しているのか。</p>
<p id="994d49d1-3996-490f-bc98-63267665e2df">ファイルシステムを変更しているのか。</p>
<p id="79ca84ea-8c6f-49c6-a284-247b49cafa70">マウント設定を変更しているのか。</p>
<p id="3bdb331b-dd8d-4869-90d5-6399484dc434">ここを曖昧にしたまま進めると、OSが起動しない、マウントできない、データが読めない、といった事故につながります。</p>
<p id="564f7d65-b5a9-4af7-8a60-b49241787b40">クラウドを使っていても、OSとファイルシステムの基本は消えません。</p>
<p id="0ec23304-0b78-4848-bdbb-85fc112946ae">むしろ、AWS側の操作とOS側の構造をつなげて理解していないと、簡単そうな作業ほど危険になります。</p>
<h2 id="48f8e04d-4e3f-4007-88c5-feb9d5261ae7" tabindex="-1"><span id="toc6">手順の前に、作業の性質を見極める</span></h2>
<p id="ed8df4a2-90ce-4372-a47e-30f0d729e125">この話は、EBSだけの話ではありません。</p>
<p id="ab595434-2fbf-4d0b-adbb-c9869ada5908">クラウドサービスを使っていると、リソース変更が簡単に見えることがあります。</p>
<ul id="50b204c6-4e5a-42fb-aab8-4579f3cb0586">
<li>
<p id="4657b034-2ff1-4d4f-aaaf-b818ab65784b">CPUを増やす</p>
</li>
<li>
<p id="557219eb-1670-4480-93d5-53a0b0a9e990">メモリを増やす</p>
</li>
<li>
<p id="28a17bc3-a71a-4267-a15e-c18cc99aece0">ディスクを増やす</p>
</li>
<li>
<p id="8c77c469-b10e-436e-b0a0-17126d5f421e">インスタンスタイプを変える</p>
</li>
<li>
<p id="92f81c76-289a-4341-8f5e-215c40f12181">スナップショットを取る</p>
</li>
</ul>
<p id="d2728d18-5bcb-46d0-b2b5-e871fd892516">コンソール上では、確かに操作できます。</p>
<p id="9f2396df-b1d3-4e3f-ba73-739f21f19777">しかし、システムとして安全に変更できるかは別です。</p>
<p id="b2115c61-4e12-4798-82af-3915718256a2">今回の自分の反省も、まさにそこにありました。</p>
<p id="4e46f854-77ff-49ef-a529-ca8ac936f9ce">最初は、容量縮小を「ディスクサイズを小さくする作業」として見ていました。</p>
<p id="7eddeadf-1b9b-4284-94ba-c2554a97690c">だから、まず探したくなるのは、縮小するための手順やコマンドです。</p>
<p id="b5ec08d7-0c15-49c7-9762-c4f70e26153c">しかし実際には、これはサイズ変更ではなく、小容量ディスクへの移行作業でした。</p>
<p id="1a16ee95-a731-4a8f-bcbd-7ed42e4645b7">この見立てが変わると、考えるべきことも変わります。</p>
<ul id="9b4ed41c-b6fb-4436-95b4-e03cb59cc8b5">
<li>
<p id="759bbeec-3421-491e-8a83-41dcca404295">バックアップはどうするのか</p>
</li>
<li>
<p id="5cb21a67-d4f1-454c-81f6-baa3c891bc25">リストアはどうするのか</p>
</li>
<li>
<p id="b1b3cb7a-dfd4-4708-bcc2-aa6f42bb5725">停止時間はどれくらい必要なのか</p>
</li>
<li>
<p id="75442f9b-2871-4391-a097-161ef640361f">失敗した場合、どう切り戻すのか</p>
</li>
<li>
<p id="7ffe957e-dd8f-4e21-a824-79ee8eed65a3">移行後に、OS・アプリケーション・運用の観点で何を確認するのか</p>
</li>
</ul>
<p id="a9941395-31d2-40f7-a6a2-fc6fdd3c0518">作業の性質を見誤ると、手順をどれだけ調べても計画が甘くなります。</p>
<p id="32f01678-40d9-48d0-aa56-b82ac7912d89">逆に、最初に「これは移行作業だ」と捉えられれば、必要な確認観点が見えてきます。</p>
<p id="5bcad22e-2f4a-4296-b354-dfbf37e7a78b">今回の学びは、EBS縮小の具体的な手順そのものではありません。</p>
<p id="f7b4ea00-cc7b-406f-84fb-8c8d7d86d545"><strong>手順の前に、作業の性質を見極めること。</strong></p>
<p id="b1e58983-0fd5-4eb2-9c52-7a3512e55f50">これが、クラウド環境の変更作業では特に重要だと感じました。</p>
<h2 id="ca321933-95f7-482e-bf0f-0aadf94760df" tabindex="-1"><span id="toc7">まとめ</span></h2>
<p id="8fe05796-5a74-4a77-b529-3b10579de72d">EBSの容量縮小は、単なるサイズ変更ではありません。</p>
<p id="0a4caa67-15b5-4d9e-8e1f-63c72ce7b343">拡張は、既存の領域を広げる作業です。</p>
<p id="4c56ef8a-76fd-4bd4-8af6-88e762312d22">縮小は、新しい小容量ディスクへ移し替える作業です。</p>
<p id="94163034-e890-4c8e-89ec-a72697867407">この2つは、同じ種類の作業ではありません。</p>
<p id="f7a48531-f945-460e-b72c-1d098c0a4b26">この違いを理解していないと、作業直前になって次のような状態になります。</p>
<ul id="e719577a-c535-4570-bdb2-faefc62d0a45">
<li>
<p id="3a9a066a-5489-451f-b081-c07bf57893bd">AWS側に縮小操作がない</p>
</li>
<li>
<p id="520bd02d-5fa7-4af8-afe1-b761c8ac1b02">AMIから戻せばよいと思ったが、容量が合わない</p>
</li>
<li>
<p id="75e366aa-f333-4303-bacf-d4bb81bedded">OS上でどう復元するか決めていない</p>
</li>
<li>
<p id="5d566121-4417-467d-a54a-603a05bd6b24">UUIDやマウント設定の確認が漏れている</p>
</li>
<li>
<p id="f1309238-9911-4db4-bbd9-e1a66c304e26">切戻し方針を用意していない</p>
</li>
<li>
<p id="d99fb222-3c1f-479e-b13e-3c1798bd0f0c">動作確認の観点が整理されていない</p>
</li>
</ul>
<p id="45ad7698-927c-436c-9492-259f65595fc0">クラウドだから簡単、ではありません。</p>
<p id="ea733909-d629-4489-9d69-333d2b11ea5c">クラウドを使うほど、インフラの基本が不要になるわけでもありません。</p>
<p id="6e11cfc2-0c60-44d6-9c26-6a835a59fdce">むしろ、AWSの仕様とOSの構造をつなげて理解していないと、簡単そうに見える作業ほど危険になります。</p>
<p id="e3f67bce-bee9-46d7-b262-47e840ba4154">EBSの容量縮小で必要なのは、縮小コマンドを探すことではありません。</p>
<p id="4515e416-5ef5-4cda-b2b6-d5527d7041d7"><strong>「これはディスク移行作業である」と捉え直すことです。</strong></p>
<hr id="fd9b46d7-9522-49ac-8bb8-743c2079c671" />
<p>このあたりは、以下の記事でも詳しく書いています。</p>
<p><a rel="nofollow" href="https://sys-univ.com/dev/detailed-design-overview/" target="_blank">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="11509699-b6e2-4cb5-af51-af3ef3bd772d">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/incident/ebsresize/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CloudWatch Logsのログエクスポートが失敗した話｜「ジョブは動く」と「運用で回る」は別物</title>
		<link>https://sys-univ.com/aws/cloudwatch-logs-export-concurrency/</link>
					<comments>https://sys-univ.com/aws/cloudwatch-logs-export-concurrency/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Mon, 22 Jun 2026 05:32:22 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=2728</guid>

					<description><![CDATA[ログエクスポートのジョブは、正しく書いてある。 IAMも問題ない。 S3バケットも存在する。 ロググループも存在する。 なのに、本番運用で失敗する。 そういうことがあります。 今回起きたのは、CloudWatch Log [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">ログエクスポートのジョブは、正しく書いてある。<br />
IAMも問題ない。<br />
S3バケットも存在する。<br />
ロググループも存在する。</p>


<p class="wp-block-paragraph">なのに、本番運用で失敗する。</p>


<p class="wp-block-paragraph">そういうことがあります。</p>


<p class="wp-block-paragraph">今回起きたのは、CloudWatch Logsのログエクスポートジョブが、日次処理でエラーになるという事象です。</p>


<p class="wp-block-paragraph">CloudWatch Logsのログを、定期的にS3へエクスポートする。</p>


<p class="wp-block-paragraph">AWSを使ったシステムでは、よくある運用設計です。</p>


<p class="wp-block-paragraph">ログをCloudWatch Logsに集約し、一定期間ごとにS3へ退避する。<br />
監査、障害調査、保存期間、コスト、運用保守を考えると、自然な構成に見えます。</p>


<p class="wp-block-paragraph">しかし、今回の本質は、ジョブの実装ミスではありませんでした。</p>


<p class="wp-block-paragraph">問題は、AWSサービスの制約を、運用ジョブ設計とテスト設計に織り込めていなかったことです。</p>


<p class="wp-block-paragraph">CloudWatch Logsのログエクスポートは、ジョブを作れば好きなだけ並列に流せるものではありません。</p>


<p class="wp-block-paragraph">ここを知らないと、単体では正常に動いていたジョブが、本番運用で突然失敗します。</p>



  <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">原因</a></li><li><a href="#toc4" tabindex="0">打った対策と運用の設計観点</a><ol><li><a href="#toc5" tabindex="0">補足：そもそもExportTaskでよかったのか</a></li></ol></li><li><a href="#toc6" tabindex="0">テスト工程で見るべきだったこと</a></li><li><a href="#toc7" tabindex="0">クラウドでも設計は省けない</a></li><li><a href="#toc8" tabindex="0">再発防止として見るべきこと</a></li><li><a href="#toc9" tabindex="0">若手SEに伝えたいこと</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">起きたこと</span></h2>


<p class="wp-block-paragraph">あるシステムで、日次ジョブとしてCloudWatch Logsのログエクスポートを実行していました。</p>


<p class="wp-block-paragraph">処理内容はシンプルです。</p>


<p class="wp-block-paragraph">CloudWatch Logsに出力されたログを、一定期間ごとにS3へエクスポートする。<br />
S3側に保存しておけば、長期保管、調査、監査対応にも使える。<br />
CloudWatch Logs側の保持期間も適切に管理できる。</p>


<p class="wp-block-paragraph">よくある構成です。</p>


<p class="wp-block-paragraph">ところが、日次ジョブで実行しているログエクスポートがエラーになりました。</p>


<p class="wp-block-paragraph">確認すると、ロググループは存在している。<br />
S3バケットも存在している。<br />
IAMロールも大きく間違っていない。<br />
以前は同じ処理が動いていた。</p>


<p class="wp-block-paragraph">にもかかわらず、ジョブが失敗する。</p>


<p class="wp-block-paragraph">この時点で、最初に疑うのは個別設定です。</p>


<p class="wp-block-paragraph">権限が足りないのではないか。<br />
出力先バケットのポリシーが変わったのではないか。<br />
ロググループ名が間違っているのではないか。<br />
対象期間の指定がおかしいのではないか。<br />
Lambdaやシェルの実装に不備があるのではないか。</p>


<p class="wp-block-paragraph">もちろん、それらの確認は必要です。</p>


<p class="wp-block-paragraph">しかし、調べていくと、原因はもっと上位の設計にありました。</p>


<h2 class="wp-block-heading"><span id="toc2">何が問題だったのか</span></h2>


<p class="wp-block-paragraph">問題は、CloudWatch Logsのログエクスポートには、AWS側の制約があるという点です。</p>


<p class="wp-block-paragraph">CloudWatch Logsのログエクスポートでは、CreateExportTaskを使って、ロググループのログをS3へ出力します。</p>


<p class="wp-block-paragraph">このExportTaskには制約があります。</p>


<p class="wp-block-paragraph"><strong>1つのAWSアカウント、1つのリージョンにつき、アクティブなExportTaskは1つしか持てません。</strong></p>


<p class="wp-block-paragraph">ここでいうアクティブとは、実行中または保留中の状態です。</p>


<p class="wp-block-paragraph">つまり、あるログエクスポートタスクがまだ実行中、または開始待ちの状態で残っている場合、同じアカウント・同じリージョン内で次のエクスポートタスクを作成しようとしても失敗する可能性があります。</p>


<p class="wp-block-paragraph">これはAWS公式ドキュメントにも記載されているCloudWatch Logsのクォータです。</p>


<p class="wp-block-paragraph">これが盲点でした。</p>


<p class="wp-block-paragraph">1つのシステムだけを見ていると、この問題は見えにくいです。</p>


<p class="wp-block-paragraph">1つのロググループを対象にしている。<br />
手動で1回だけ実行する。<br />
単体テストで1回だけエクスポートする。</p>


<p class="wp-block-paragraph">この条件なら、正常に見えます。</p>


<p class="wp-block-paragraph">しかし、同じAWSアカウントの同一リージョンの中に複数システムが存在し、それぞれが日次でCloudWatch Logsのエクスポートを実行していると、話が変わります。</p>


<p class="wp-block-paragraph">Aシステムのログエクスポートが実行中。<br />
そのタイミングで、Bシステムのログエクスポートが起動する。<br />
さらに、Cシステムのログエクスポートも同じ時間帯に起動する。</p>


<p class="wp-block-paragraph">それぞれのジョブは、単体で見れば正しい。</p>


<p class="wp-block-paragraph">しかし、アカウント全体で見ると、同時に実行できない処理が重なっている。</p>


<p class="wp-block-paragraph">これでは失敗します。</p>


<p class="wp-block-paragraph">ジョブの中身が間違っていなくても、AWSサービスの制約に引っかかるからです。</p>


<figure id="fc5fa595-aa7a-4582-8171-4bcc58b3e682" class="wp-block-image"><a href="https://assets.st-note.com/img/1780546651-v1RoMmfjWIxeOiyX02qCnFH5.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780546651-v1RoMmfjWIxeOiyX02qCnFH5.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">　　　　　　　　　　　　　　　　　　　　　　　複数システムが同一AWSアカウント／同一リージョンで競合する</figcaption>
</figure>


<p class="wp-block-paragraph">個別には正しい。<br />
しかし、共通のAWSアカウント／リージョン側で競合する。</p>


<p class="wp-block-paragraph">今回の問題は、まさにここでした。</p>


<h2 class="wp-block-heading"><span id="toc3">原因</span></h2>


<p class="wp-block-paragraph">「AWSの制約でした」で終わらせてはいけません。</p>


<p class="wp-block-paragraph">それは調べれば分かる話です。</p>


<p class="wp-block-paragraph">実務で問うべき原因は、もう一段深いところにあります。</p>


<p class="wp-block-paragraph">それは、AWSサービスの制約を、設計時点でジョブ設計・スケジュール設計・テスト設計に落とせていなかったことです。</p>


<p class="wp-block-paragraph">AWSの制約そのものは障害ではありません。<br />
AWSが壊れていたわけではありません。<br />
CloudWatch Logsが異常だったわけでもありません。</p>


<p class="wp-block-paragraph">仕様どおりに動いていただけです。</p>


<p class="wp-block-paragraph">問題は、その仕様を使う側が、運用条件に織り込めていなかったことです。</p>


<p class="wp-block-paragraph">特に、複数システムを1つのAWSアカウントに載せる場合、各システムが独立してジョブを設計すると、こういう問題が起きます。</p>


<p class="wp-block-paragraph">Aシステムの担当者は、Aシステムのログエクスポートだけを見る。<br />
Bシステムの担当者は、Bシステムのログエクスポートだけを見る。<br />
Cシステムの担当者は、Cシステムのログエクスポートだけを見る。</p>


<p class="wp-block-paragraph">個別に見ると、それぞれの設計は間違っていない。</p>


<p class="wp-block-paragraph">しかし、アカウント全体で見ると、同時実行できないジョブが同じ時間帯に並んでいる。</p>


<p class="wp-block-paragraph">この状態では、本番運用で失敗します。</p>


<h2 class="wp-block-heading"><span id="toc4">打った対策と運用の設計観点</span></h2>


<p class="wp-block-paragraph">対策を考えるときに、単純に「エラーになったらリトライすればよい」と考えるのは危険です。</p>


<p class="wp-block-paragraph">もちろん、リトライは必要です。</p>


<p class="wp-block-paragraph">しかし、何も考えずにリトライを入れると、別のシステムのExportTaskがまだ完了していない状態で、同じ失敗を繰り返すだけになります。</p>


<p class="wp-block-paragraph">今回考えるべき対策は、少なくとも次の3つです。</p>


<p class="wp-block-paragraph"><strong>1つ目は、ログエクスポートジョブの実行時間をずらすことです</strong>。</p>


<p class="wp-block-paragraph">同じAWSアカウント・同一リージョン内で複数システムがCloudWatch Logsのエクスポートを行う場合、各ジョブの起動時刻を重ねないようにする必要があります。</p>


<p class="wp-block-paragraph">たとえば、以下のように時間帯を分けます。</p>


<pre class="wp-block-code"><code>変更前：
01:00 Aシステム ログエクスポート
01:00 Bシステム ログエクスポート
01:00 Cシステム ログエクスポート

変更後：
01:00 Aシステム ログエクスポート
02:00 Bシステム ログエクスポート
03:00 Cシステム ログエクスポート
</code></pre>



<p class="wp-block-paragraph">ただし、これは最低限の対策です。</p>


<p class="wp-block-paragraph"><strong>2つ目は、ExportTaskの状態を確認してから、次のタスクを作成することです。</strong></p>


<p class="wp-block-paragraph">ログ量が多い日には、前のエクスポート処理が想定より長引くことがあります。<br />
障害や遅延により、前日のタスクが残っていることもあります。<br />
単純に時刻をずらしただけでは、処理時間の変動に対応できません。</p>


<p class="wp-block-paragraph">そのため、既存のExportTaskの状態を確認し、実行中または保留中のタスクがある場合は、待機する、スキップする、後続へ回す、といった制御が必要になります。</p>


<p class="wp-block-paragraph">処理の流れとしては、以下のような形です。</p>


<pre class="wp-block-code"><code>1. 既存のExportTaskを確認する
2. RUNNINGまたはPENDINGのタスクがあれば待機する
3. 一定時間待っても完了しなければスキップまたは異常終了する
4. 実行可能な状態であれば新しいExportTaskを作成する
5. 作成したタスクIDを記録する
6. 完了状態を確認する
7. 失敗時はリトライまたは運用通知する
</code></pre>



<figure id="42c49159-1326-4192-85fb-5c00695ec2f4" class="wp-block-image"><a href="https://assets.st-note.com/img/1780546820-6ReMw4cFhZBqD0yVdpuX2Glz.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780546820-6ReMw4cFhZBqD0yVdpuX2Glz.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　ExportTask作成前のガード処理フロー</figcaption>
</figure>


<p class="wp-block-paragraph">ここで重要なのは、ジョブの成功条件を「APIを呼べたこと」にしないことです。</p>


<p class="wp-block-paragraph">CreateExportTaskを呼び出せた。<br />
タスクIDが返ってきた。<br />
だから成功。</p>


<p class="wp-block-paragraph">これだけでは不十分です。</p>


<p class="wp-block-paragraph">運用上は、実際にエクスポートが完了し、S3に期待したログが出力されていることまで確認する必要があります。</p>


<p class="wp-block-paragraph"><strong>3つ目は、失敗時の運用を決めておくことです。</strong></p>


<p class="wp-block-paragraph">エクスポートに失敗した場合、翌日にまとめて再実行するのか。<br />
対象期間を分割して再実行するのか。<br />
失敗したロググループだけを再実行するのか。<br />
運用担当者にアラートを出すのか。<br />
一定回数までは自動リトライするのか。<br />
リトライしても失敗した場合、誰が判断するのか。</p>


<p class="wp-block-paragraph">ここまで決めて、初めて運用ジョブの設計になります。</p>


<p class="wp-block-paragraph">「毎日1時にジョブを起動する」だけでは、設計として足りません。</p>


<p class="wp-block-paragraph">「その時間に実行してよい状態か」<br />
「実行できなかった場合にどう扱うか」<br />
「ログ欠損や二重出力をどう防ぐか」</p>


<p class="wp-block-paragraph">ここまで考える必要があります。</p>


<p class="wp-block-paragraph">失敗時の設計観点は、最低でも次のように整理します。</p>


<pre class="wp-block-code"><code>・リトライ回数
・リトライ間隔
・再実行対象期間
・二重出力の扱い
・ログ欠損時の対応
・通知先
・運用手順書への記載
</code></pre>



<p class="wp-block-paragraph">ジョブは、処理を起動するだけではありません。</p>


<p class="wp-block-paragraph">失敗したときに、運用担当者が判断できる状態にしておくところまで含めて、ジョブ設計です。</p>


<h3 class="wp-block-heading"><span id="toc5">補足：そもそもExportTaskでよかったのか</span></h3>


<p class="wp-block-paragraph">ここまでの対策は、CloudWatch LogsのExportTaskを使い続ける前提の話です。</p>


<p class="wp-block-paragraph">しかし、設計としては、そもそもS3へ日次エクスポートする方式でよかったのか、という確認も必要です。</p>


<p class="wp-block-paragraph">障害調査や一時的なログ検索が目的であれば、CloudWatch Logs Insightsで足りるケースもあります。<br />
CloudWatch Logsにログを保持し、必要なときに検索・分析できれば、必ずしもS3へエクスポートしなくてよい場合があります。</p>


<p class="wp-block-paragraph">一方で、長期保管、監査対応、CloudWatch Logsの保持期間外の保存、S3を前提にしたログ管理が必要であれば、S3への保存は必要になります。</p>


<p class="wp-block-paragraph">その場合も、日次のExportTaskだけが選択肢ではありません。</p>


<p class="wp-block-paragraph">リアルタイム性が必要な場合や、ExportTaskの同時実行制約を避けたい場合は、CloudWatch LogsのサブスクリプションフィルターからAmazon Data Firehoseへ連携し、Firehose経由でS3へ配信する構成も検討対象になります。</p>


<p class="wp-block-paragraph">つまり、対策は「ExportTaskの起動時間をずらす」だけではありません。</p>


<p class="wp-block-paragraph">ログの用途、保存期間、検索頻度、監査要件、リアルタイム性、コスト、運用負荷を踏まえて、そもそものログ保存方式を選ぶ必要があります。</p>


<p class="wp-block-paragraph">今回のようなトラブルは、単にジョブを直すだけでなく、ログ運用方式そのものを見直すきっかけにもなります。</p>


<h2 class="wp-block-heading"><span id="toc6">テスト工程で見るべきだったこと</span></h2>


<p class="wp-block-paragraph">今回の話で重要なのは、設計だけではありません。</p>


<p class="wp-block-paragraph">テスト工程でも、見方を間違えるとこの問題は見逃されます。</p>


<p class="wp-block-paragraph">単体テストでは、CloudWatch LogsからS3へエクスポートできるかを確認します。</p>


<p class="wp-block-paragraph">これは必要です。</p>


<p class="wp-block-paragraph">ロググループを指定する。<br />
対象期間を指定する。<br />
S3バケットに出力される。<br />
IAMロールで実行できる。<br />
エラー時にログが出る。</p>


<p class="wp-block-paragraph">ここまでは確認します。</p>


<p class="wp-block-paragraph">しかし、単体テストで1回エクスポートが成功しても、本番運用で問題なく回ることは保証できません。</p>


<p class="wp-block-paragraph">結合テストでは、ジョブスケジューラから起動できるか、LambdaやシェルからAWS APIを呼べるか、S3に出力されるか、異常時に通知されるかを確認します。</p>


<p class="wp-block-paragraph">これも必要です。</p>


<p class="wp-block-paragraph">しかし、それでもまだ足りません。</p>


<p class="wp-block-paragraph">システムテストや運用テストでは、実際の運用に近い条件で確認する必要があります。</p>


<p class="wp-block-paragraph">たとえば、次のような観点です。</p>


<pre class="wp-block-code"><code>・同じAWSアカウント内に複数システムが存在する
・同一リージョン内で複数のログエクスポートジョブが日次で動く
・ログ量が多い日にExportTaskの完了が遅れる
・前日のExportTaskが残っている状態で翌日のジョブが起動する
・他システムのExportTask実行中に自システムのジョブが起動する
・失敗した場合に再実行すると対象期間が重複する
・スキップした場合にログ欠損が起きる
・運用担当者が失敗に気づける
・通知を受けた担当者が、何を見て判断すればよいか分かる
</code></pre>



<p class="wp-block-paragraph">ここまで見ないと、運用ジョブとしての品質は確認できません。</p>


<p class="wp-block-paragraph">「1回エクスポートできた」ことと、<br />
「毎日、運用として成立する」ことは別です。</p>


<p class="wp-block-paragraph">これは、テスト工程で非常に重要な考え方です。</p>


<p class="wp-block-paragraph">機能確認だけなら、1回エクスポートできれば合格に見えます。</p>


<p class="wp-block-paragraph">しかし、運用確認として見るなら、複数システム、複数ジョブ、ログ量増加、遅延、再実行、通知、手順まで確認しなければいけません。</p>


<p class="wp-block-paragraph">テスト工程は、単に「作ったものが動くか」を見る工程ではありません。</p>


<p class="wp-block-paragraph">設計した運用が、実際の条件で破綻しないかを確認する工程です。</p>


<h2 class="wp-block-heading"><span id="toc7">クラウドでも設計は省けない</span></h2>


<p class="wp-block-paragraph">今回の気づきは、CloudWatch LogsのExportTask制約そのものではありません。</p>


<p class="wp-block-paragraph">それは調べれば分かります。</p>


<p class="wp-block-paragraph">本当の気づきは、クラウドサービスを使う場合、設計対象は自分たちが作った処理だけではないということです。</p>


<p class="wp-block-paragraph">AWSのマネージドサービスを使うと、OSやミドルウェアを自分たちで管理しなくてよい部分が増えます。</p>


<p class="wp-block-paragraph">それは大きなメリットです。</p>


<p class="wp-block-paragraph">しかし、その代わりに、サービスごとの仕様、クォータ、非同期処理、状態遷移、リトライ設計、料金体系を理解する必要があります。</p>


<p class="wp-block-paragraph">CloudWatch Logsのエクスポートも同じです。</p>


<p class="wp-block-paragraph">画面上は簡単に見えます。<br />
APIも用意されています。<br />
S3へ出力できるので、仕組みとしてはシンプルに見えます。</p>


<p class="wp-block-paragraph">しかし、実運用では、同時実行数、処理時間、ログ量、再実行、監視、通知まで考える必要があります。</p>


<p class="wp-block-paragraph">クラウドだから簡単になる部分はあります。</p>


<p class="wp-block-paragraph">しかし、クラウドだから設計しなくてよい、という話ではありません。</p>


<p class="wp-block-paragraph">むしろ、クラウドサービスの仕様を知らないまま設計すると、オンプレとは別の形で詰まります。</p>


<p class="wp-block-paragraph">オンプレでは、サーバ、ディスク、ネットワーク、ジョブスケジューラ、ミドルウェアの制約を見ていました。</p>


<p class="wp-block-paragraph">クラウドでは、そこにAWSサービスごとの制約が加わります。</p>


<p class="wp-block-paragraph">サービスを使うだけなら簡単です。</p>


<p class="wp-block-paragraph">しかし、業務システムとして運用するなら、サービスの制約まで含めて設計する必要があります。</p>


<h2 class="wp-block-heading"><span id="toc8">再発防止として見るべきこと</span></h2>


<p class="wp-block-paragraph">同じ問題を繰り返さないためには、個別ジョブを修正するだけでは不十分です。<br />
<br />
今回のような問題は、担当者がCloudWatch LogsのExportTask制約を知っていれば防げます。<br />
しかし、知らない人が設計すれば、また同じことが起きます。<br />
<br />
だからこそ、個人の知識や注意力に頼るのではなく、設計レビューやテスト計画の観点として残しておく必要があります。<br />
<br />
以下は、設計レビューやテスト計画にそのまま転用できる形で整理したチェックリストです。</p>


<pre class="wp-block-code"><code>・使用するAWSサービスのクォータを確認したか
・アカウント単位、リージョン単位の制約を確認したか
・同一アカウント内の他システムと競合しないか
・同一リージョン内で競合するジョブがないか
・同時実行できない処理を並列に起動していないか
・ジョブの起動時刻だけでなく、完了時刻も考慮したか
・処理時間が長引いた場合の後続影響を確認したか
・前回処理が残っている場合の動作を決めたか
・リトライ時に二重処理やログ欠損が起きないか
・スキップ時にどのように検知するか決めたか
・失敗時に誰が、どの通知で、何を見て判断するか
・運用手順書に再実行方法を記載したか
・運用テストで複数システム同時稼働を確認したか
</code></pre>



<p class="wp-block-paragraph">このような観点を、設計レビューやテスト計画に入れておく。</p>


<p class="wp-block-paragraph">それが再発防止のために見るべきことです。</p>


<p class="wp-block-paragraph">今回のような問題は、担当者個人の注意力だけに頼ると再発します。</p>


<p class="wp-block-paragraph">CloudWatch LogsのExportTask制約を知っている人がいれば防げる。<br />
知らない人が設計するとまた起きる。</p>


<p class="wp-block-paragraph">それでは、組織として弱いです。</p>


<p class="wp-block-paragraph">だから、レビュー観点にする。<br />
テスト観点にする。<br />
運用設計のチェックリストにする。</p>


<p class="wp-block-paragraph">これが、実務では必要になります。</p>


<h2 class="wp-block-heading"><span id="toc9">若手SEに伝えたいこと</span></h2>


<p class="wp-block-paragraph">若手SEのうちは、どうしても「処理が動くか」に意識が向きます。</p>


<p class="wp-block-paragraph">コマンドが成功した。<br />
APIが通った。<br />
S3にファイルが出た。<br />
ジョブが正常終了した。</p>


<p class="wp-block-paragraph">もちろん、それは大事です。</p>


<p class="wp-block-paragraph">しかし、実務ではそれだけでは足りません。</p>


<p class="wp-block-paragraph">本番では、他のシステムも動いています。<br />
他のジョブも動いています。<br />
ログ量も日によって変わります。<br />
AWSサービス側の制約もあります。<br />
障害時には再実行もあります。</p>


<p class="wp-block-paragraph">だから、設計では「単体で動くか」だけでなく、「運用全体の中で成立するか」を見なければいけません。</p>


<p class="wp-block-paragraph">CloudWatch Logsのログエクスポート失敗は、小さなトラブルに見えるかもしれません。</p>


<p class="wp-block-paragraph">しかし、ここには大事な教訓があります。</p>


<p class="wp-block-paragraph"><strong>ジョブは、処理単体ではなく、運用全体で設計する。</strong></p>


<p class="wp-block-paragraph">そして、</p>


<p class="wp-block-paragraph"><strong>テストは、機能確認ではなく、運用で破綻しないことを確認する工程である。</strong></p>


<p class="wp-block-paragraph">この視点がないと、クラウドでもオンプレでも、同じように運用で詰まります。</p>


<p class="wp-block-paragraph">AWSを使うこと自体は難しくありません。</p>


<p class="wp-block-paragraph">しかし、AWSを使って業務システムを安定運用するには、サービス仕様、制約、ジョブ設計、監視、再実行、テスト工程までつなげて考える必要があります。</p>


<p class="wp-block-paragraph">「1回動いたから大丈夫」</p>


<p class="wp-block-paragraph">この考え方が、本番運用では一番危ないです。</p>


<p class="wp-block-paragraph">単体で動くことと、運用で回ることは違います。</p>


<p class="wp-block-paragraph">この違いを理解しているかどうかが、実務のSEとしてかなり大きな差になります。</p>
<p>今回の話は、単なるCloudWatch Logsの制約の話ではなく、<br />
「ジョブ単体では動く」ことと、<br />
「本番運用で毎日回る」ことは別物である、という話でもあります。</p>
<hr />
<p>このあたりは、以下の記事でも詳しく書いています。</p>
<p><a rel="nofollow" href="https://sys-univ.com/dev/detailed-design-overview/" target="_blank">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="11509699-b6e2-4cb5-af51-af3ef3bd772d">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/aws/cloudwatch-logs-export-concurrency/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RHELで使えた設定方法が、Amazon Linuxでは使えなかった｜MTU設定に見る、OS差分と永続化確認の落とし穴</title>
		<link>https://sys-univ.com/aws/mtusetting/</link>
					<comments>https://sys-univ.com/aws/mtusetting/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Mon, 03 Oct 2022 05:10:47 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1475</guid>

					<description><![CDATA[構築作業が終わり、確認コマンドでも想定どおりの値になっている。 「これで設定完了です」 そう報告したあと、OSを再起動したら設定が戻っていた。 クラウド環境でインスタンスを再作成したら、同じ設定が入っていなかった。 イン [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="aec80593-f0fa-4915-810d-3119e89cea6f">構築作業が終わり、確認コマンドでも想定どおりの値になっている。</p>
<p id="c11efdeb-ff6c-493c-ae23-d5efdb1984de">「これで設定完了です」</p>
<p id="449f078f-76b2-4940-be7d-f73dc20dc82c">そう報告したあと、OSを再起動したら設定が戻っていた。<br />
クラウド環境でインスタンスを再作成したら、同じ設定が入っていなかった。</p>
<p id="c8df7210-8dbc-44d7-a07c-75203f2fb6fe">インフラ構築では、こういうことが起きます。</p>
<p id="62ef42e3-bf5c-4a1f-91d3-dad6916da403">特に危ないのは、作業直後には正しく見えるケースです。</p>
<p id="cc8e3c02-bdc7-4fc2-a237-147c98379ddb">コマンドを実行した。<br />
設定値も変わった。<br />
疎通もできた。</p>
<p id="1a0c8037-932a-4551-8d0c-fcc8c875d8a2">だから大丈夫だと思っていた。</p>
<p id="621740dd-f3dc-45b7-bf0b-4b26ba007a8a"><strong>しかし、再起動後、AMI化後、インスタンス再作成後、DHCP更新後に設定が戻る。<br />
</strong><br />
本番運用でこれが起きると、単なる作業ミスでは済まなくなります。</p>
<p id="dcf0ac41-a8a5-469a-a64e-2976e4b0f375">今回は、<strong>MTU設定</strong>を題材にします。</p>
<p id="e16d71fc-2b3f-4eb7-bbea-7b29cb4d9217">MTUとは、ネットワークで一度に送れるパケットサイズの上限です。</p>
<p id="5a3eab60-bddf-4b07-a204-eab600e92de8">通常のWebシステムでは、普段あまり意識しないかもしれません。<br />
しかし、クラウド環境、VPN、Direct Connect、閉域接続、ジャンボフレーム、オンプレからクラウドへの移行などが絡むと、MTUは設計・構築・試験で確認すべき項目になります。</p>
<p id="a997677c-1592-4ba7-834b-b49912909b5d">今回のトラブルは、次のようなものでした。</p>
<p id="e8027bc1-1de3-445b-830c-dc74ba451537">RHEL7の環境では、NetworkManager を使ってMTUを設定していた。<br />
ところが、Amazon Linux 2の環境では、同じように設定しようとしても、RHEL7と同じ前提では作業できなかった。</p>
<p id="dd7cf0d2-dfd9-4565-bda9-48e59176d865">つまり、<strong>RHELで使っていた設定手順を、そのままAmazon Linux 2に横展開できなかった</strong>のです。</p>

  <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">問題は「MTUの設定方法を知らなかったこと」ではない</a></li><li><a href="#toc3" tabindex="0">なぜこういうことが起きるのか</a></li><li><a href="#toc4" tabindex="0">RHEL7ではNetworkManager、Amazon Linux 2では別の見方が必要だった</a></li><li><a href="#toc5" tabindex="0">一番怖いのは、設定できたように見えてしまうこと</a></li><li><a href="#toc6" tabindex="0">設定確認は「今」だけで終わらせない</a></li><li><a href="#toc7" tabindex="0">このトラブルを防ぐための確認観点</a></li><li><a href="#toc8" tabindex="0">詳細設計と構築手順では「設定値」だけでなく「反映と確認」まで書く</a></li><li><a href="#toc9" tabindex="0">試験項目では「今の設定値」だけを見ない</a></li><li><a href="#toc10" tabindex="0">レビューでは設定値ではなく、設定が残る仕組みを見る</a></li><li><a href="#toc11" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 id="b63cb731-5120-4545-ac30-026aaeff5bbb" tabindex="-1"><span id="toc1">何が起きたのか</span></h2>
<p id="a93f3eff-8ff2-446f-9592-d913a3f6afe0">ある環境で、ネットワークインターフェースのMTU値をカスタマイズする必要がありました。</p>
<p id="4c7e4a88-e238-4714-b48e-7a3f3094e61f">RHEL7の環境では、次のように nmcli を使って設定していました。</p>
<div class="code-block-container">
<pre id="e88d6e43-2fe1-44af-b402-4ac4ab28b9b7" data-name="preCode"><code class="hljs swift" data-name="code">nmcli <span class="hljs-built_in">c</span> modify <span class="hljs-string">"My favorite connection"</span> ethernet.mtu <span class="hljs-number">1600</span>
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="61add955-6eba-488d-9c7a-8d2a588a9c03">nmcli は、NetworkManagerを操作するためのコマンドです。</p>
<p id="1ec68c27-aedc-4e82-b9bb-77ac8518a4c3">NetworkManagerが管理している接続設定に対して、MTU値などを変更できます。</p>
<p id="2aa32fd6-fd5a-4187-b883-d3d2ad091f63">この場合、設定内容は結果的に以下のようなファイルにも反映されます。</p>
<div class="code-block-container">
<pre id="3d63a0c4-bfbe-45a7-bc30-12fbf5650c44" data-name="preCode"><code class="hljs" data-name="code">/etc/sysconfig/network-scripts/ifcfg-XXXX
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="5b838b50-8cab-435d-9e10-c3e6c71ac56f">そのため、RHEL7で構築経験がある人からすると、</p>
<p id="eebd7c6a-b32f-446b-aaa8-2c1a57679ca5">「MTUを変えるなら、nmcli で設定すればよい」</p>
<p id="82b1e9dc-27ad-445e-b4bd-83b3860baff0">という感覚になりがちです。</p>
<p id="3b684b64-4cae-4953-ab11-6c188bd25dea">しかし、今回のAmazon Linux 2環境では、同じ前提が成り立ちませんでした。</p>
<p id="b2f2c27e-9403-41e8-9af6-a14517ed119e">RHEL7と同じように NetworkManager.service を前提にした構成ではなく、nmcli 前提の手順をそのまま使うことができなかったのです。</p>
<h2 id="d4d44757-45e9-4e64-b1e3-fbf8c1c1b6df" tabindex="-1"><span id="toc2">問題は「MTUの設定方法を知らなかったこと」ではない</span></h2>
<p id="37f3fd70-c536-4834-be02-34d4e668a2db">ここで大事なのは、</p>
<p id="ba727c03-febc-4a8b-a051-358b180955a6">「Amazon Linux 2では、このファイルを編集しましょう」</p>
<p id="a66ee79b-995c-4725-b007-d05a67824c94">という単純な話ではありません。</p>
<p id="03d640ea-6d21-4679-b8f9-f43c69f5b6dc">本質的な問題は、<strong>OSが変わったにもかかわらず、ネットワーク設定の管理方式が同じだと思い込んだこと</strong>です。</p>
<p id="bc0bee59-c43b-4766-b533-bcba73c41ef4">Linuxといっても、すべてが同じではありません。</p>
<p id="f31113ce-4670-4a50-b578-608c6a9bfdee">RHEL、CentOS、Amazon Linux、Ubuntu、Oracle Linuxなど、ディストリビューションが違えば、設定ファイルの場所、サービス管理の考え方、ネットワーク設定の反映方法、標準で有効になっているサービスが変わることがあります。</p>
<p id="ad8fe594-ffbe-468c-987f-3a6fb14cd817">さらに、同じRHEL系に見えても、バージョンやクラウドイメージの作りによって、デフォルト構成が違うこともあります。</p>
<p id="fd138906-917c-4857-bb22-f7e8444a603d">つまり、</p>
<p id="55c8774a-a64f-4069-87e4-4aa7806428bc">「前の案件で動いた」<br />
「RHELではこうだった」<br />
「Linuxだから同じだろう」</p>
<p id="e5e0eeb6-b8a9-4f18-98b5-159e05462f20">という判断は、インフラ構築では危険です。</p>
<h2 id="81dd49bb-c588-461f-aec4-28ed1a7762f8" tabindex="-1"><span id="toc3">なぜこういうことが起きるのか</span></h2>
<p id="4f4d4c8e-7dc4-480b-85b5-76d00e6ff2c7">オンプレミス環境のLinuxと、クラウド環境のLinuxでは、サーバの作られ方が違います。</p>
<p id="df0891d4-3c72-4d68-99c5-da9d9ecf06bd">オンプレミスでは、OSをインストールし、ネットワーク設定を作り込み、固定的なサーバとして長期間運用することが多くあります。</p>
<p id="eba446bc-d7f6-4d7f-a4cf-a59bdf96c088">一方、クラウド環境では、AMIなどのイメージからインスタンスを起動し、起動時にIPアドレス、ホスト名、鍵情報、ネットワーク関連の初期設定などが自動的に構成されることがあります。</p>
<p id="411a1f97-d122-4020-8dbb-0c416d5b5cbe">Amazon Linux 2のようなクラウド向けのOSイメージでは、オンプレミスのRHEL環境と同じ管理サービス構成になっているとは限りません。</p>
<p id="75a5a556-7d48-41d6-972d-37fdccee9b5e">そのため、NetworkManagerだけでなく、network service、DHCP、cloud-init、AMI作成時の状態など、複数の仕組みが関係する場合があります。</p>
<p id="d1f38bba-cd91-4fe7-97d5-440eb17e23cd">今回の環境では、RHEL7で使っていたNetworkManager前提の設定手順を、そのまま使える構成ではありませんでした。</p>
<p id="3bb2e7af-3c12-4a86-a4b4-37aa188a55bc">見るべきポイントは、</p>
<p id="abf9247e-9521-4fe0-b324-53037ba7fa67">「どのOSか」</p>
<p id="69ff822c-21be-4efe-899f-aebce59fee3c">だけではありません。</p>
<p id="d8f5311a-1dba-4df3-81d3-1a0429ae8e55">より正確には、</p>
<p id="caea0fe4-faa3-439b-be65-a2ce0bb90d21">「そのOSイメージでは、ネットワーク設定を何が管理しているのか」</p>
<p id="72aaabc9-2727-45f1-a0bb-c63a435470b4">です。</p>
<p id="9ac4a5ec-260a-4bbc-b6d9-3cb5267007fa">ここを確認せずに手順を横展開すると、設定が反映されない、再起動後に戻る、別インスタンスでは挙動が違う、というトラブルにつながります。</p>
<p id="98d50e7e-b7de-4f85-b6fd-aae1c3efedcc">なお、Amazon Linux 2023では、さらに事情が変わります。</p>
<p id="4ccd5dd9-598d-4311-8199-38c902d9fce5">AWS公式ドキュメントでは、AL2023では `systemd-networkd` がネットワークインターフェースを管理し、AL2で使われていた `dhclient` から変更されていると説明されています。</p>
<p id="56615450-c388-4c2f-bb60-e3f8fa8f8bb1">つまり、Amazon Linux 2で確認した手順も、Amazon Linux 2023にそのまま横展開できるとは限りません。</p>
<h2 id="431a1056-2710-429a-b3a5-c882c9e34308" tabindex="-1"><span id="toc4">RHEL7ではNetworkManager、Amazon Linux 2では別の見方が必要だった</span></h2>
<p id="ef9c712f-4b0c-4dcc-9f97-92bce0c8a7ea">今回の差分を簡単に整理すると、以下のようになります。</p>
<figure id="1e3252c4-535b-43c6-a6f4-150bde55b7b8"><a href="https://assets.st-note.com/img/1780964845-vz9RTZ6Vsj5e4PpuntySLHmE.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780964845-vz9RTZ6Vsj5e4PpuntySLHmE.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="269b6f88-c1b6-427b-97af-11e6ff7b3ed9">RHEL7では、NetworkManagerがネットワーク設定の中心になっている環境があります。</p>
<p id="04bcdb31-e8e6-4888-9216-f3d824a4f426">その場合、nmcli で接続プロファイルを変更することが自然な方法になります。</p>
<p id="002b70a7-6afa-4a8b-a4de-66a04809161d">一方で、Amazon Linux 2では、環境によってはNetworkManagerを前提にできません。</p>
<p id="3b04325d-4a03-46b7-bc1c-563fc989c800">そのため、インターフェース設定ファイルやDHCPクライアント設定、起動時にネットワーク設定へ関わる仕組みを確認する必要があります。</p>
<p id="a42d013c-69dd-4d65-a750-2e81fa23bbe1">たとえば、インターフェース側では以下のような設定ファイルを確認します。</p>
<div class="code-block-container">
<pre id="d10850bf-e4a2-42d6-9edd-948aedecbbc1" data-name="preCode"><code class="hljs" data-name="code">/etc/sysconfig/network-scripts/ifcfg-eth0
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="282114ac-77c2-461e-b722-144fda9d80d5">MTU値を指定する場合、環境に応じて次のような設定を追加・変更します。</p>
<div class="code-block-container">
<pre id="a4dc8d95-1739-449a-85ab-ecb0ed543f0b" data-name="preCode"><code class="hljs" data-name="code">MTU=1600
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="4d780b00-8318-4fac-93d9-63e97d482eec">さらに、DHCPでネットワーク設定を取得している場合は、DHCPクライアント側の設定も確認対象になります。</p>
<div class="code-block-container">
<pre id="4899517a-e9c4-46fd-853c-3859d0147938" data-name="preCode"><code class="hljs" data-name="code">/etc/dhcp/dhclient.conf
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="46110550-e96f-4c2d-bff3-15fc2bbf7a01">ここで出てくるコマンドやファイルパスを、すべて丸暗記する必要はありません。</p>
<p id="54410ff8-e443-4d3b-8800-1726d85c29a3">大事なのは、個別のコマンドを覚えることではなく、</p>
<p id="78e6ce8a-e6b5-4faf-8e7e-22824eaa13e8">「誰がネットワーク設定を管理しているのか」<br />
「どこに書けば再起動後も残るのか」<br />
「何に上書きされる可能性があるのか」</p>
<p id="d2f48d67-8712-4c1d-8dba-3012b973b4ac">という構造を押さえることです。</p>
<figure id="749c37c5-cdd9-42bc-9729-e4babe7fac2a" data-align="center"><a href="https://assets.st-note.com/img/1780621641-carLuhgPyj5CT2ApKYS4knql.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780621641-carLuhgPyj5CT2ApKYS4knql.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="88a98c40-fbd4-4476-bbc5-721c44db9290">この図で見てほしいのは、設定値の違いではありません。</p>
<p id="3baf05ab-296b-415f-943f-f0ce13f9577a">同じMTU設定でも、RHEL7ではNetworkManager経由、Amazon Linux 2では設定ファイルやDHCP関連の確認が中心になる、という<strong>設定経路の違い</strong>です。</p>
<h2 id="9c190c47-2b87-4a38-b3e1-9e9d09fee8fd" tabindex="-1"><span id="toc5">一番怖いのは、設定できたように見えてしまうこと</span></h2>
<p id="d178ebba-f9f7-434d-b59f-c3b3e6c0f230">この手のトラブルで怖いのは、最初から完全に失敗してくれるとは限らないことです。</p>
<p id="1f3ebb15-8085-4755-a926-d7aa6e89c59e">コマンドが存在しない。<br />
サービスが存在しない。<br />
設定ファイルが見つからない。</p>
<p id="bae35c12-c208-4855-8c33-263e423f2660">ここまで分かりやすく失敗してくれれば、まだよいです。</p>
<p id="0fd89c9c-f73e-459f-8f99-8d120fe6fe86">問題は、<strong>設定したつもりになっているケース</strong>です。</p>
<p id="c5f5f33f-4bfa-4ab4-b6a5-e7ef5897d7c1">たとえば、次のようなコマンドで確認したとします。</p>
<div class="code-block-container">
<pre id="ee2984fe-cb7f-4812-a97a-573bfa5a6900" data-name="preCode"><code class="hljs" data-name="code">ip link show eth0
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="5539e4f4-dc96-4c3c-9edc-5f2f874c3806">その時点では、MTUが変わっているように見える。</p>
<p id="d73eb59a-06e2-4bd0-a505-b8bcaa56366d">しかし、ネットワークサービスを再起動すると戻る。<br />
OSを再起動すると戻る。<br />
AMIから再作成すると戻る。<br />
DHCP更新後に戻る。<br />
別のインスタンスでは挙動が違う。</p>
<p id="2028e23f-e87b-443a-b6bb-7ae61838d795">この場合、作業者の感覚としては、</p>
<p id="b0de435d-b7fe-4676-a5e1-c30a04f55f21">「設定したのに戻った」<br />
「なぜか環境によって違う」<br />
「手順通りにやったのに再現しない」</p>
<p id="97f8458d-8222-4c17-a380-57f36d92a33f">となります。</p>
<p id="0e16f2e8-2331-4f6a-811c-e9bb5056f049">しかし、原因はシンプルです。</p>
<p id="d8329e15-f81d-4d07-8800-e50d44ff31f0"><strong>その設定が、永続化される場所に入っていなかった。</strong><br />
または、<br />
<strong>永続化したつもりの設定が、別の仕組みに上書きされていた。</strong></p>
<p id="30b53f24-d2bd-4492-858a-57afec7086ff">作業直後に設定値が変わることと、運用中もその設定が維持されることは、別の話です。</p>
<h2 id="ce3c3ec8-b7b3-461b-b972-66653b5e9be9" tabindex="-1"><span id="toc6">設定確認は「今」だけで終わらせない</span></h2>
<p id="0e7550a2-b192-4ad9-90a7-25567d176c84">MTU設定後に ip link show eth0 で確認することは必要です。</p>
<p id="64c23201-0e2c-4293-8987-6e1abc777f0d">しかし、それは「今そうなっている」ことを見ているだけです。</p>
<p id="d1ca4136-3744-4069-8f0d-b1e9cd11adf1">インフラ構築では、設定直後だけでなく、network再起動後、OS再起動後、AMI化・再作成後、DHCP更新後まで確認します。</p>
<ul id="49768f84-3f60-4e34-a276-599ce2a85a9e">
<li>
<p id="a6a94918-e1c5-4d68-88e4-76cf2652d703">設定直後にMTUが変わっているか</p>
</li>
<li>
<p id="1723accc-9679-47ae-ae2e-0d5fa9e5e521">network再起動後も維持されるか</p>
</li>
<li>
<p id="d2bc8525-d577-4673-ae15-9c5e9b64cbd9">OS再起動後も維持されるか</p>
</li>
<li>
<p id="0c528687-6ab9-44bc-8311-b993d710f241">AMI化・再作成後も維持されるか</p>
</li>
<li>
<p id="38a638ee-61ad-4366-98a5-c19057da24d2">DHCP更新後に戻らないか</p>
</li>
</ul>
<figure id="6c3037b6-b6ce-482c-8db9-b90146745f90" data-align="center"><a href="https://assets.st-note.com/img/1780621751-QXH3kKSWs6iNpnxMfJDPVGoI.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780621751-QXH3kKSWs6iNpnxMfJDPVGoI.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="2435e595-df32-40ae-9afc-e5619f94d396">この図で伝えたいのは、「今変わっているか」だけでなく、<strong>戻らないか</strong>まで見る必要がある、ということです。</p>
<h2 id="90825d49-519a-4f4a-83ec-19b6b861a997" tabindex="-1"><span id="toc7">このトラブルを防ぐための確認観点</span></h2>
<p id="494fa3c5-ea03-4ce1-b199-8adfd835fcc6"><strong>1. ネットワーク設定の管理方式を確認する</strong></p>
<p id="b208e563-57e2-4b28-8be7-4aed8b3e7740">対象OSでネットワーク設定を何が管理しているかを最初に確認します。</p>
<div class="code-block-container">
<pre id="dc300757-dc37-42f9-8619-c2bcede29ce0" data-name="preCode"><code class="hljs" data-name="code">systemctl status NetworkManager
systemctl status network
ls -l /etc/sysconfig/network-scripts/
cat /etc/sysconfig/network-scripts/ifcfg-eth0
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="b6874985-2c55-4da2-beec-7bcd4dafb404">見るべきなのは、コマンドが使えるかどうかだけではありません。</p>
<p id="eb65fd43-ecae-455c-8d6a-a5f4d520530f">そのサービスがOS起動時に使われているか。<br />
対象インターフェースを管理しているか。<br />
設定ファイルの内容と実際の状態が合っているか。</p>
<p id="424fd0ac-ea6d-496d-859c-fa46e0ec03f2">ここまで確認します。</p>
<p id="ec210bcf-b497-401a-81bd-53c043906d17"><strong>2. 一時設定と永続設定を分ける</strong></p>
<p id="758511c3-82fe-44d0-9075-f73a1738f1eb">MTUは、一時的に変更するだけなら次のようなコマンドでも変更できます。</p>
<div class="code-block-container">
<pre id="66a1ec71-88b1-4027-9687-9aac86cfb05e" data-name="preCode"><code class="hljs javascript" data-name="code">ip link <span class="hljs-keyword">set</span> dev eth0 mtu 1600
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="efd571ed-f67e-4f7f-ac44-a2d6f36739a7">しかし、これは基本的に一時的な変更です。</p>
<p id="b5cfb3c5-87e8-4d43-af3f-ae209bc41db4">OS再起動後に維持されるかは別問題です。</p>
<p id="30d124c1-eeee-4ff1-b555-49037e267ae3">一時設定で確認するのか。<br />
永続設定として設計するのか。</p>
<p id="8cb51758-74fb-42eb-91e6-5c88c9e22c92">ここを混同すると、構築時は動いていたのに、本番運用で戻るということが起きます。</p>
<p id="95e891d3-bf24-4db4-8344-68c635af0a4f"><strong>3. DHCPやcloud-initによる上書きを確認する</strong></p>
<p id="aef6ab87-d9cf-4ee5-975b-654510914963">クラウド環境では、OSが起動した後に、DHCPやcloud-initなどがネットワーク設定に関わることがあります。</p>
<p id="34b8a460-6023-4f29-8d6a-19bdd5dfd47d">そのため、設定ファイルに値を書いただけでは不十分な場合があります。</p>
<p id="80396ac6-651d-4129-9e85-a54ca60ba36f">確認すべきことは、たとえば次のような点です。</p>
<ul id="86475a68-aad1-4511-a882-20a06a16f0fc">
<li>
<p id="9a781b7c-8960-442b-b9f2-303b220d9264">DHCPで取得した設定によりMTUが上書きされないか</p>
</li>
<li>
<p id="fa75f086-c3fb-462c-b057-aef7ae4f4828">dhclient.conf で明示的な設定が必要か</p>
</li>
<li>
<p id="63d26f57-2f47-4979-aebb-c97f50e9d1ae">cloud-initが起動時にネットワーク設定を生成・変更していないか</p>
</li>
<li>
<p id="0829283f-4a97-449b-923e-ef17bf4e45f9">AMI化した後、別インスタンスで同じ設定が再現されるか</p>
</li>
</ul>
<p id="aa2f3916-8648-4278-bc62-b053912b72b5">さらに対策として、手作業で変更した内容を、AMI作成手順、構築手順、構成管理、または自動構築の仕組みに反映しておく必要があります。</p>
<h2 id="3f333a38-ffb2-487b-80e2-7e95b91a50a7" tabindex="-1"><span id="toc8">詳細設計と構築手順では「設定値」だけでなく「反映と確認」まで書く</span></h2>
<p id="31e43114-d0ba-4bf8-904b-f6d1634be3b1">詳細設計書に、</p>
<figure id="d7d1210c-2ebf-4bf4-9705-63f773ffd98f">
<blockquote>
<p id="8f7cb816-0620-4ca2-988e-62b0f6db185c">MTUを1600に設定する</p>
</blockquote><figcaption></figcaption></figure>
<p id="dde411c9-9eda-4c74-8167-e9d611214817">とだけ書いてあったとします。</p>
<p id="c1b65f39-848e-434c-b2f1-739c919ec657">設定値だけでは、構築する側は判断できません。<br />
少なくとも次の情報が必要です。</p>
<div class="code-block-container">
<pre id="de5c32bb-2c50-465a-b383-ec97ee6969b2" data-name="preCode"><code class="hljs" data-name="code">対象OS：
  Amazon Linux 2

対象インターフェース：
  eth0

設定値：
  MTU=1600

設定箇所：
  /etc/sysconfig/network-scripts/ifcfg-eth0

DHCP設定：
  /etc/dhcp/dhclient.conf の更新要否を確認

反映方法：
  networkサービス再起動、またはOS再起動

確認方法：
  ip link show eth0
  ping疎通
  必要に応じてパケットサイズ指定で疎通確認

永続化確認：
  OS再起動後もMTU値が維持されること
  AMI化・再作成後もMTU値が維持されること
  DHCP更新後にMTU値が戻らないこと
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<p id="5bf20dac-924d-46e0-bbf1-656395df921b">これくらい書いて、ようやく構築・試験できる設計になります。</p>
<p id="cd861f7b-ba17-415e-912f-62a8fa49282d">構築手順書に落とす場合も同じです。</p>
<p id="879c304e-ebc5-44d0-a1be-c08be6796864">手順書には、設定コマンドだけでなく、変更前確認、変更後確認、再起動後確認、必要に応じてAMI化・再作成後の確認まで含める必要があります。</p>
<p id="52b7b141-4d0b-4656-9492-b0cd533c3aab">たとえば、作業の流れとしては次のようになります。</p>
<div class="code-block-container">
<pre id="ca595290-f71c-4dea-bb1c-b8e546bcb1bf" data-name="preCode"><code class="hljs" data-name="code">1. 現在のMTU値を確認する
2. 対象インターフェースを確認する
3. ネットワーク設定の管理方式を確認する
4. 設定ファイルやDHCP設定を修正する
5. network再起動またはOS再起動で反映する
6. MTU値を確認する
7. OS再起動後に再確認する
8. 必要に応じてAMI化・再作成後に再確認する
</code></pre>
<div class="a-button__inner" data-v-00506f85=""> </div>
</div>
<h2 id="b49759d3-9c19-41be-b20a-7d78d2c1c44e" tabindex="-1"><span id="toc9">試験項目では「今の設定値」だけを見ない</span></h2>
<p id="824e8aca-54b5-457e-9b57-661df5d110f7">ip link show eth0 だけでは「今の状態」しか分かりません。<br />
実務では次の観点まで確認します。</p>
<figure id="a1001a90-43f7-43fa-b9c1-884357164964" data-align="center"><a href="https://assets.st-note.com/img/1780622118-0H7rql89SgVGFEKXPO6oyjsw.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780622118-0H7rql89SgVGFEKXPO6oyjsw.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="c9004c73-04cf-4a54-8873-fd1fad2d3c08">特にクラウド環境では、AMI化・再作成後の確認が重要です。</p>
<p id="ebd62679-178b-4ada-8803-469f2fac026a">Auto Scalingや障害復旧で新しいインスタンスが起動したときに設定が戻るなら、構築時に確認できていても運用には耐えません。</p>
<h2 id="f4ba7c9d-70a7-4344-be1d-8ea775b83681" tabindex="-1"><span id="toc10">レビューでは設定値ではなく、設定が残る仕組みを見る</span></h2>
<p id="b693d8c3-d935-4789-a7a2-e647ad2e7466">MTU設定の設計書や手順書をレビューするなら、次のような観点で見ます。</p>
<ul id="e97a01fa-d576-46d6-a3b5-d42158300c34">
<li>
<p id="83c97e2a-0ab5-45e0-b8d9-a8e2c35555fa">対象OS・バージョン・対象インターフェースが明記されているか</p>
</li>
<li>
<p id="f4e6c4b5-7f9e-4503-98e5-31f334ba7fab">設定箇所と反映方法が明記されているか</p>
</li>
<li>
<p id="1d1b063b-122d-4d88-ae1b-4247f244ef3b">NetworkManager前提か、network service前提かが明記されているか</p>
</li>
<li>
<p id="0a80f59a-6ae2-48b5-ba95-4d76aa5f2bab">DHCP・cloud-initの影響を確認しているか</p>
</li>
<li>
<p id="0d5ada20-d55a-431d-8dde-40f899f4e704">OS再起動後の確認があるか</p>
</li>
<li>
<p id="990a9110-6c12-433a-a43f-e438c68f741b">AMI化・再作成後の確認があるか</p>
</li>
</ul>
<p id="b46ccb60-64e3-452e-85de-309e0c9fdbb0">「MTU=1600と書いてあるからOK」では、このトラブルは防げません。<br />
設定値ではなく、設定が残る仕組みまで見ることがレビューのポイントです。</p>
<h2 id="c7dea103-5b0c-40c2-b418-d2c949f8d3ef" tabindex="-1"><span id="toc11">まとめ</span></h2>
<p id="9cf4b455-b3d0-467e-b15c-c695fa8d8c10">今回のトラブルは、RHEL7とAmazon Linux 2でMTU設定方法が違っていた、という事例です。</p>
<p id="8abd743e-9ad3-4441-98f5-506bc66efdd6">ただし、学ぶべきことは「Amazon Linux 2ではこのファイルを編集する」という単純な話ではありません。</p>
<p id="fb55b832-b66e-4de1-98a6-f4ad6035c65a">重要なのは、以下です。</p>
<ul id="22fff5b1-e13f-47b4-a832-ff9046aba507">
<li>
<p id="3a58c13e-3bed-49b9-b3f1-826aa08c71d9">OSが変われば、設定の管理方式も変わる</p>
</li>
<li>
<p id="e3855094-0351-45b4-973e-2d97280b8e3f">コマンドではなく、管理している仕組みを見る</p>
</li>
<li>
<p id="6a843259-feeb-4ed0-84aa-38bbcab8641d">設定直後だけでなく、再起動後・再作成後も確認する</p>
</li>
<li>
<p id="c58ef937-90ed-40ba-b465-275e97e78a79">詳細設計では、設定値だけでなく設定箇所・反映方法・確認方法まで書く</p>
</li>
<li>
<p id="b8b9307e-5b21-456e-aa44-1bf2b610133c">クラウド環境では、AMI化・再作成後も同じ設定になるかを見る</p>
</li>
</ul>
<p id="7a67735c-d585-4821-8ff9-a44c2df2cc30">コマンドを知っていること以上に、その設定がどの仕組みに管理され、再起動後も維持されるのかを確認できること。</p>
<p id="1c2313cc-ebc1-4407-8607-1142f7fadaf2">この視点が、インフラ構築の品質を分けます。</p>
<p id="b7c3e600-282f-43c9-8c22-15a4035e8224"><strong>関連記事</strong></p>
<p id="a74373b3-48ac-4d9e-bfc4-77c788da1cac">今回の記事で扱った「設定値だけでなく、設定箇所・反映方法・確認方法・永続化確認まで設計に落とす」という考え方は、以下の記事でも整理しています。</p>
<p><a rel="nofollow" href="https://sys-univ.com/dev/detailed-design-overview/" target="_blank">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="977be368-4c93-44ea-9dfc-2cb25d028cce">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/aws/mtusetting/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【AWS】別AZで起動したWindowsが通信不能に｜原因はVPCではなく「OS内のルート情報」だった</title>
		<link>https://sys-univ.com/aws/addroute/</link>
					<comments>https://sys-univ.com/aws/addroute/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Tue, 04 Oct 2022 03:00:28 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1493</guid>

					<description><![CDATA[セキュリティグループも見た。 NACLも見た。 VPCルートテーブルも見た。 それでも通信できない。 そんなとき、原因はAWSコンソールの中ではなく、OSの中にあるかもしれません。 今回扱うのは、EC2を別AZで起動した [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="520c1fbf-2ede-41b1-994c-13ebd9a6950e">セキュリティグループも見た。<br />
NACLも見た。<br />
VPCルートテーブルも見た。</p>
<p id="bdf24a40-c78c-4282-a5dd-f17d3711dca3">それでも通信できない。</p>
<p id="54740cae-ca78-4bfe-a5b6-705cfb958d64">そんなとき、原因はAWSコンソールの中ではなく、OSの中にあるかもしれません。</p>
<p id="e309d140-47b7-4e48-9bfa-f53bd87488d2">今回扱うのは、EC2を別AZで起動した際に、Windows ServerのOS内ルート情報が更新されず、通信できなくなった事象です。</p>
<p id="2443481b-b38c-4cd5-9218-cd644f43373a">この記事では、単なるルート設定の話ではなく、EC2Launch、User Data、AMI再利用、DR設計で見落としやすい「起動後のOS状態」について整理します。</p>

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-10" checked><label class="toc-title" for="toc-checkbox-10">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">EC2は起動した。でも通信できない</a></li><li><a href="#toc2" tabindex="0">AZ移動後、Windowsサーバが通信できない</a></li><li><a href="#toc3" tabindex="0">原因はEC2Launchの起動時処理だった</a></li><li><a href="#toc4" tabindex="0">対策は「OS起動ごとに必要な処理を実行させる」こと</a></li><li><a href="#toc5" tabindex="0">AWS側の設定だけ見ても足りない</a></li><li><a href="#toc6" tabindex="0">これはルーティングだけの話ではない</a></li><li><a href="#toc7" tabindex="0">なぜクラウドはOS設定を書き換えるのか</a></li><li><a href="#toc8" tabindex="0">DR設計では「起動できる」だけでは足りない</a></li><li><a href="#toc9" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 id="c8671a81-fd99-4eed-8b0b-16236561ffb3" tabindex="-1"><span id="toc1">EC2は起動した。でも通信できない</span></h2>
<p id="ac9bf7a0-d792-4e16-b53c-53a92e61f89b">EC2インスタンスを別AZで起動した。</p>
<p id="56009cfd-145a-4a49-a20c-ec797d51d345">インスタンスの起動は成功している。<br />
OSも上がっている。<br />
しかし、通信できない。</p>
<p id="33d27af2-9d34-4b3e-9f5d-007a1e39d3ed">このような事象が起きると、まずAWS側の設定を疑うと思います。</p>
<p id="f122f626-784b-427d-b739-6aa4455103b4">セキュリティグループがおかしいのか。<br />
NACLで止められているのか。<br />
サブネットのルートテーブルが間違っているのか。</p>
<p id="6fd185d9-7227-4a8d-b05b-3524bf620ee8">もちろん、それらは確認すべきです。</p>
<p id="97be70f4-ab23-4f38-b041-1e5864d48c7c">しかし、今回の原因はそこではありませんでした。</p>
<p id="7128f477-a6cd-4887-831f-b67500912c9c">問題は、Windows OS内のルーティング情報が、移動先AZに合わせて更新されていなかったことでした。</p>
<h2 id="a3a5eaa4-c886-4635-bde5-7da292d728fd" tabindex="-1"><span id="toc2">AZ移動後、Windowsサーバが通信できない</span></h2>
<p id="8be28339-3a1a-4d0a-9219-76da3f8698d7">今回の事象は、AZ障害時の切替を想定した環境で発生しました。</p>
<p id="59bb9556-58f5-43f8-88c8-322329457d7e">通常時は、あるAZでWindows ServerのEC2インスタンスを稼働させています。</p>
<p id="da117454-26d7-4584-bed8-181589631070">障害時には、別AZでインスタンスを起動し、業務を継続する想定でした。</p>
<p id="99a6c266-c60f-4a74-b71f-f4ec02836cc9">構成としては、クラウドではよくある考え方です。</p>
<figure id="c4b2b1e1-5f67-43f6-bc8a-0236391e1678"><a href="https://assets.st-note.com/img/1780473466-Rbf2paQvm8dgSjYeAcN19LlP.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780473466-Rbf2paQvm8dgSjYeAcN19LlP.png?width=1200" alt="画像" width="620" height="439" data-modal="true" /></a><figcaption>別AZでEC2を起動できても、起動後に通信できるとは限らない</figcaption></figure>
<p id="c1be95ca-8ac6-4547-b9ff-57afc1258861">ただし、この構成で注意すべきなのは、「別AZでEC2が起動できること」と「起動後に業務通信が成立すること」は別問題だという点です。</p>
<p id="f2598e8d-5c12-42cd-88f0-be155b8b78ff">今回も、インスタンスの起動自体は成功していました。</p>
<p id="695718a0-cbf9-4a6e-b4eb-866039f64326">OSも起動していました。</p>
<p id="f8eacf54-fb85-415b-a364-3dbabf6d0731">ところが、正常なネットワーク通信ができませんでした。</p>
<p id="d3d10523-d178-4f61-bfa1-e114d517222b">AWS側の設定だけを見れば、サブネット、セキュリティグループ、NACL、VPCルートテーブルを疑いたくなります。</p>
<p id="1df1b1ab-d696-4ef8-a1a8-acb0c2d8ea39">しかし、調査していくと、問題はWindows OS内部のルーティング情報にありました。</p>
<p id="66ba10a6-bae5-4343-ae15-8c486fa08344">移動先AZで必要となるルート情報が、OS起動時に追加されていなかったのです。</p>
<p id="dfc6dca6-adf2-4a12-9188-a28a1c22db3d">ここで重要なのは、VPCのルートテーブルではなく、Windows OS内のルート情報だという点です。</p>
<p id="33322f9d-1790-43cf-aa11-e1863b2d4044">では、なぜOS内にルート情報が必要になるのでしょうか。</p>
<p id="8c305441-a343-4c47-8ae7-007810946f97">たとえば、次のような構成を考えてみます。</p>
<p id="4cdbe14f-e1d8-4b46-bd7e-6fbd6f755d0c">通常の業務通信は、デフォルトゲートウェイから出す。<br />
一方で、監視サーバ向けのセグメント 172.16.10.0/24 には、2枚目のNIC、つまり別ENI側の経路を使って通信させる。</p>
<p id="98542b5a-80a3-47db-9711-5d897318ef13">この場合、Windows OS内には、</p>
<div class="code-block-container">
<pre id="46d69c23-cf13-40a2-8ebb-c072fbf2aee7" data-name="preCode"><code class="hljs" data-name="code">172.16.10.0/24 は、2枚目のNIC側の経路へ向ける
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="fee2c283-960a-4d4c-b754-aef9747089d7">というスタティックルートが必要になります。</p>
<p id="558bd618-473e-4872-b4f1-c98941fdd35e">VPCルートテーブルが正しくても、Windows OS内にこのルートがなければ、監視サーバ向けの通信は期待した経路に流れません。</p>
<p id="d28e64a9-5ed9-4074-811c-634190aecfa4">EC2はクラウド上の仮想サーバです。</p>
<p id="6420f64d-4848-4fcc-b51d-885a1590558c">しかし、サーバである以上、OSの中にもネットワーク設定があります。</p>
<p id="287de988-c449-45bd-933f-f4daa1edf4b4">クラウド側の設定だけでは、通信は完結しません。</p>
<p id="714591fe-82e4-43d5-a195-bcbebdccdcce">さらに、別AZで起動すると、通常は起動先のサブネットも変わります。</p>
<p id="c67abc63-67e0-435e-b423-e1903ea6e1af">サブネットやENI構成が変われば、OS内のスタティックルートで前提にしていたネクストホップ（次に経由するルーターやゲートウェイのIPアドレス）　　やインターフェースが、移動先の環境と合わなくなることがあります。</p>
<p id="2e61561a-0f65-42b6-b5b9-713341bd8895">しかし、AMIを取得した時点のOS内ルート情報には、旧環境を前提にした経路が残っている場合があります。</p>
<p id="b24f9cda-53c0-47b5-8c77-eb1426745f06">そのまま別AZで起動すると、ルートのエントリは存在しているのに、実際には期待した経路へ到達できない。</p>
<p id="6c8da315-1f88-4c00-b62e-8e52f9d0880a">これが、</p>
<p id="de020489-a57e-4e8b-849d-4db0decf00a5">「設定した覚えはあるのに通信できない」</p>
<p id="04d9981e-06be-48eb-9e9c-eba36d62f716">という事象の正体です。</p>
<h2 id="99877098-61b6-496c-848d-5dd548e51304" tabindex="-1"><span id="toc3">原因はEC2Launchの起動時処理だった</span></h2>
<p id="b48b74a5-65a3-4e18-9b13-bda3220b0a70">原因は、Windows Serverの起動時に動く初期化処理でした。</p>
<p id="18317afc-79f3-4f82-a242-aed5963f82af">Windows Server 2012 R2以前では、EC2Configというサービスが使われていました。</p>
<p id="ac3131f8-dfdc-4399-a5dd-b3c6834e78d7">一方、Windows Server 2016 / 2019では、EC2Launch v1が使われる構成があります。</p>
<p id="8d0a940b-bc2d-4b5d-a36f-27b49ffb694b">ここで見落としやすいのは、</p>
<p id="48da3542-dbca-4370-9abe-edd7ecdc348a">「Windows Serverなら、起動時に毎回同じ初期化処理が走る」</p>
<p id="858ea04d-9c9a-43ba-9a03-e9bc1e26eca1">とは限らないことです。</p>
<p id="4c1c9119-37e9-4b70-8d94-a8cb3f4e45f8">今回のポイントはここです。</p>
<p id="041b0076-981e-4bad-9489-1765f91126a6">AMIを取得する前のインスタンスで、すでに初回起動時の処理が終わっている。<br />
その状態をAMIとして固める。<br />
そのAMIから別AZで起動する。<br />
しかし、OSや初期化エージェントの状態としては、必要な処理が「初回起動時のみ実行済み」と扱われる。<br />
その結果、別AZで起動したときに、ルート追加処理が走らない。</p>
<p id="41cc4ac3-908f-4b8b-8fb7-18b291af7f98">このような流れになると、EC2自体は起動しているのに、OS内のルート情報が移動先AZに合わないまま残ります。</p>
<p id="290b3c4f-ad31-4814-be17-76c2d6054a39">その結果、サーバは起動したのに通信できない、という状態になります。</p>
<p id="41d6073d-d6ec-47c3-81a0-db5ec5d68053">若手SEがここで学ぶべきなのは、OSの設定そのものだけではありません。</p>
<p id="0db4176e-26e0-42cc-a8c0-ea7c85ded38a">「その設定は、いつ、どの仕組みによって入るのか」</p>
<p id="89352f38-55e4-4543-9e66-648f12fbfa74">を見る必要があるということです。</p>
<p id="46863647-a47d-4a45-b7a0-99eb63d5563a"><strong>EC2Config、EC2Launch v1、EC2Launch v2をざっくり押さえる</strong></p>
<p id="c6e08fd5-bcb1-42c3-b0f4-69a1e9e4bb19">細かい仕様をすべて暗記する必要はありません。</p>
<p id="618b2056-2e7a-4003-8d36-db5d1f9e9707">ただ、Windows EC2の初期化エージェントには世代差があることは押さえておくべきです。</p>
<div class="code-block-container">
<pre id="215f7c23-ee25-42a0-b706-21d6c14f0329" data-name="preCode"><code class="hljs" data-name="code">Windows Server 2012 R2以前
  → EC2Config

Windows Server 2016 / 2019の一部AMI
  → EC2Launch v1

Windows Server 2022 / 2025、
一部のWindows Server 2016 / 2019 AMI
  → EC2Launch v2
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="43d53b97-fb56-4681-934e-44fb90837075">現在は、EC2Launch v2への移行が進んでいます。</p>
<p id="0cbdd46c-2d54-4c1c-ad7b-25048e174389">EC2Launch v2では、「どのタスクを、どのステージで、どの頻度で実行するか」を管理する考え方になります。</p>
<p id="56e59873-f8b1-4f9e-9428-6c2b298e2a85">見るべきポイントは、バージョン名そのものではありません。</p>
<p id="8916d201-98b3-4ee3-84a0-3fcde6a88e2b">実務では、以下を確認します。</p>
<div class="code-block-container">
<pre id="4bbbaade-a532-4ed3-b45d-9601e4422c4f" data-name="preCode"><code class="hljs" data-name="code">・対象OSは何か
・EC2Config、EC2Launch v1、EC2Launch v2のどれか
・User Dataは初回だけか、毎回か
・起動時タスクは有効か
・タスクの実行頻度は once か always か
・初期化処理のログにエラーは出ていないか
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="8cba2820-2c79-425c-add8-3051f9c43dbb">特にEC2Launch v2では、User Dataもタスクとして扱われるため、実行頻度が once なのか always なのかを確認する必要があります。</p>
<p id="2434891b-d0f2-4600-897d-a014256aabb0">ここを確認しないままDR設計や移行設計を進めると、机上では成立しているのに、切替時に通信できないサーバが立ち上がることがあります。</p>
<p id="48dd7e54-4fbf-4684-a2c2-b8a735faddc2">なお、EC2Launch v2には agent-config.yml などの設定ファイルがありますが、この記事では詳細な設定手順までは踏み込みません。</p>
<p id="9236ab5f-5d3b-4392-b644-d9a4dd5b615e">ここで重要なのは、ファイル名を暗記することではなく、起動時に実行されるタスクと実行頻度を確認する、という考え方です。</p>
<p id="5e6fb7ed-ef69-4bb7-8d94-1a669b884a22"><strong>なぜ永続ルートではなく、起動ごとの処理なのか</strong></p>
<p id="13927e36-ea3c-4e62-a312-d57257a46815">ここで、こう思う人もいるかもしれません。</p>
<p id="3666f2cf-9f9e-4b60-b988-7b15a9961709">「Windowsなら route add -p で永続ルートにすればよいのでは？」</p>
<p id="50f1ad2d-7685-4627-b4dc-4491a3121ad9">たしかに、固定的な経路であれば、それで済む場合もあります。</p>
<p id="09e30b34-392f-4089-854c-8e0a56a90a7f">route add -p は、Windowsで再起動後も残るルートを登録する方法です。</p>
<p id="c1bc12c6-6759-4387-abd1-f8ece513f74f">しかし、クラウド移行やAZ切替では、単純な永続ルートだけでは不十分な場合があります。</p>
<p id="b16c09d2-221c-457a-b387-e34f7e44bcc1">なぜなら、起動先のAZ、サブネット、ENI構成、ゲートウェイ、経路設計によって、追加すべきルートが変わることがあるからです。</p>
<p id="672a0c0f-57b1-4f93-8326-28f5d4815a21">AMIに固定ルートを焼き込んでしまうと、元のAZでは正しくても、別AZでは古い経路を引きずる可能性があります。</p>
<p id="defa0de7-9de4-4b96-b717-63719bece69d">たとえば、元の環境では `10.0.1.1` 側を通る前提でOS内にルートを持っていたとします。</p>
<p id="2f1e7c26-126f-41ab-b46d-65fd68a70832">しかし、別AZで起動した後は、サブネットやENI構成が変わり、`10.0.2.1` 側を通すべき構成になっているかもしれません。</p>
<p id="f6adfcbc-97ec-40c2-a19c-850f7dd3340a">このとき、OS内に旧環境のルートが残ったままだと、設定は存在しているのに、移動先環境では正しい経路に通信が流れません。</p>
<p id="c0f012db-e45f-4526-a8e7-84fc922b3805">一方、起動ごとのスクリプトでルートを追加する方式なら、起動先の環境に合わせて必要なルートを入れ直す設計にできます。</p>
<p id="fdfd37e4-556b-491d-9966-08f4b296a18b">もちろん、その分だけスクリプト設計は慎重に行う必要があります。</p>
<p id="272f33d3-2e68-4fcd-a812-c24db7c26af6">特に重要なのが、冪等性です。</p>
<p id="c66f034f-4e56-426a-9401-23e0235104a5">冪等性とは<strong>「同じ処理を何度実行しても、結果が壊れず同じ状態に収まる性質のこと」</strong>です。</p>
<p id="83472d99-91b3-472a-b240-2ea13f788f0d">起動のたびに実行される処理は、何度実行しても壊れないように作る必要があります。</p>
<p id="4c7ca025-bd64-4f21-bcc9-fd6f6cd9f7eb">たとえば、同じルートを毎回追加しようとしてエラーになる。<br />
既存設定を無条件で上書きしてしまう。<br />
途中で失敗したときに中途半端な状態が残る。</p>
<p id="595cc8a9-9868-46e0-bb64-254f2601bf48">こうした作りになっていると、初期化処理そのものが新しい障害原因になります。</p>
<h2 id="ffb4b76d-d9d7-4cd8-ac35-4ea4923847d2" tabindex="-1"><span id="toc4">対策は「OS起動ごとに必要な処理を実行させる」こと</span></h2>
<p id="b99140a8-5071-4048-ba68-94bf2247b63a">今回の対策は、OS起動ごとに必要なルート追加処理が実行されるようにすることでした。</p>
<p id="d9074ce8-8323-4a49-98dc-1ddfdc458a6d">EC2Launch v1の場合、単に「起動すれば自動で全部整う」と考えるのではなく、起動時に必要な処理が実行される状態になっているかを確認する必要があります。</p>
<p id="2ca816d6-31b8-44a9-bf5b-239ca6df67de">たとえば、今回のようなルート追加であれば、User DataからEC2Launchのモジュールを読み込み、`Add-Routes` を呼び出す方法があります。</p>
<div class="code-block-container">
<pre id="3c15d7d2-f4b4-4fbd-bff8-b73d09d6d9da" data-name="preCode"><code class="hljs ruby" data-name="code">Import-Module (Join-Path $env<span class="hljs-symbol">:ProgramData</span> <span class="hljs-string">'Amazon\EC2-Windows\Launch\Module\Ec2Launch.psd1'</span>)
Add-Routes</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="d43e0ea1-daca-4392-9978-83e22dbf4642">さらに、User Dataを起動ごとに実行したい場合は、persist を有効にします。</p>
<div class="code-block-container">
<pre id="fc69529c-b693-4730-9298-0452a352f91e" data-name="preCode"><code class="hljs javascript" data-name="code">&lt;persist&gt;<span class="hljs-literal">true</span>&lt;<span class="hljs-regexp">/persist&gt;</span></code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="36300f10-9445-4356-a2dd-cbe9d108de37">これにより、インスタンス起動時にUser Dataの処理が繰り返し実行され、移動先環境に合わせたルート追加処理を走らせることができます。</p>
<p id="ebfe3831-d78c-4893-bf03-78d06e21cb52">重要なのは、コマンドそのものを暗記することではありません。</p>
<p id="cce9e892-0477-43e2-920e-934e57f50d92">タスクスケジューラ、User Data、EC2Launchのどの仕組みによって、起動時の処理を実行させているのかを理解することです。</p>
<p id="f01fcead-b950-40a8-bbd7-63ae65fbff3b">EC2Launch v2では、この種の起動時タスクの扱いが整理されており、同じ問題が起きにくい構成になっています。</p>
<p id="49cb7bbc-6b39-4a46-b3b3-d1077715a9ee">ただし、実際の挙動は、AMIの世代、EC2Launchのバージョン、User Data、タスクの実行頻度に依存します。</p>
<p id="454bb55a-a98e-48f6-a49f-b2ba01163394">そのため、v2だから確認不要、とは考えない方が安全です。</p>
<p id="9546e064-917d-45a0-98e6-6e575ffea0c9">環境によって確認ポイントは変わります。</p>
<p id="a1d6843a-1495-48f5-ae71-174cb79e8f15">しかし、共通する考え方は同じです。</p>
<p id="fe9f05a2-93ed-42d5-afce-876646e15a59">「起動時に、必要なOS設定が、確実に反映される状態になっているか」</p>
<p id="5f4a3331-5b6a-4ff0-991c-3d41e67d7027">ここを確認する必要があります。</p>
<h2 id="a646f83e-76e1-4a3d-9fdf-5207130cc22e" tabindex="-1"><span id="toc5">AWS側の設定だけ見ても足りない</span></h2>
<p id="9cd7c1d7-ec90-419e-8ba4-2800e2e09d7c">若手SEにとって、EC2の通信不可というと、どうしてもAWS側の設定に目が行きます。</p>
<p id="eb2369b5-f961-4003-9a70-46c60b5bba5a">それ自体は間違いではありません。</p>
<p id="1cf8e9b7-0c39-4958-8d5e-1c4dd771fbd5">実際、通信不可の原因として、セキュリティグループ、NACL、VPCルートテーブル、サブネット、ENI、DNS設定などはよくあります。</p>
<p id="bb05981f-4562-4edd-b493-22f488800052">しかし、それだけでは足りません。</p>
<p id="8b8feb07-8fb6-4dc9-9b56-1ebcca31342c">今回のように、OS内部の設定が原因になることもあります。</p>
<p id="70f08156-abe7-412c-8fd0-8122ff77b59c">今回の切り分けは、3つの層で見ると整理しやすくなります。</p>
<div class="code-block-container">
<pre id="b657639a-00e7-41bc-a6c0-708533387c30" data-name="preCode"><code class="hljs" data-name="code">AWSインフラ層
  → セキュリティグループ、NACL、VPCルートテーブルを見る

初期化エージェント層
  → EC2LaunchやUser Dataが期待どおり実行されたかを見る

OS設定層
  → Windowsのルーティングテーブルが移動先環境に合っているかを見る
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="2a8b25ca-8d1b-4138-9243-86fb830658a5">今回の原因は、AWSインフラ層ではなく、初期化エージェント層とOS設定層の間にありました。</p>
<p id="008ff45d-0f6d-4718-876c-921dbe2ac2e2">EC2の通信確認では、AWS側の設定、クラウド初期化処理、OS内部の設定を一連の流れとして見る必要があります。</p>
<figure id="34ae7188-7c91-481f-b108-8c5b3bed636f"><a href="https://assets.st-note.com/img/1780473510-jpmDS8wUoYf6e4PZRXhbilrK.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780473510-jpmDS8wUoYf6e4PZRXhbilrK.png?width=1200" alt="画像" width="620" height="439" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="b7610046-233b-42f1-bfec-c32ee4771b31">この図で言いたいのは、EC2が起動した時点で確認が終わるわけではない、ということです。</p>
<p id="e8bd6263-71e5-47d2-bd61-a81e6efae9c3">AWS側の設定が正しく、インスタンスが起動していても、その後に動く初期化処理やOS内部の設定が想定どおりでなければ、業務通信は成立しません。</p>
<p id="a433a55b-2556-4ce8-bcff-6360b67c154c">サーバが起動していることと、業務通信が成立していることは別です。</p>
<p id="944bd7c5-1a7c-4b0b-a392-5a53b6845d77">ここを混同すると、DRテストや移行リハーサルで痛い目を見ます。</p>
<h2 id="88eefb7d-79fc-49c6-a6f2-2becfa26dfe3" tabindex="-1"><span id="toc6">これはルーティングだけの話ではない</span></h2>
<p id="b497ca4f-e0f8-4987-8d88-7c06627610d7">今回の事象は、Windows Serverのルーティング情報が更新されなかった、という個別トラブルに見えます。</p>
<p id="b5187475-b14b-4be9-930e-2fc920563bba">しかし、これはルーティングだけの話ではありません。</p>
<p id="c8fd7ac7-e7f6-473b-a32b-382e493bb8c0">以前扱ったような、MTU設定が戻る、SSHでログインできない、OS起動後に想定した設定になっていない、といった事象にも共通する構造があります。</p>
<p id="e48a4680-2290-4c0f-b16d-332b33aa3e16">共通しているのは、初期化エージェントがOS設定を書き換える、または書き換えないことで、起動後のOS状態が想定とずれる点です。</p>
<p id="e0ca0382-7430-4122-a56e-d4da26079a32">ある設定は、初期化エージェントによって上書きされます。</p>
<p id="7f3b890b-44f6-43bf-9d76-02ffedd1bcc3">別の設定は、初期化エージェントが実行されないために更新されません。</p>
<p id="a72179eb-5b83-4733-9aa9-a9bcd559fad8">つまり、</p>
<p id="9e46566e-43e3-496b-a39f-cf69a57d9efe">「書き換えられて困る」</p>
<p id="cc4dbf88-fc42-4ff6-af57-eba774015879">場合もあれば、</p>
<p id="5868f75e-2a3d-411e-ab45-1ab4d8565d1c">「書き換えてほしいのに書き換わらない」</p>
<p id="bfe239b1-65a2-4b53-9f94-a1f495208493">場合もあります。</p>
<p id="53112035-682e-4cf2-90b3-f101574ce9dd">どちらも、クラウド初期化処理がOS設定に関与していることを理解していないと、原因にたどり着きにくくなります。</p>
<h2 id="dcdadf47-4d5e-4dce-a98a-1a1492e0fc38" tabindex="-1"><span id="toc7">なぜクラウドはOS設定を書き換えるのか</span></h2>
<p id="bbeff4ac-5424-42b8-ab0a-6a307b935a90">では、なぜクラウド環境では、起動時にOS設定へ手を入れるのでしょうか。</p>
<p id="58d5f910-b76e-487d-ab97-293c79dbb820">理由は大きく3つあります。</p>
<p id="b6c55e9e-0fe0-4c4d-92ca-22e64e4833c0">1つ目は、セキュリティです。</p>
<p id="fcb37893-80de-4380-b1e7-cd7ae76ff846">クラウド環境では、インターネットや社内ネットワークから到達可能なサーバを短時間で作成できます。</p>
<p id="6d53b24d-3481-46ab-a6b0-f532e7144bf0">そのため、初期状態をできるだけ安全側に寄せる必要があります。</p>
<p id="84296913-9871-4a5a-90fb-eddaba2fa80f">SSHのパスワード認証を無効にし、公開鍵認証を前提にするような考え方は、その典型です。</p>
<p id="84a5be44-9c7f-41ff-9c54-5f29122d3230">パスワード総当たり攻撃の入口を減らすためです。</p>
<p id="c708c9e1-ca21-4ac9-bb86-ad5a74f9ef80">これは、クラウド環境におけるベストプラクティスに寄せた挙動と考えると理解しやすいです。</p>
<p id="edea57d0-7873-44a6-b2ab-05acc0a6add7">2つ目は、クラウド環境に合わせてOSを自動適応させるためです。</p>
<p id="7ce72a7a-dc57-464e-bdad-25fb05d79ced">EC2インスタンスは、起動時にインスタンスメタデータ、User Data、ネットワーク情報などを利用します。</p>
<p id="4ac540b9-3bf1-4074-b261-717feb53e0d3">OSは、起動した場所、割り当てられたIP、ホスト名、初期化スクリプトなどをもとに、クラウド上で動ける状態に整えられます。</p>
<p id="0a9081b5-8ac6-4e2f-8a59-715d9edf847d">3つ目は、AMIを再利用するためです。</p>
<p id="6c15de6b-8039-46ad-8a09-0a0693308b8d">AMIは、ある時点のOS状態を固めたものです。</p>
<p id="5ad2e64b-b093-46e1-acc2-736f84bd576c">しかし、そのAMIから起動されるインスタンスは、元の環境と同じとは限りません。</p>
<p id="b6bfb5bd-75c8-4069-8c9f-647670e014e4">別AZかもしれません。<br />
別サブネットかもしれません。<br />
別IPかもしれません。<br />
別用途のサーバとして起動されるかもしれません。</p>
<p id="378eaf36-6e37-457d-8b0f-10597b76aa4f">そのため、AMIに残っているOS設定をそのまま信じるだけでは危険です。</p>
<p id="8969a507-91c0-4c74-937f-a00445e05ca1">クラウドでは、起動時にメタデータやUser Dataを参照し、起動先の環境に合わせて初期化する仕組みが用意されています。</p>
<p id="7edb6bb8-fc76-4064-b0aa-3622d63f9413">ただし、その初期化処理が「いつ」「どの条件で」「何を」実行するかは、OS、エージェント、設定によって変わります。</p>
<p id="0af63280-b917-4939-b3ef-073b2b8886e0">ここを理解していないと、</p>
<div class="code-block-container">
<pre id="b0ac7176-e1d2-44f3-ba45-16fbbeb48224" data-name="preCode"><code class="hljs" data-name="code">設定したはずなのに戻った
自動で入ると思っていたのに入らなかった
AMIから起動したら前の状態を引きずった
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="2a4d7173-7a65-4131-aad4-f187a5fb8aa5">という事象が起こります。</p>
<h2 id="b7c0ad2b-c423-4958-afa9-7e572f0397e9" tabindex="-1"><span id="toc8">DR設計では「起動できる」だけでは足りない</span></h2>
<p id="afc653c5-4207-47b0-a738-535870392c7b">今回の話は、DR設計やAZ障害時の切替設計にも直結します。</p>
<p id="c2c4b579-673b-495e-98fe-3a17340222b6">DR設計では、次のような確認をしがちです。</p>
<div class="code-block-container">
<pre id="f4c89edf-77dc-429b-b9c6-b920af551280" data-name="preCode"><code class="hljs" data-name="code">・別AZでEC2が起動できる
・AMIからインスタンスを作成できる
・EBSを付け替えられる
・IPやDNSを切り替えられる
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="5568bfd6-4578-41dd-a95d-edcd7bad4e73">もちろん、これらは重要です。</p>
<p id="ddc3a103-b93b-45fb-8caa-0dbc7eab78a4">しかし、これだけでは不十分です。</p>
<p id="1fdcd319-d5ff-4c51-b638-4167d25baded">本当に確認すべきなのは、起動後に業務通信が成立するかです。</p>
<p id="2c4f0a7c-ae0a-4b07-8ca2-214a0f14de29">実務では、少なくとも以下を確認した方がよいです。</p>
<div class="code-block-container">
<pre id="8c663d5a-3d2d-470a-9c70-75d2c24301ff" data-name="preCode"><code class="hljs" data-name="code">・OS内のルート情報は正しいか
・DNS名前解決はできるか
・ADや認証基盤へ到達できるか
・業務アプリの接続先へ通信できるか
・監視、バックアップ、ジョブ管理エージェントは動くか
・User Dataや起動時スクリプトは期待どおり実行されたか
・初期化処理のログにエラーは出ていないか
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="f185292c-a2e1-4f5f-9449-bafca878bd55">DRテストで見るべきなのは、インスタンスの起動成功ではありません。</p>
<p id="379cbc44-b2bc-41a5-9ea6-7e07a84e199d">業務として使える状態になったかどうかです。</p>
<p id="fbff3646-bde5-4ded-8371-a0b34e6dd069">ここを間違えると、テストでは成功したように見えても、本番障害時に通信できないサーバが立ち上がることになります。</p>
<h2 id="83a8c398-c306-41d8-80e1-51081f7e5856" tabindex="-1"><span id="toc9">まとめ</span></h2>
<p id="34fed3d6-cb18-4f15-bdf5-a17a80deb49f">今回は、EC2を別AZで起動した際に、Windows Serverのルーティング情報が更新されず、通信できなくなった事象を扱いました。</p>
<p id="44c32348-a128-4031-8d0a-ecb02e906184">原因は、AWS側のセキュリティグループやVPCルートテーブルではなく、OS内部のルート情報でした。</p>
<p id="86459391-867b-46b3-91ce-30bc7f9c85f9">そして、その背景には、EC2Config、EC2Launch、EC2Launch v2といったクラウド初期化エージェントの挙動差がありました。</p>
<p id="48b161c5-54db-4119-9265-4b695fe8f2ba">クラウドでは、サーバを起動するだけなら簡単です。</p>
<p id="0c7a2496-9c90-4c6b-ad64-66cf3d3315f0">しかし、起動したサーバが業務として使える状態になっているかは、別の問題です。</p>
<p id="0b4034bf-072e-4182-a173-6b62449b2431">若手SEは、EC2が起動したかどうかだけで安心してはいけません。</p>
<p id="7a7fab07-c8c1-4567-9597-8d002965293a">見るべきなのは、起動後に、どの設定が、どのタイミングで、どの仕組みによって反映されるのかです。</p>
<p id="a76a836c-421f-499b-b667-c3be5c8485ce">サーバは起動した。<br />
でも通信できない。</p>
<p id="3441d922-79bb-40c4-b038-e0ea5edd8f60">その原因は、AWS側ではなく、OSの中にあるかもしれません。</p>
<hr id="fd9b46d7-9522-49ac-8bb8-743c2079c671" />
<p id="bad0c73b-5e79-4e8d-8a38-c9d8c1a681bc"><strong>関連記事</strong></p>
<p id="a74373b3-48ac-4d9e-bfc4-77c788da1cac">この考え方については、以下の記事でも整理しています。</p>
<p id="b531dedc-61a0-4cd6-baa1-46d8614e45d8"><a rel="nofollow" href="https://sys-univ.com/dev/detailed-design-overview/" target="_blank">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="11509699-b6e2-4cb5-af51-af3ef3bd772d">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/aws/addroute/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>EC2を止めただけなのに再作成？Auto Scaling運用の落とし穴｜クラウドの自動化は、作業者の意図までは読んでくれない</title>
		<link>https://sys-univ.com/aws/ec2autoscaling/</link>
					<comments>https://sys-univ.com/aws/ec2autoscaling/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Sat, 06 Jun 2026 12:06:17 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1510</guid>

					<description><![CDATA[AWSを使っていると、EC2を一時的に停止・起動したい場面があります。 たとえば、検証作業、メンテナンス、OS設定変更、ミドルウェア設定変更、不要時間帯の停止などです。 単体のEC2であれば、停止して、起動する。それだけ [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="d4dcfd93-906c-4bb8-93a4-2f8b0a294955">AWSを使っていると、EC2を一時的に停止・起動したい場面があります。</p>
<p id="4a994136-f88d-4179-87c3-23a198235f36">たとえば、検証作業、メンテナンス、OS設定変更、ミドルウェア設定変更、不要時間帯の停止などです。</p>
<p id="933c34dc-d328-49f9-93a9-12cd30ebfe47">単体のEC2であれば、停止して、起動する。それだけです。</p>
<p id="8fc23f98-e07e-4268-ba5f-0cbf714c8827">しかし、そのEC2がAuto Scaling Group配下のインスタンスだった場合、話は少し変わります。</p>
<p id="6db2ebfa-c75b-495f-b44a-0d3720da0961">Auto Scaling Groupは、単にEC2をまとめて管理する仕組みではありません。指定された台数を維持するために、インスタンスの状態を監視し、異常と判断した場合には新しいインスタンスに置き換える仕組みです。</p>
<figure id="18c62ac1-b3e0-46c9-828f-4f78deb1d30f"><a href="https://assets.st-note.com/img/1780102175-dzpUTNAZfmIv8uabFtkV530Q.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780102175-dzpUTNAZfmIv8uabFtkV530Q.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="6c273a4c-d9fe-4874-b809-408f0946f496">ここで、現場で起こりがちな事故があります。</p>
<p id="d12cb694-0048-442b-b96f-e5feae352937">Auto Scaling対象のEC2を停止・起動したところ、意図せずインスタンスが再作成されてしまう。</p>
<p id="a16493a2-3e66-4b5b-9d3d-33f6d311b077">作業者としては「既存のEC2を一時停止して、また起動しただけ」のつもりです。しかしAuto Scaling側から見ると「正常ではないインスタンスがいる。希望台数を維持する必要がある」という判断になることがあります。そして結果として新しいEC2が起動され、元のEC2が置き換えられてしまう。</p>
<p id="75b0473e-f47e-40ad-8ad5-5d37e3bd7276">これが、Auto Scaling配下のEC2停止・起動で起こる落とし穴です。</p>

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-12" checked><label class="toc-title" for="toc-checkbox-12">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">クラウドでも、過去の落とし穴が消えているとは限らない</a></li><li><a href="#toc2" tabindex="0">HealthCheckとReplaceUnhealthyの違い</a></li><li><a href="#toc3" tabindex="0">「ヘルスチェック猶予期間があるから大丈夫」ではない</a></li><li><a href="#toc4" tabindex="0">どう対策すべきか</a></li><li><a href="#toc5" tabindex="0">事前にどうチェックすべきか</a></li><li><a href="#toc6" tabindex="0">これは運用設計の問題である</a></li><li><a href="#toc7" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 id="df4826ab-8688-41e5-8e0f-d9b7f182337b" tabindex="-1"><span id="toc1">クラウドでも、過去の落とし穴が消えているとは限らない</span></h2>
<p id="626b903b-3062-4620-8151-82228931dab2">実はこれ、かなり昔に経験した事象です。</p>
<p id="85e056ea-6a41-4ef0-a863-30398713abb4">Auto Scaling配下のEC2を停止・起動したところ、意図せずインスタンスが再作成されてしまった。</p>
<p id="ecd93a97-7534-4d6e-ae64-ecc7789167af">当時は、「そんな動きをするのか」と思いました。</p>
<p id="bcc293fd-c0ae-4c44-a0bf-a7c1c148284c">ただ、クラウドサービスは日々進化します。</p>
<p id="9557d3b7-a169-4f1e-ba38-b5bc08cf2a91">昔の事故事例を、今もそのまま起こる前提で語るのは危険です。</p>
<p id="36be8f4c-af7d-4b63-bbbb-06076abbd421">一方で、過去に起きた事故や落とし穴が、現在では完全に解消されているとも限りません。</p>
<p id="5ad3abee-c096-4522-8f17-b51ad653f3a8">特に、Auto Scaling、ヘルスチェック、自動復旧、フェイルオーバーのような仕組みは、クラウドサービスの基本的な設計思想に関わります。</p>
<p id="fdc6cfd5-dfbd-482e-bdd4-63dc633a0118">そのため、昔の事例であっても、今の仕様ではどうなっているのかを確認することが大切です。</p>
<p id="bf800540-9b76-4ff6-8268-94ad607e9db2">今回の事象も、現在の<a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ec2-auto-scaling-health-checks.html" target="_blank">AWS公式ドキュメント</a>で確認できます。</p>
<figure id="15d36664-c7a3-4e26-91c3-d27e2e18f5b8">
<blockquote>
<p id="31ba7614-03dd-4e72-99cb-e45726fedb6f">ヘルスチェック猶予期間中であっても、Amazon EC2 Auto ScalingがインスタンスをEC2の running 状態ではないと検出した場合、そのインスタンスを即座に Unhealthy とマークして置き換える</p>
</blockquote><figcaption><a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ec2-auto-scaling-health-checks.html" target="_blank">AWS公式ドキュメント</a></figcaption></figure>
<figure id="29b279e6-f19a-4931-8e5c-7177650a190d"><a href="https://assets.st-note.com/img/1780102574-fbZvws2oIGc37XH5ngNykQmB.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780102574-fbZvws2oIGc37XH5ngNykQmB.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="3acad24b-b1d1-446a-b71b-061137923a4c">つまり、Auto Scaling Group配下のEC2を停止するという行為は、今でも単体EC2の停止とは意味が違います。</p>
<p id="62606795-0736-42c2-9686-0bbbe328687b">単体EC2なら、停止はただの停止です。</p>
<p id="905dc497-98c6-4668-a34d-0f47782bc308"><strong>しかしAuto Scaling Group配下では「本来動いているべきインスタンスが、正常な状態ではない」と判断される可能性があります。</strong></p>
<p id="42406c04-0f71-404f-8d98-6b17f32804fc">これはAWSのバグというより、Auto Scalingが希望台数を維持するための仕様です。</p>
<p id="a76869a2-e2d6-4abf-8a75-0ccf3c79ac28">問題は、作業者の意図とAuto Scalingの判断がずれることです。</p>
<h2 id="9cc1386c-8e73-4f2c-b2ed-5af316b4114e" tabindex="-1"><span id="toc2">HealthCheckとReplaceUnhealthyの違い</span></h2>
<p id="d2652342-04e2-4e50-b486-2a5959085fde">Auto Scalingには複数の内部プロセスがあります。今回特に関係するのがHealthCheckとReplaceUnhealthyです。</p>
<p id="adc7df10-249e-4f03-9e3b-d140efffef7d">HealthCheckはインスタンスの正常性を確認し、ReplaceUnhealthyは、異常と判断されたインスタンスを置き換えるプロセスです。</p>
<p id="cd59abbc-d7a6-4cad-864b-e3b3d5086588">AWS公式ドキュメントでは、以下のとおり説明されています。</p>
<figure id="17437a21-b535-460e-b68b-03679f492880">
<blockquote>
<p id="7274444e-1a58-42e3-bfab-d89192fcfa46">・ReplaceUnhealthyを停止すると異常とマークされたインスタンスの置き換えは止まるが、EC2やELBのヘルスチェックに失敗したインスタンスは引き続き異常とマークされる<br />
・ReplaceUnhealthyを再開すると、停止中に異常とマークされていたインスタンスが置き換えられる</p>
</blockquote><figcaption><a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/understand-how-suspending-processes-affects-other-processes.html" target="_blank">（AWS公式ドキュメント）</a></figcaption></figure>
<figure id="dfedd44e-9b2c-4949-a6df-1f12740c54e0"><a href="https://assets.st-note.com/img/1780102595-brECIa6Jpk20uUj8mY1nqzQe.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780102595-brECIa6Jpk20uUj8mY1nqzQe.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="6108d3c7-3c5e-4050-8920-8ecf8f28bb3d">つまり、ReplaceUnhealthyを止めていたとしても、その間にインスタンスが異常扱いになっていると、再開した瞬間に置き換えが走る可能性があります。</p>
<p id="d5890be3-b293-4680-b676-fc83ab2c3b4d">作業者としては「作業が終わったから戻そう」という感覚です。しかしAuto Scaling側では「このインスタンスはすでに異常とマークされています。プロセスが再開されたので置き換えます」という動きになる可能性があります。だから、単にプロセスを戻すのではなく、戻す前の状態確認が必要になります。</p>
<h2 id="157e5bf6-f6fb-46fd-970c-5eb08bae93a6" tabindex="-1"><span id="toc3">「ヘルスチェック猶予期間があるから大丈夫」ではない</span></h2>
<p id="0d11176c-12af-4a64-ae76-39d6417ad2f8">ヘルスチェック猶予期間は、新しく起動したインスタンスがInServiceになってから、Auto Scalingがヘルスチェックの評価を始めるまでの待ち時間です<a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/health-check-grace-period.html" target="_blank">（AWS公式ドキュメント）</a>。</p>
<p id="7d5cea67-6b34-44fd-b3b7-63760745c30c">これだけを見ると「猶予期間を長くしておけば安全では？」と思うかもしれません。しかしここに落とし穴があります。</p>
<p id="f8c9b724-2b6b-4398-9dd8-d3c617d2856b">ヘルスチェック猶予期間は、アプリケーションの起動待ちには役立ちます。しかし、Auto Scaling Group内のインスタンスを停止した場合に、それを安全に見逃してくれる仕組みではありません。ここを勘違いすると危険です。</p>
<h2 id="5a6b3705-7a7c-4c6b-9bbc-36193c615743" tabindex="-1"><span id="toc4">どう対策すべきか</span></h2>
<p id="6fc76cc5-10fa-4d58-a9f4-710dbe2d2768">対策として重要なのは、EC2を起動した直後にAuto Scalingのヘルスチェックや置き換えプロセスを機械的に戻さないことです。</p>
<p id="b7ccb40b-a086-4b1b-9f0f-bcc16631f50d">「EC2起動後、5分待ってからヘルスチェックを有効化する」という運用は実務上よく見ます。ただし、5分という数字そのものが本質ではありません。本質は「Auto Scalingが正常と判断できる状態になってから戻す」ことです。</p>
<figure id="04c6cc47-e3a0-405b-b115-c6d7555e9e18"><a href="https://assets.st-note.com/img/1780102941-MWyU9tAB81TgDq7r5IOuXQP0.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780102941-MWyU9tAB81TgDq7r5IOuXQP0.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="54f17e97-08d7-4fe3-8aa5-ab8bd53d75ba">戻す前に確認すべきことは次のとおりです。</p>
<ul id="6c77152f-9408-44a9-9757-ebdfcf12f8b4">
<li>
<p id="2d532c37-2f58-4c86-aa62-f5a19b150253">EC2のステータスチェックが正常であること</p>
</li>
<li>
<p id="305e05db-c118-4244-9e89-744023ad1a18">OSが正常に起動していること</p>
</li>
<li>
<p id="a5602b8f-803f-4011-a8a0-210d1d492ed4">ミドルウェアが起動していること</p>
</li>
<li>
<p id="9bd17dd0-37cb-4bd7-95a9-7da271204ea1">アプリケーションが正常応答していること</p>
</li>
<li>
<p id="0db5e50d-80d8-45f4-84bb-6e29ca4e3609">ELBまたはターゲットグループでHealthyになっていること</p>
</li>
<li>
<p id="e08b0909-a04e-4b87-84dc-039e7857fb45">Auto Scaling Activityに異常な置き換え履歴がないこと</p>
</li>
</ul>
<p id="754950cd-db31-4f40-9716-94986bf483f8">手順書には「起動後5分待つ」だけでなく、「何を確認できたら次の操作に進んでよいのか」を書く必要があります。</p>
<h2 id="026a6714-b19b-4c9a-b547-e86eead48224" tabindex="-1"><span id="toc5">事前にどうチェックすべきか</span></h2>
<p id="6867611f-7ab9-4613-b203-08b63489a806">このような事象を防ぐために、作業前に確認すべき点は大きく4つあります。</p>
<p id="0e764eeb-9724-4aa1-8914-dc4107cc4525"><strong>1. 対象EC2がAuto Scaling Group配下か確認する</strong></p>
<p id="a0388558-f896-437c-950b-702c78daf7fb">EC2一覧だけを見ていると、普通のEC2に見えます。しかしタグやAuto Scaling Group名を見ると、ASG管理対象であることがあります。少なくとも以下を確認してください。</p>
<ul id="4fcbf8b2-2c74-4612-9591-d7133b9337d2">
<li>
<p id="03fd93b8-c9f3-4c6a-af02-9db2a8487eeb">対象EC2はAuto Scaling Group配下か</p>
</li>
<li>
<p id="a1ccfdf4-2a60-4bf3-bfd6-cfb18b406058">Desired Capacityはいくつか</p>
</li>
<li>
<p id="5e84155e-4af4-4ade-906b-ac70088c7aac">対象インスタンスを停止した場合、希望台数維持のために補充されるか</p>
</li>
<li>
<p id="c5b494ce-c951-4d53-ac27-7638d6c27f73">再作成された場合、元の状態を再現できるか</p>
</li>
</ul>
<p id="19d2e60e-b389-42cd-8517-bd302a9521d9">特に危険なのは、手作業で設定変更されたEC2がAuto Scalingで再作成されるケースです。再作成されたEC2は起動テンプレートやAMIに基づいて作られるため、手作業で入れた設定が消える可能性があります。</p>
<p id="84a03266-e4af-4b56-92a3-e4fcda1cc2b3"><strong>2. どのAuto Scalingプロセスを止めるべきか確認する</strong></p>
<p id="28b65146-5443-4cff-aa41-58ee63989fc5">HealthCheckとReplaceUnhealthyは意味が違います。状況に応じて、どちらを止めるのか、Standbyを使うのかを判断する必要があります。スケジュールスケーリングやスケーリングポリシーの影響も確認してください。</p>
<ul id="8192c481-2c1f-4584-bc94-9a53ac26c093">
<li>
<p id="87d23782-2a3c-4407-9003-b48b7e23e2f8">プロセスの一時停止・再開：<a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/as-suspend-resume-processes.htmlperiod.html" target="_blank">（AWS公式ドキュメント）</a></p>
</li>
<li>
<p id="23fb0902-658e-4e7e-8ddc-bd4f4acb0ac5">Standby機能：<a rel="nofollow noopener" href="https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/as-enter-exit-standby.html" target="_blank">（AWS公式ドキュメント）</a></p>
</li>
</ul>
<p id="8b9d283b-811c-401a-8c27-fccc1498769b"><strong>3. ヘルスチェック猶予期間と起動時間を確認する</strong></p>
<p id="da6adb04-c65c-476b-b092-86e28eca784d">EC2起動からステータスチェック正常化まで何分かかるか、アプリケーションが正常応答するまで何分かかるか、ELBがHealthyになるまで何分かかるか。これらがヘルスチェック猶予期間と整合しているかを確認してください。</p>
<p id="b0ac5c7c-b5e9-43ff-bf64-5f4728316fcb"><strong>4. 手順書に「戻し条件」を書く</strong></p>
<p id="b25ac4f8-1a95-4e2c-9015-abc8f8a11b91">運用手順書でよくあるのは、操作手順は書いてあるが戻し条件が曖昧なケースです。「EC2起動後、Auto Scalingのヘルスチェックを有効化する」だけでは危険です。上で挙げた確認項目をすべて満たしたことを確認してから戻す、と明記する必要があります。</p>
<p id="40b3a2bc-4c6b-423e-b390-48c1a2ec4f45">運用手順で大事なのは操作そのものではありません。次の操作に進んでよい条件を明確にすることです。</p>
<h2 id="9fcbbd3d-45ce-42a8-88a9-1eabe31ff27e" tabindex="-1"><span id="toc6">これは運用設計の問題である</span></h2>
<p id="34afaae9-a3be-4cc6-bdaf-7a625ce0ad1f">今回の話は、AWSのAuto Scalingという個別サービスの話に見えます。しかし実際には運用設計の問題です。</p>
<p id="ee9e5628-7efe-4465-8853-58caaf3af681">Auto Scalingを使うなら、設計時点で少なくとも以下を決めておく必要があります。</p>
<ul id="83dc4274-32bd-409c-8a32-aeb904ab5602">
<li>
<p id="3b4c86fc-199a-4c99-ae35-248178ac6fc6">インスタンスを手動停止してよいのか</p>
</li>
<li>
<p id="72f74f0b-0421-402f-9fc4-be13407cd5f5">メンテナンス時はStandbyに入れるのか</p>
</li>
<li>
<p id="26dc3371-3aec-4640-b7da-b5c7fe2b81a3">HealthCheckやReplaceUnhealthyを一時停止するのか</p>
</li>
<li>
<p id="516eb7bc-ba83-4de5-89c8-0b2546a7c4ef">どの条件を満たしたらAuto Scalingのプロセスを戻してよいのか</p>
</li>
<li>
<p id="8e7b3d1e-759e-47dd-881b-930fbbc870f9">再作成された場合、設定やデータは失われないのか</p>
</li>
<li>
<p id="a36aaf38-4a28-417a-8b8f-194986da96d5">手作業で変更した内容はAMI、起動テンプレート、IaCに反映されているのか</p>
</li>
</ul>
<p id="ea6df4dd-4341-4913-9005-1684ea9ec4c1">これらは、運用当日に作業者がその場で判断するものではありません。設計書、運用設計書、作業手順書、チェックリストに落としておくべき内容です。</p>
<p id="45424004-72e2-4355-84bf-b9f808522c3a">クラウドでは、ひとつの操作に対して裏側で複数の自動化機能が反応します。作業対象のサーバだけを見ていると危険です。周辺にある自動制御の仕組みまで含めて、作業手順を考える必要があります。</p>
<p id="fa0083de-5303-4ee9-a1ed-aa03f8037fe1">これはバックアップ保存期限の設計と同じ構図です。「5日保存」と書いてあっても5営業日分なのか5世代なのかを確認しないと復旧時に認識違いが起きます。Auto Scalingも同様で、「EC2を停止・起動する」とだけ書くのではなく、その操作に対してAuto Scaling、ELB、CloudWatchがどう反応するのかまで設計しておく必要があります。</p>
<p id="d06837a9-5b44-48e2-9453-4a4f00f6426e">設計で決めるべきことを曖昧にしたまま運用に渡すと、作業時に現場が迷います。Auto Scalingの事故は、そのことを教えてくれる典型例です。</p>
<h2 id="d702d3ad-c722-493a-afd2-621153425573" tabindex="-1"><span id="toc7">まとめ</span></h2>
<p id="005297ac-d908-4bd2-996d-000ee0644851">Auto Scaling対象のEC2を停止・起動する場合、単体EC2と同じ感覚で作業してはいけません。</p>
<p id="7eae3904-5eda-42f2-9c7e-94ddb7635c86">停止中にUnhealthyとマークされ、起動直後にプロセスを戻した瞬間に置き換えが走る。ヘルスチェック猶予期間を長くしても、それは防げない。「起動後5分待つ」は暫定ルールであって、設計ではない。</p>
<p id="aef3b31a-6fd1-472c-a1c8-5d732d6635b7">本質は、Auto Scalingが正常と判断できる状態になってから戻すことです。そしてその判断基準を、設計時点で手順書に落としておくことです。</p>
<p id="3ae83f50-fb98-4315-b418-5c5661f37449">クラウドの自動化は便利です。しかし、作業者の意図までは読んでくれません。だからこそ、設計では正常時の構成だけでなく、メンテナンス時・障害時・復旧時にシステムがどう振る舞うかまで考える必要があります。</p>
<p id="42a6c4ce-5829-4b1d-8907-4f539f54819f">この考え方については、以下の記事でも整理しています。</p>
<p><a href="https://sys-univ.com/dev/detailed-design-overview/">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="11509699-b6e2-4cb5-af51-af3ef3bd772d">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/aws/ec2autoscaling/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>EBSは見えているのにマウントできない？｜AMIコピーで起きた落とし穴</title>
		<link>https://sys-univ.com/aws/mounterr/</link>
					<comments>https://sys-univ.com/aws/mounterr/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Fri, 30 Sep 2022 00:39:50 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1419</guid>

					<description><![CDATA[クラウドリフトで見落としやすい「OSの中身」の落とし穴 クラウドリフトでは、既存サーバをAMI化し、そこからEC2を作成することがあります。 オンプレミスのサーバ更改でいえば、既存環境を複製して、新しい環境で起動するよう [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="a1e6ad44-4f19-4776-be9c-78e79bfa35c0">クラウドリフトで見落としやすい「OSの中身」の落とし穴</p>
<p id="5bae012d-11d8-447f-aec2-1c8454a897e6">クラウドリフトでは、既存サーバをAMI化し、そこからEC2を作成することがあります。</p>
<p id="0f4d4361-539e-4f99-a412-1bda26287b4f">オンプレミスのサーバ更改でいえば、既存環境を複製して、新しい環境で起動するようなイメージです。</p>
<p id="8a5fc594-7a14-4ffc-b3db-56197693f049">一見すると、とても便利です。</p>
<p id="5b4c18d2-e5d0-47a5-a856-b9aba1e902f3">OS、ミドルウェア、設定ファイル、アプリケーション、ディレクトリ構成などを、元の環境に近い状態で再現できます。</p>
<p id="253c98c4-6fb9-4b80-beee-70ba70401f2e">そのため、クラウド移行では、</p>
<figure id="c0bfd809-9abd-419e-9a59-245c2fe7e76a">
<blockquote>
<p id="ad199ffd-0f5f-4db0-8251-0a032d30f0db">AMIを作って、そこからEC2を起動すればよい</p>
</blockquote><figcaption></figcaption></figure>
<p id="25c1a0a8-3400-434b-8848-23f93e874849">と思いがちです。</p>
<p id="0b2562c2-abfb-4087-9dbd-866fbc46efb7">しかし、ここに落とし穴があります。</p>
<p id="cea98c1b-d0ae-4855-a174-5375e13881c2">EC2は起動できる。<br />
EBSボリュームも作成できる。<br />
別のEC2へアタッチもできる。</p>
<p id="692a0622-8f6a-4552-8db1-56ec721e6311">それなのに、<strong>OS上で期待どおりにマウントできない</strong>ことがあります。</p>
<p id="f6eb5652-b17e-4236-b9b6-59bfd9ce1a45">今回扱うのは、AMIコピーやスナップショットから復元したEBSを、既存EC2にアタッチしてデータ復旧しようとしたときに起きたトラブルです。</p>

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-14" checked><label class="toc-title" for="toc-checkbox-14">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">何が起きたのか</a></li><li><a href="#toc2" tabindex="0">原因は「EBSが壊れていた」ではない</a></li><li><a href="#toc3" tabindex="0">なぜ LVM2_member になるのか</a></li><li><a href="#toc4" tabindex="0">UUIDの競合も見落としやすい</a></li><li><a href="#toc5" tabindex="0">どう対処したのか</a></li><li><a href="#toc6" tabindex="0">クラウドリフトでは「コピーできた」と「運用できる」は違う</a></li><li><a href="#toc7" tabindex="0">事前にどうチェックすべきだったのか</a></li><li><a href="#toc8" tabindex="0">これは詳細設計・運用設計の問題である</a></li><li><a href="#toc9" tabindex="0">まとめ</a></li><li><a href="#toc10" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2 id="414c7bdc-a5bc-48cb-a43e-48917cba516f" tabindex="-1"><span id="toc1">何が起きたのか</span></h2>
<p id="83e513a6-f7a7-4b01-a421-7300150b76d7">過去のAMIバックアップからデータを復旧したい場面がありました。</p>
<p id="79a2cdba-036d-44f8-b669-668a09e091c9">やろうとしたことは、よくある復旧作業です。</p>
<ol id="3baa4c1a-d82b-4800-b621-57499f15ce22">
<li>
<p id="50d6fb79-eca5-48d8-b829-2a36b6e9d8b1">過去のAMIまたはスナップショットからEBSを復元する</p>
</li>
<li>
<p id="6430f0ba-8678-408e-abdb-b296f6addc6c">復元したEBSを既存のEC2にアタッチする</p>
</li>
<li>
<p id="4527d5a3-3595-45b5-9ceb-41b7a8bd5a74">OS上でマウントする</p>
</li>
<li>
<p id="8d8f47e2-180f-4aca-bc61-db3cf61231ed">必要なファイルを取り出す</p>
</li>
</ol>
<p id="50b88b81-b8b8-4de0-8062-73ef442ccfa9">クラウド環境では、障害調査や復旧作業でよく出てくる手順です。</p>
<p id="631bae24-d1b3-42ae-bb39-97f0d79cc578">EBSはAWS上では問題なく作成できました。<br />
既存EC2へのアタッチもできました。<br />
OS上でもディスクとして見えていました。</p>
<p id="62147b04-85f4-4ea3-b7af-5eb250a6c834">ところが、いざマウントしようとすると失敗しました。</p>
<p id="b7bd9f90-19be-47d5-a8df-2d620b1180c1">たとえば、以下のようにデバイスを直接指定してマウントしようとします。</p>
<div class="code-block-container">
<pre id="c92b023f-b3a8-4ee9-a6f8-a3951c9e9074" data-name="preCode"><code class="hljs" data-name="code">mount /dev/xvdf2 /mnt
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="8ec9c17e-1778-4399-9391-a9d58eb7ec73">すると、次のようなエラーになります。</p>
<div class="code-block-container">
<pre id="ce325d02-3cfe-4b28-8396-4d50c2516c79" data-name="preCode"><code class="hljs go" data-name="code">mount: /mnt: unknown filesystem <span class="hljs-keyword">type</span> <span class="hljs-string">'LVM2_member'</span>
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="592f90c5-2f78-43bf-a106-ec11831ddd2b">ここが今回のポイントです。</p>
<p id="32d1a255-5273-4fa9-9da5-03fca1dc2cb3">OSから見ると、/dev/xvdf2 はそのままマウントできるXFSやext系のファイルシステムではありませんでした。</p>
<p id="0eab71d0-9610-45d2-96ea-f56815123dd0">LVM2_member として認識されています。</p>
<p id="e9de1ede-27cf-45dd-9d3d-a9ab4546c616">つまり、直接マウントしようとしていた対象は、ファイルシステムそのものではなく、LVMの物理ボリュームとして扱われる領域だったということです。</p>
<h2 id="fed3e22e-3306-4e22-8cdb-af1928f423e9" tabindex="-1"><span id="toc2">原因は「EBSが壊れていた」ではない</span></h2>
<p id="20b7b4e6-1c24-4425-a6c2-2108deacb823">この手のエラーを見ると、最初はこう考えがちです。</p>
<p id="2472c018-5650-49ec-b4de-30e1c6acfdd6">EBSの復元に失敗したのではないか。<br />
スナップショットが壊れているのではないか。<br />
デバイス名を間違えたのではないか。</p>
<p id="551eab3f-2239-48e2-ba39-41857fafb4db">もちろん、それらも確認すべきです。</p>
<p id="7884c2e3-cd9c-4776-9711-90c42058b683">しかし今回の本質は、EBSそのものが壊れていたことではありません。</p>
<p id="71ee1879-39f3-430d-ab9d-e55de71bbcbe">原因は二つあります。</p>
<p id="79ff95b7-42c6-4a4f-8936-28dec6067ae0">一つ目は、直接マウントしようとした対象が LVM2_member だったことです。</p>
<p id="bc32686e-6562-46d6-9b7a-3559eb1f1e04">二つ目は、同じAMIを元にしたインスタンス同士で、ディスクやボリューム管理情報の識別子が競合したことです。</p>
<p id="453736d5-8282-45cd-acad-7c6e8bc25f0d">AMIからEC2を作ると、OSの中身も含めて複製されます。</p>
<p id="9c7ca32f-e4b0-46eb-a7da-30c22f39b48f">ファイルシステムのUUID、LVMのボリューム情報、/etc/fstab の記述、デバイス構成の前提なども、元の環境を引き継ぎます。</p>
<p id="c063e770-2c75-4046-b123-05d35ab75088">そのため、同じAMIを元にしたEC2に、同じ系統のAMIやスナップショットから復元したEBSをアタッチすると、OSから見た識別情報が競合することがあります。</p>
<p id="a67206cc-058e-47a6-8da6-eb30ed25368c">作業者としては、</p>
<figure id="708f8bc2-e5ce-4b74-8f78-f7552d7e8c3d">
<blockquote>
<p id="310cb1be-8f9b-41b5-b4e1-e4c722dfe9a1">復元したEBSを別EC2に付けて、中身を見たいだけ</p>
</blockquote><figcaption></figcaption></figure>
<p id="57747afe-4914-48fb-aa2d-0232229039d7">です。</p>
<p id="43efb1e5-333a-4503-b613-785ce1c75233">しかしOS側から見ると、同じような識別情報を持つボリュームが複数見えている状態になります。</p>
<p id="9a01c816-4b00-462d-90f2-2875937ccef4">AWS上ではEBSがアタッチできていても、OS上で安全にマウントできるとは限りません。</p>
<p id="ac470be3-3505-4344-90e8-8f2f6370fc5d">ここを取り違えると、復旧作業で詰まります。</p>
<p id="dd4b159c-ce07-4338-8a7c-3c1087314ae1">これはAWSの不具合というより、Linuxのディスク管理、UUID、LVM、fstab の仕組みに基づく動作です。</p>
<p id="5a53b042-3f26-4151-ba96-23be6f41b96d">EBSはクラウド上のブロックストレージですが、最終的にそれをどう認識し、どうマウントするかはOS側の話になります。</p>
<h2 id="a4aed584-69a7-42dd-aa26-4c28142cf83d" tabindex="-1"><span id="toc3">なぜ LVM2_member になるのか</span></h2>
<p id="672514c9-616e-44c6-89e7-a7cfce8995b4">Linuxでは、ディスク上に直接ファイルシステムが作られている場合もあれば、LVMを使ってボリューム管理している場合もあります。</p>
<p id="77f547cc-7783-423d-81b1-478d276dc156">単純な構成であれば、パーティションにXFSなどのファイルシステムがあり、そのパーティションを直接マウントできます。</p>
<p id="271aed7a-743f-43cf-bc6b-1635e44673ff">一方、LVMを使っている場合、物理ディスクやパーティションは、まずLVMの物理ボリュームとして扱われます。</p>
<p id="8ec62288-c9d9-4098-8d13-62badf4cbce8">その上にボリュームグループがあり、さらに論理ボリュームが作られ、その論理ボリューム上にファイルシステムがあります。</p>
<p id="cf4ee645-7f28-41a7-8f35-61f0e20989e7">つまり、LVM構成では、次のような階層になります。</p>
<figure id="14c53725-13ce-471d-b272-527ca51d0f3e"><a href="https://assets.st-note.com/img/1780366499-KXh7a8PEBNZzrn0VC1iHDvTQ.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780366499-KXh7a8PEBNZzrn0VC1iHDvTQ.png?width=1200" alt="画像" width="620" height="465" data-modal="true" /></a><figcaption></figcaption></figure>
<p id="22945179-05c0-411c-ac3e-cf1037cd1b82">この場合、LVMの物理ボリュームを直接 mount しても、ファイルシステムとして認識できません。</p>
<p id="015f3933-44ce-4cc4-8583-16e0b9b0cc00">そのため、</p>
<div class="code-block-container">
<pre id="bcfb7f4f-7635-4799-bd92-c7840aa2874a" data-name="preCode"><code class="hljs go" data-name="code">unknown filesystem <span class="hljs-keyword">type</span> <span class="hljs-string">'LVM2_member'</span>
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="a8483dc4-fc29-40c9-b27c-1034fed56c27">となります。</p>
<p id="608d9f49-b8d9-4d76-92aa-8e96ce3449de">これは、OSが対象を見失っているというより、</p>
<figure id="8362bb38-f116-49f4-a4e9-53cd9171b0bf">
<blockquote>
<p id="def357b4-c6c4-4129-935d-0e29f18037ef">そこは直接マウントする場所ではない</p>
</blockquote><figcaption></figcaption></figure>
<p id="3e412f14-23c9-463f-b345-e46817e604d0">という意味に近いです。</p>
<p id="75361438-f9e3-4333-b838-309af55efc0a">たとえば、blkid で見ると、対象パーティションが次のように見えることがあります。</p>
<div class="code-block-container">
<pre id="6f77bb35-c71d-4195-98bc-224ec6664268" data-name="preCode"><code class="hljs" data-name="code">blkid /dev/xvdf2
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<div class="code-block-container">
<pre id="07b8dff8-2610-4cb9-9471-a9ceb3a6c59c" data-name="preCode"><code class="hljs javascript" data-name="code">/dev/xvdf2: UUID=<span class="hljs-string">"xxxxx"</span> TYPE=<span class="hljs-string">"LVM2_member"</span>
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="a574d4f1-928a-4402-8f4f-b7950f82769e">この状態で /dev/xvdf2 を直接 mount しても、XFSやext系のファイルシステムとしては扱えません。</p>
<h2 id="26a4b4d3-005b-4e44-b67d-689195d8c6c1" tabindex="-1"><span id="toc4">UUIDの競合も見落としやすい</span></h2>
<p id="689a59f6-caff-49d3-a7e0-4a937c38c836">もう一つ重要なのがUUIDです。</p>
<p id="7edad6da-0ad4-4109-8b08-5c1490b8b718">Linuxでは、ディスクやパーティションを /dev/xvdf、/dev/xvdf1、/dev/nvme1n1p1 のようなデバイス名で扱うことがあります。</p>
<p id="717e2029-69cc-48d7-9e4d-0bbfebf668da">しかし、クラウド環境ではデバイス名だけを信じると危険です。</p>
<p id="e3c99943-2288-48e0-aae5-95e54df118a4">AWSコンソール上で指定したデバイス名と、OS上で見えるデバイス名が直感どおり一致しないことがあります。</p>
<p id="9e36146b-1360-495e-9c34-a4ab6b6914dc">さらに、AMIやスナップショットから復元したボリュームでは、ファイルシステムUUIDやLVM関連の識別情報が元の環境と同じまま残ることがあります。</p>
<p id="9dc411d1-bb5f-4745-9b6c-78ac3bf1c1f1">そのため、同じAMI由来のボリュームを同じ系統のEC2にアタッチすると、UUIDやボリューム管理情報が競合し、どのボリュームをマウントすべきかが分かりにくくなります。</p>
<p id="87d931f4-e2ab-481c-9081-ff41fe206058">ここで必要なのは、勘でデバイス名を指定することではありません。</p>
<p id="7e668a3f-11d0-46a9-a4aa-ec2af63927c8">OSが実際にどう認識しているかを確認することです。</p>
<p id="72e56501-0323-4c92-af40-d3da4cc4c485">たとえば、以下のようなコマンドで確認します。</p>
<div class="code-block-container">
<pre id="708ca8af-4980-4737-a4bc-34017d7e9dbd" data-name="preCode"><code class="hljs cs" data-name="code">lsblk
blkid
ls -l /dev/disk/<span class="hljs-keyword">by</span>-uuid
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="a9125f5a-ba9f-4911-b98b-194f7ae372f3">これらを使って、次の情報を確認します。</p>
<ul id="a032dfba-aa02-4746-a876-d07ed4318aba">
<li>
<p id="a1b29c82-c15a-4f8c-bd0d-66e4c83f5a0d">どのデバイスが追加ボリュームなのか</p>
</li>
<li>
<p id="d429215e-b3f1-412b-9e9d-5d1789cb7a55">どのパーティションにファイルシステムがあるのか</p>
</li>
<li>
<p id="e40a9827-de2e-4962-9ce6-00389ba5a2e7">LVM2_member として見えているのか</p>
</li>
<li>
<p id="c43cc4c4-eb48-4c81-b94b-b52b4a7cce2d">どのUUIDがどのデバイスに対応しているのか</p>
</li>
<li>
<p id="85e8a6f1-0d0b-421e-94b2-4d55d4ca530a">既存ボリュームと識別情報が競合していないか</p>
</li>
</ul>
<h2 id="b997a2a8-ae89-435a-985d-a5214967a05f" tabindex="-1"><span id="toc5">どう対処したのか</span></h2>
<p id="666c6141-74d9-4566-befb-76cb746ac81a">今回の対処の核心は、同じAMI由来ではない作業用EC2を用意し、そこに復元EBSをアタッチしてマウントするという点です。</p>
<p id="51ccd583-a8d2-4557-b7cb-bca78401e2a4">狙いは、同じAMI由来のOSボリュームと復元ボリュームを同じEC2上に同居させることで起きる、UUIDやLVM関連の識別情報の競合を避けることです。</p>
<p id="e415073c-88f0-4401-912e-a167394b7702">ここでいう「別のEC2を用意する」とは、LVM2_member が自動的にマウントできるようになる、という意味ではありません。</p>
<p id="f4068b75-60fc-4de8-9c08-9507d61c3534">そのうえで、OS上で lsblk、blkid、/dev/disk/by-uuid を確認し、どの領域が直接マウントできるファイルシステムなのか、どの領域が LVM2_member なのかを切り分けました。</p>
<p id="b9113960-cbce-4650-845c-fa51adb754a9">LVM構成を維持したまま確認したい場合は、pvscan、vgscan、vgchange -ay でボリュームグループを有効化する方法や、複製されたLVMボリュームを別物として扱う vgimportclone を使う方法もあります。</p>
<p id="1f5e2114-ef0f-4fa1-a27a-243b09da5e2f">また、既存EC2上で対応せざるを得ない場合は、mount -o nouuid で一時的に参照する方法もあります。</p>
<p id="24673cb2-d344-4085-a6ae-43561bec33a5">ただし、これらは環境と目的によって適否が分かれます。</p>
<p id="c48a3b10-47df-4bca-bb42-8a217041d4af">今回は復旧対象のファイルを一時的に安全に取り出すことが目的だったため、作業用EC2を用意し、UUIDで対処する方針を採りました。</p>
<p id="31d342fe-62bb-49cc-98b1-154d5cea5042">具体的な手順は以下のとおりです。</p>
<p id="b2f1f4f3-bc8c-4cd6-ad22-aca6f1d87877">まず、/dev/disk/by-uuid でUUIDとデバイスの対応を確認します。</p>
<div class="code-block-container">
<pre id="e4f8f0b6-f2b8-46b0-9654-bcece5b6e262" data-name="preCode"><code class="hljs cs" data-name="code">ls -l /dev/disk/<span class="hljs-keyword">by</span>-uuid
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="26dc8e02-4c0a-4915-b7d6-4111c7f71948">たとえば、以下のように表示されます。</p>
<div class="code-block-container">
<pre id="359dd71a-8a9d-4ab9-96af-906ad7f9f5f5" data-name="preCode"><code class="hljs rust" data-name="code">lrwxrwxrwx. <span class="hljs-number">1</span> root root <span class="hljs-number">11</span> Feb <span class="hljs-number">16</span> <span class="hljs-number">07</span>:<span class="hljs-number">47</span> <span class="hljs-number">1</span>c5999b9-<span class="hljs-number">594</span>d-<span class="hljs-number">40</span>aa-<span class="hljs-number">84</span>d2-<span class="hljs-number">167</span>a92a977c5 -&gt; ../../xvdf1
lrwxrwxrwx. <span class="hljs-number">1</span> root root <span class="hljs-number">11</span> Feb <span class="hljs-number">16</span> <span class="hljs-number">07</span>:<span class="hljs-number">46</span> <span class="hljs-number">949779</span>ce-<span class="hljs-number">46</span>aa-<span class="hljs-number">434e-8</span>eb0-<span class="hljs-number">852514</span>a5d69e -&gt; ../../xvda2
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="8869707f-5133-4273-8903-8d3e5f546d38">この例では、xvdf1 がアタッチした復元ボリューム、xvda2 が既存のルートボリュームとして見えています。</p>
<p id="7e6a94f1-f9ae-485f-8bf8-a4ef90f080df">次に、/etc/fstab にマウント先を追記します。</p>
<div class="code-block-container">
<pre id="8355ab36-e2b2-4dfb-a1f5-84add2ee3fce" data-name="preCode"><code class="hljs python" data-name="code"><span class="hljs-comment"># fstab.new（変更後）</span>
UUID=<span class="hljs-number">949779</span>ce<span class="hljs-number">-46</span>aa<span class="hljs-number">-434e-8</span>eb0<span class="hljs-number">-852514</span>a5d69e /      xfs  defaults  <span class="hljs-number">0</span> <span class="hljs-number">0</span>
UUID=<span class="hljs-number">1</span>c5999b9<span class="hljs-number">-594</span>d<span class="hljs-number">-40</span>aa<span class="hljs-number">-84</span>d2<span class="hljs-number">-167</span>a92a977c5 /mnt   xfs  defaults  <span class="hljs-number">1</span> <span class="hljs-number">1</span>
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="d78fc159-03e8-4959-bbd3-b4951170b691">そのうえで、マウントを実行します。</p>
<div class="code-block-container">
<pre id="3c32c6af-8e5b-4b77-9c79-f34b551e58fe" data-name="preCode"><code class="hljs" data-name="code">mount -a
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="e9fca54b-c82c-448b-9ea0-065d7f3de357">最後に、マウント先の中身を確認して、意図したボリュームであることを確認します。</p>
<div class="code-block-container">
<pre id="4547096c-fe42-426d-8d4c-c0afb123174d" data-name="preCode"><code class="hljs" data-name="code">cat /mnt/etc/hostname
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="a0a82999-6a29-4b1b-a0cf-e9ebdf52f0cf">この確認により、単にマウントできたかどうかだけでなく、本当に目的のボリュームを参照できているかを確認できます。</p>
<h2 id="6208d713-e896-4031-acac-20309dbb5c35" tabindex="-1"><span id="toc6">クラウドリフトでは「コピーできた」と「運用できる」は違う</span></h2>
<p id="131b5e7e-859f-46dc-9b1f-3306f5261e63">クラウドリフトでよくある誤解があります。</p>
<p id="f8374eb4-8704-4a40-82e9-5a947a068cb4">AMIを作れた。<br />
EC2が起動した。<br />
EBSもアタッチできた。<br />
だから移行できている。</p>
<p id="2e57ffb6-78fd-4a27-a2a2-65acade18f9b">もちろん、これらは重要です。</p>
<p id="c1bb99fa-598d-4dd5-aef1-cb9fa92cd782">しかし、それだけでは十分ではありません。</p>
<p id="676ad1ad-5c35-4f7c-83a5-6dc9b9123dbf">本当に確認すべきなのは、移行後に必要な運用作業ができるかです。</p>
<p id="091e10e8-6bee-40a1-a813-442bca8c25c0">たとえば、障害時に旧ボリュームを別EC2にアタッチして中身を確認できるか。<br />
/etc/fstab の記述は移行後の構成に合っているか。<br />
デバイス名だけに依存せず、UUIDで対象を識別できるか。<br />
LVM構成なら、LVMとして認識・有効化できるか。</p>
<p id="794f564c-c66d-41ef-bb76-493af0aeeb8a">こうした確認が抜けると、本番障害時に困ります。</p>
<p id="10005680-c934-4d0e-8fcc-354150ee526d">通常時は問題なく動いているように見えても、いざ障害調査や復旧作業をしようとしたときに、</p>
<figure id="d8cc0b90-1acb-4866-b1e3-c98f0f16f07e">
<blockquote>
<p id="e106d497-8ba4-4463-9eeb-aeffcd9b95ea">そのボリューム、どうやって安全にマウントするんだっけ？</p>
</blockquote><figcaption></figcaption></figure>
<p id="560075f5-50c6-4d94-95b9-fd4d1729b782">となります。</p>
<p id="cdebfed4-ae0a-4c45-976d-5cdab26fe4e7">クラウドリフトでは、このような運用時の確認観点が後回しになりがちです。</p>
<h2 id="6572f61e-f250-4c18-94c7-c78da40127df" tabindex="-1"><span id="toc7">事前にどうチェックすべきだったのか</span></h2>
<p id="2072a0e2-d447-4323-afcd-2c87005efdd5">チェックリストとして最小限に絞るなら、見るべきポイントは次の4つです。</p>
<p id="ccb4c119-4084-4e47-a2da-b340fd85904e"><strong>1. OSのディスク構成を確認する</strong></p>
<p id="812fa0db-b6cc-44ac-993d-402afac34547">ルートボリュームはどれか。<br />
追加ボリュームはどれか。<br />
パーティション構成はどうなっているか。<br />
ファイルシステムは何か。<br />
LVMを使っているか。<br />
UUIDは何か。<br />
/etc/fstab はどう書かれているか。</p>
<p id="5368a0b5-b01e-480f-9049-93b34db6189a">クラウドリフトでは、EC2を起動できるかだけでなく、移行後のOS内部構成まで確認する必要があります。</p>
<p id="fbf9ae99-a096-4dc5-8a33-b891547d0ad8"><strong>2. LVM構成か、直接マウント可能なファイルシステムかを確認する</strong></p>
<p id="5e5971d4-2692-4907-a04b-b8606d49bbf5">lsblk や blkid で、対象がXFSなどのファイルシステムなのか、LVM2_member なのかを確認します。</p>
<p id="22f3238f-f20b-4bb9-98a6-e2bd8e1c6f5c">LVM2_member であれば、直接 mount する対象ではありません。</p>
<p id="4d71b12b-8f00-4480-95c3-67bae970063a">LVMとして認識させるのか、UUIDでマウント対象を指定するのかを、OS構成に応じて判断する必要があります。</p>
<p id="b362c53c-7ce0-4ddd-99fb-bde831af1b45"><strong>3. UUIDの対応を確認する</strong></p>
<p id="892683a4-fd84-47ae-b71c-a2249f2b2688">/dev/disk/by-uuid を確認し、どのUUIDがどのデバイスを指しているかを確認します。</p>
<p id="ea96fd2a-8b06-48e1-828f-760f46f63c33">同じAMI由来のボリュームを扱う場合は、UUIDやボリューム管理情報の競合に注意します。</p>
<p id="c7319392-c623-4f76-9d94-6a493832ef25">デバイス名だけで判断せず、UUID、ファイルシステム、マウント先の対応を確認します。</p>
<p id="764f2ef0-8e08-4a57-8b60-35dede0681ed"><strong>4. 復旧手順として事前に試す</strong></p>
<p id="a02a0c99-2479-44a1-842a-ec6986454df6">設計書や手順書に「EBSをアタッチしてマウントする」と書いてあっても、本当にできるとは限りません。</p>
<p id="c764d621-b952-4ed8-b564-29beaa5ec230">別EC2にEBSをアタッチする。<br />
OS上でデバイスを確認する。<br />
UUIDを確認する。<br />
必要に応じてLVM構成を確認する。<br />
マウントして中身を確認する。<br />
作業後にアンマウントする。</p>
<p id="0460b0d6-1013-4cb0-9dbb-1bb4c3d1a604">ここまで一度試しておくべきです。</p>
<p id="d658cbd9-d3af-46ff-a29a-8fc313f8f72d">復旧手順は、障害が起きてから初めて実行するものではありません。</p>
<h2 id="e89b4753-2b76-4af1-8654-d9607a740da5" tabindex="-1"><span id="toc8">これは詳細設計・運用設計の問題である</span></h2>
<p id="c3526da0-b4da-4227-b09d-5e4afec7cb38">今回の話は、EBSをマウントできなかったという作業トラブルに見えます。</p>
<p id="2472d9ce-f61f-4a48-8b05-5167457cb3d9">しかし、本質は詳細設計・運用設計の問題です。</p>
<p id="85e764f7-5cb9-490b-ae35-a66031a97d8f">クラウドリフトでAMIやEBSを扱うなら、設計時点で少なくとも以下を決めておく必要があります。</p>
<ul id="0fab29ce-b512-472c-bcd3-e50a784ee55a">
<li>
<p id="c8906514-3e3e-4319-a624-698d4247b8ef">移行後のEBS構成</p>
</li>
<li>
<p id="8b552771-95e5-430d-888a-32402063bcc2">OS上のデバイス認識</p>
</li>
<li>
<p id="953cb954-2037-4f8d-9120-5b5335ba99ce">LVMを使っているかどうか</p>
</li>
<li>
<p id="0dbb4c0a-bedf-460b-8552-35754fdbf588">ルートボリュームと追加ボリュームの識別方法</p>
</li>
<li>
<p id="bbf047d6-e8a1-40bf-ba71-59214de941bf">UUIDの確認方法</p>
</li>
<li>
<p id="e0ea04b2-78d1-4551-97fc-cf350c22c33d">/etc/fstab の記述方針</p>
</li>
<li>
<p id="73f56f0d-8d81-4fd3-9f21-638eb98c3907">障害時に別EC2へアタッチして確認する手順</p>
</li>
<li>
<p id="5faec238-17b9-483a-add6-91d7898705bf">マウント確認後に何を見て正常と判断するか</p>
</li>
</ul>
<p id="4e426197-6e97-4291-b0dd-4b95941ef85c">これらは、運用当日に作業者が感覚で判断するものではありません。</p>
<p id="e9f05549-8148-41e8-bae5-f6530515b2e1">設計書、運用設計書、作業手順書、復旧手順書に落としておくべき内容です。</p>
<p id="fa5deb12-cc91-4327-9cad-6a09242e01a6">特に、構築担当者と運用担当者が分かれているプロジェクトでは、この問題が起きやすくなります。</p>
<p id="eb4d0293-835d-45b9-a0f0-a52494d30f21">構築担当者は、「AMIからEC2は起動した」「EBSも作成できた」と考える。</p>
<p id="cbf393af-2939-4569-aaff-c2f164722d77">一方、運用担当者は障害時に、「復元したEBSをどのEC2にアタッチし、どのUUIDを見て、どのディレクトリにマウントし、何を確認すればよいのか」で迷う。</p>
<p id="4edd882f-9241-4945-bc80-b98566232aa8">この間を埋めるのが、詳細設計と運用設計です。</p>
<p id="07a452dc-efb2-47fe-8749-d4e96f099eb2">「EC2が起動した」ことと、「運用できる」ことは違います。</p>
<p id="c03290de-d6f9-4222-ace8-68aca6f3e741">「EBSがアタッチされた」ことと、「安全にマウントできる」ことも違います。</p>
<p id="a4d43ed0-29d3-4f29-9043-64668b232e82">この違いを設計で潰しておくことが重要です。</p>
<h2 id="3c1b1450-15d2-4ed2-b6cd-a7a7d3a71742" tabindex="-1"><span id="toc9">まとめ</span></h2>
<p id="f9d41e86-77a3-4595-a6f5-771e32b69383">AMIコピーやスナップショット復元で作成したEBSは、AWS上でアタッチできていても、OS上でそのまま期待どおりにマウントできるとは限りません。</p>
<p id="e7f1120b-bad5-41da-ab10-fac37b3b861a">今回の事象では、直接マウントしようとした対象が LVM2_member であり、さらに同じAMI由来のボリューム識別情報が競合していたことが問題でした。</p>
<p id="805bf3dc-dfa3-4499-85bf-d51a3ebb72f0">対処の核心は、同じAMI由来ではない作業用EC2を用意して、そこに復元EBSをアタッチすることです。</p>
<p id="bfb599b7-b4cc-42be-8539-92b5f82ba2a2">そのうえで、/dev/disk/by-uuid を確認し、実際にマウント対象となるファイルシステムのUUIDを指定してマウントしました。</p>
<p id="612aa3dd-57c9-4453-a143-a50c5f6a9168">作業前には、lsblk、blkid、/dev/disk/by-uuid で、OSが対象ボリュームをどう認識しているかを必ず確認します。</p>
<p id="bfccd2b2-407d-4447-a024-53495eac2874">デバイス名だけで判断せず、UUID、ファイルシステム、マウント先の対応を確認してから作業に入ることが重要です。</p>
<p id="67abcff9-e007-4cb2-9363-d54157ad71fe">クラウドリフトで本当に大事なのは、サーバをクラウド上で起動することだけではありません。</p>
<p id="c3c4f85c-3d21-4d85-a8c3-e018751ffbcc">移行後に、調査できること。<br />
復旧できること。<br />
運用できること。</p>
<p id="87929eb3-5e48-4028-9c8e-1f076dc5682d">ここまで確認して初めて、クラウドリフトは現場で使えるものになります。</p>
<h2 id="1afa7894-18d3-4452-b1ac-563924439116" tabindex="-1"><span id="toc10">関連記事</span></h2>
<p>この考え方については、以下の記事でも整理しています。</p>
<p><a href="https://sys-univ.com/dev/detailed-design-overview/">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="11509699-b6e2-4cb5-af51-af3ef3bd772d">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/aws/mounterr/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AMIからRHELインスタンスを起動したらSSHログインできなくなった｜cloud-initが上書きする設定を知らないと、復旧以前に入れなくなる</title>
		<link>https://sys-univ.com/incident/sshfail/</link>
					<comments>https://sys-univ.com/incident/sshfail/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Sun, 02 Oct 2022 03:00:58 +0000</pubDate>
				<category><![CDATA[トラブル]]></category>
		<category><![CDATA[AWS]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1463</guid>

					<description><![CDATA[AMIから起動したRHEL系インスタンスで、SSHのパスワードログインができなくなった。 ネットワークは到達している。 OSも起動している。 sshd も動いているように見える。 それでも入れない。 原因は、/etc/s [&#8230;]]]></description>
										<content:encoded><![CDATA[<p id="6dbf4fc1-3266-4c3c-8d03-4be7d2627509">AMIから起動したRHEL系インスタンスで、SSHのパスワードログインができなくなった。</p>
<p id="16236afa-50d2-4e47-b9e5-f8f47b408947">ネットワークは到達している。<br />
OSも起動している。<br />
sshd も動いているように見える。</p>
<p id="309700d7-721e-4ad9-b625-927884d1e383">それでも入れない。</p>
<p id="db0cfccf-e402-4714-99d0-41edb67642c7">原因は、/etc/ssh/sshd_config そのものではなく、起動時に動作する cloud-init 側の設定でした。</p>
<p id="84593371-6174-4331-82e9-6e56630f8550">今回の記事で伝えたいのは、パスワード認証の是非ではありません。</p>
<p id="e437d880-37c1-4634-b496-9a2218db1614"><strong>クラウド環境では、OSの設定ファイルだけを見ても、起動後の状態を正しく判断できないことがある。</strong></p>
<p id="5ac1aa34-83df-4547-b0aa-a98723ccab0d">ここがポイントです。</p>

  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-16" checked><label class="toc-title" for="toc-checkbox-16">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">事象：AMIから起動したらSSHパスワードログインできない</a></li><li><a href="#toc2" tabindex="0">最初に疑いたくなるポイント</a></li><li><a href="#toc3" tabindex="0">原因：cloud-initがSSH設定を上書きしていた</a></li><li><a href="#toc4" tabindex="0">対策：cloud-init側の設定も確認する</a></li><li><a href="#toc5" tabindex="0">起動後に確認するコマンド例</a></li><li><a href="#toc6" tabindex="0">RHEL 8/9/10でも考え方は同じ</a></li><li><a href="#toc7" tabindex="0">もし実際に入れなくなったら</a></li><li><a href="#toc8" tabindex="0">ただし、パスワード認証を推奨する話ではない</a></li><li><a href="#toc9" tabindex="0">まとめ</a></li><li><a href="#toc10" tabindex="0">関連記事</a></li></ol>
    </div>
  </div>

<h2 id="403a65fb-1849-4696-ad1a-341c0fbf2235" tabindex="-1"><span id="toc1">事象：AMIから起動したらSSHパスワードログインできない</span></h2>
<p id="83d4b180-0e1d-453c-b675-22bceb072e1c">あるRHEL系のEC2環境で、SSHのパスワードログインを有効にした状態でAMIを作成しました。</p>
<p id="1545e4bb-07ee-462f-98e0-4070d47a3939">元のEC2インスタンスでは、SSHのパスワード認証が有効になっていました。</p>
<p id="d9d6133c-a39f-48c8-a9b9-2d1fa1e6763e">そのため、AMIから新しいEC2インスタンスを起動しても、当然同じようにSSHログインできるだろうと考えていました。</p>
<p id="1ade7889-26a4-4dcb-9674-75d54ccd62e4">ところが、実際にAMIからインスタンスを起動すると、SSHのパスワードログインができません。</p>
<p id="fcb371b3-98c0-4592-a1f4-5a0871106008">OSは起動している。<br />
インスタンスのステータスチェックも通っている。<br />
ネットワーク的にも到達できている。<br />
でも、SSHのパスワード認証が通らない。</p>
<p id="8a6d81a2-6ae5-426e-9e22-6dd619bc65b6">この状態になると、非常に困ります。</p>
<p id="95909f13-984d-4466-95b2-3422d0289ea3">障害調査をしたい。<br />
ログを見たい。<br />
設定を戻したい。<br />
サービスを再起動したい。</p>
<p id="500321ae-2288-4ffe-991e-c4cd6b3971d4">そう思っても、そもそもサーバに入れなければ作業できません。</p>
<p id="dbde0e8d-01b9-4d74-918e-8b368e19ec64">SSHログイン不可は、単なる接続ミスではありません。<br />
復旧作業の入口を塞いでしまう、かなり重いトラブルです。</p>
<hr id="5a6156a4-10a6-4594-864d-43a8a4cb061e" />
<h2 id="951c891c-9a40-4c8a-b5c1-ad369cc308e9" tabindex="-1"><span id="toc2">最初に疑いたくなるポイント</span></h2>
<p id="57a57474-7883-45b8-828c-225297299ec5">SSHログインできない場合、まず疑うのは、だいたい次のような箇所です。</p>
<ul id="14102b9b-c41a-4e40-b35b-0434dda246a4">
<li>
<p id="001ae693-ae75-4c96-9a29-42e199b89504">セキュリティグループ</p>
</li>
<li>
<p id="de2db11b-9d8f-4143-a7e0-4f6713ddb90c">ネットワークACL</p>
</li>
<li>
<p id="ce26a2ca-1633-4510-932f-65bceb7a2f95">ルートテーブル</p>
</li>
<li>
<p id="5f23d0d6-ff00-4496-bd5d-0090f1c9ffca">鍵の指定ミス</p>
</li>
<li>
<p id="ddc6af79-e4fa-485d-8a6e-5ca6871d0a0b">ユーザー名の誤り</p>
</li>
<li>
<p id="d2f838ef-fa08-4319-a461-865399f1206d">/etc/ssh/sshd_config の設定</p>
</li>
<li>
<p id="485b95da-c881-4527-9837-9e1610c8c01b">sshd サービスの状態</p>
</li>
<li>
<p id="bd33e401-23e7-40ef-8506-c6a91e693a7e">OS側のファイアウォール</p>
</li>
</ul>
<p id="c142dea2-01e5-4a70-adec-dd6c7a6f95be">もちろん、これらを確認すること自体は正しいです。</p>
<p id="5f88259f-fa56-41d8-a672-cc758e85e07c">SSH接続不可の調査では、ネットワーク、認証、OS設定、サービス状態を順番に切り分ける必要があります。</p>
<p id="6fbde4bb-f17f-4044-83a0-5467f4201420">ただ、今回の事象では、単純に /etc/ssh/sshd_config だけを見ていても原因にたどり着きにくいものでした。</p>
<p id="f01d1e61-5a4b-4973-82c5-ccce52493ecf">なぜなら、SSHの設定を<strong>起動時に別の仕組みが変更していた可能性がある</strong>からです。</p>
<hr id="ddf000af-8c1c-4f36-81c1-721adb8610d5" />
<h2 id="0f52bf01-f923-4c81-a696-ee17e0eb7cab" tabindex="-1"><span id="toc3">原因：cloud-initがSSH設定を上書きしていた</span></h2>
<p id="7f13d92a-e447-494b-8df7-ad31668f718f">原因は、cloud-init の設定でした。</p>
<p id="6ba9707e-c6de-47a1-97bf-4e5b98754994">cloud-init は、クラウド環境でインスタンス起動時に初期設定を行う仕組みです。</p>
<p id="475d0b76-f1cf-40c7-80d5-2aeb0ae68f3f">EC2でLinuxインスタンスを起動するとき、ホスト名、ユーザー、SSH関連設定、ユーザーデータなど、起動時にさまざまな初期処理が行われます。</p>
<p id="8292283f-43b8-4d8b-9331-9e8861261673">今回問題になったのは、次の設定です。</p>
<div class="code-block-container">
<pre id="60c1c818-7254-4db1-bc68-4d3dc618ae37" data-name="preCode"><code class="hljs" data-name="code">/etc/cloud/cloud.cfg
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<div class="code-block-container">
<pre id="6c01c445-6638-4f7b-9d67-397dfdba187a" data-name="preCode"><code class="hljs" data-name="code">ssh_pwauth: 0
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="a451dd91-d4f9-422f-9238-e9ee003d82bf">この `ssh_pwauth: 0` は、SSHのパスワード認証を無効にするための設定です。</p>
<p id="4612a75d-2c1e-4e71-93a3-2adc178d4625">クラウド環境では、パスワード認証よりも鍵認証、IAM、SSM Session Managerなどで接続経路を管理する方が、セキュリティ上のベストプラクティスに沿いやすいため、このような初期設定になっていることがあります。</p>
<p id="79f2036c-69b9-4994-a89d-c4ec924e0416">問題は、その設定自体ではありません。</p>
<p id="fb823a01-2107-4cb6-a5d4-911fd405766c">運用上の理由でパスワード認証を使う設計にしている場合、`cloud-init` 側の設定を理解していないと、AMIから起動したときに想定外のログイン不可につながる、という点です。</p>
<p id="aadbe3fb-136f-4741-bd18-5ccb81110641">この状態でAMIからインスタンスを起動すると、起動時に cloud-init が動作し、SSHの設定を反映することがあります。</p>
<p id="7a46b9a4-006c-4a70-85ee-0af8c994df66">その結果、/etc/ssh/sshd_config が次のような状態になる場合があります。</p>
<div class="code-block-container">
<pre id="f10bee12-ec60-4930-812f-0d5948fb6bef" data-name="preCode"><code class="hljs" data-name="code">/etc/ssh/sshd_config
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<div class="code-block-container">
<pre id="7d32fa85-c173-438d-b524-5fb9fdfef20b" data-name="preCode"><code class="hljs" data-name="code">PasswordAuthentication no
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="0a5568eb-51f1-4f20-89ac-336ae6522925">つまり、AMI取得前に手作業で /etc/ssh/sshd_config を変更していたとしても、AMIから起動したタイミングで cloud-init 側の設定が再度反映されることがあります。</p>
<p id="05e3864d-70ed-4883-8936-58fd263acb49">ここが落とし穴です。</p>
<p id="fa78c942-ed92-496e-a8a5-431c60617352">AMIから新しいEC2インスタンスを作成した場合、cloud-init はそれを新しいインスタンスの初回起動として扱い、初期設定を再実行することがあります。</p>
<p id="861f5cbe-9ecd-4aad-818b-8ed6c48a65d9">そのため、</p>
<div class="code-block-container">
<pre id="81c56d59-b6a5-47df-87f6-f26200f4a731" data-name="preCode"><code class="hljs" data-name="code">元サーバではログインできていた
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="9a20a8dd-e479-47d4-8427-2a2239bc9b02">ことと、</p>
<div class="code-block-container">
<pre id="15620a5d-5a60-408b-8122-1568bd399aca" data-name="preCode"><code class="hljs" data-name="code">AMIから起動した新インスタンスでも同じようにログインできる
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="ec3f4f33-ba7b-47b4-9e8a-1326f77f7667">ことは、必ずしも同じではありません。</p>
<p id="a94b0669-b148-489e-a7c8-255fe50e6fc9">クラウド環境では、ここを混同するとトラブルにつながります。</p>
<figure id="32c760c9-94cb-4317-bd4c-c1ef05f8fd00"><a href="https://assets.st-note.com/img/1780453706-AKchjDZYB1FICtlpV7La3y5f.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780453706-AKchjDZYB1FICtlpV7La3y5f.png?width=1200" alt="画像" width="620" height="775" data-modal="true" /></a><figcaption>　　　　　　　　　　　　　　　　　　図　混同しやすいポイント</figcaption></figure>
<hr id="5aa8661a-ceb2-40f9-afd7-19e597adfcff" />
<p id="58c95cba-cd2a-4225-a24a-8768f3a73cf7"><strong>図で見るとこういう流れ</strong></p>
<p id="ea5a00ae-66d6-4eb6-a5dd-0b62b7c9606a">この事象を図で整理すると、流れはこうです。</p>
<ul id="543a1ea2-ba98-496c-8f4d-39fa7d1007af">
<li>
<p id="22da03bb-dfac-4145-8c57-0a7a3f1f6714">AMI取得前は、sshd_config 上ではパスワード認証が有効</p>
</li>
<li>
<p id="1a3445c7-dfa0-483f-b744-b0d7bf573c55">しかし、cloud.cfg には ssh_pwauth: 0 が残っている</p>
</li>
<li>
<p id="82b04bf3-2da5-4a6c-b94c-cb3e2fc5b85a">AMIから新しいインスタンスを起動すると、cloud-init が実行されることがある</p>
</li>
<li>
<p id="ca469df6-4655-49e1-85b4-6a274557904a">cloud-init が設定を反映し、sshd_config が書き換えられることがある</p>
</li>
<li>
<p id="43c3fecc-99de-4332-bc56-c6bed01cc34d">結果として、PasswordAuthentication no になり、SSHパスワードログインできなくなる</p>
</li>
</ul>
<figure id="c27a8ab0-93a2-400e-8216-1ba12fdd9f74"><a href="https://assets.st-note.com/img/1780453760-tEnmgh6x4owQuDLB5csA7SPj.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85" aria-label="画像を拡大表示"><img loading="lazy" decoding="async" class="is-slide" src="https://assets.st-note.com/img/1780453760-tEnmgh6x4owQuDLB5csA7SPj.png?width=1200" alt="画像" width="620" height="775" data-modal="true" /></a><figcaption>　　　　　　　　　　　　　　図　AMI起動時にSSH設定が上書きされる流れ</figcaption></figure>
<p id="efe3ac6a-5141-423c-9aa2-fb0b9e761f50">見るべきポイントは、</p>
<div class="code-block-container">
<pre id="eac77e66-563f-41cd-80fd-ebbf1375bbf4" data-name="preCode"><code class="hljs" data-name="code">今のsshd_configがどうなっているか
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="17a6770c-4716-4a80-951c-2b45eaf56ea1">だけではありません。</p>
<div class="code-block-container">
<pre id="7edefa1a-1c87-4d1e-a5ae-a22227a16575" data-name="preCode"><code class="hljs" data-name="code">起動時に誰がsshd_configを書き換える可能性があるか
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="73cc33ae-88c9-4a20-b9fa-0753f236f42a">まで見る必要があります。</p>
<p id="530c7c2f-b329-4f40-8ab3-a2830cbb6a8b">クラウド環境では、ある時点の設定ファイルだけを見ても不十分です。</p>
<p id="a5899767-08ed-45b4-90db-d6f97f57ead3">その設定が、いつ、誰によって、どのタイミングで反映されるのか。</p>
<p id="fb81583b-dcd0-446f-b201-8dfc89401eda">ここまで見ないと、起動後の状態を正しく予測できません。</p>
<hr id="2cc57369-4fd5-493c-8c5b-066484ef17cc" />
<h2 id="7781322a-701e-43b2-90d4-40a5436a2d8e" tabindex="-1"><span id="toc4">対策：cloud-init側の設定も確認する</span></h2>
<p id="2aa330d9-ad2b-4c88-9807-1f50405e619f">対策は、/etc/ssh/sshd_config だけではなく、cloud-init 側の設定も確認することです。</p>
<p id="2a922820-2473-445b-966f-afb44e4488cb">今回の例では、SSHパスワード認証を有効にする必要がある場合、次のように設定します。</p>
<div class="code-block-container">
<pre id="ea540dcd-aa37-4dc4-aac1-66b6795264dd" data-name="preCode"><code class="hljs" data-name="code">ssh_pwauth: 1
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="6ad5ff15-37aa-4e5a-af18-afcf4ca5557b">これにより、AMIからインスタンスを起動した際に、SSHパスワード認証を有効にする設定として扱われます。</p>
<p id="a1f7a294-eb63-4ae5-965c-74887686f5be">結果として、/etc/ssh/sshd_config 側も次のようになります。</p>
<div class="code-block-container">
<pre id="75348672-bbe1-449c-9dd3-abb234e71177" data-name="preCode"><code class="hljs" data-name="code">PasswordAuthentication yes
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="0dd2b3e3-52af-4eab-ac4a-8691cb06697e">ただし、新しめのRHEL系OSや最近のAMIでは、/etc/cloud/cloud.cfg 本体を直接編集するよりも、</p>
<p id="795f9ab8-8e72-42f4-a7d0-75b5562942fb"><strong>追加設定ファイルとして管理する方が望ましい場合があります。</strong></p>
<p id="9e2b1e02-3028-4b8b-a55b-40376e795862">たとえば、次のようなファイルです。</p>
<div class="code-block-container">
<pre id="e06b8d85-cb5e-4793-8b97-15fe20aaafa7" data-name="preCode"><code class="hljs" data-name="code">/etc/cloud/cloud.cfg.d/99_custom_ssh.cfg
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="02334ef3-ce5b-4600-ab5e-101d25a614cf">中身は、たとえば次のようにします。</p>
<div class="code-block-container">
<pre id="5a56000f-924b-41cf-90ab-261368217c2c" data-name="preCode"><code class="hljs" data-name="code">ssh_pwauth: 1
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="4d876477-3aab-4257-9378-e587e57e9096">cloud.cfg 本体は基本設定として残し、環境ごとの差分や個別設定は cloud.cfg.d 配下のファイルで管理する、という考え方です。</p>
<p id="ccda3f9f-a7e5-4f5e-b14d-c322a4d11a35">ただし、どの方法を使うべきかは、利用しているOS、AMI、cloud-init のバージョン、運用ルールによって変わります。</p>
<p id="2efbe15e-b227-43be-b504-a18a4a54865f">重要なのは、見えている設定だけを直すことではありません。</p>
<p id="620b8a89-1731-473d-9b99-ed08e9d26fa6">それを後から上書きする仕組みが残っていないかを見ることです。</p>
<hr id="495f6e68-16a9-4858-926d-b410692da0f7" />
<h2 id="e92c4ff7-a477-490b-862a-e41c23cbec09" tabindex="-1"><span id="toc5">起動後に確認するコマンド例</span></h2>
<p id="75d541f8-193f-4554-a25c-435af1f20d20">実際のトラブルシューティングでは、</p>
<p id="49b2387b-d4b5-449a-b86f-8e4283a19afd">「起動後に本当に sshd_config がどうなっているのか」<br />
「cloud-init が動いていた形跡はあるのか」</p>
<p id="2e14d9ed-f2b3-4a8d-93f6-baedc2311e9e">を確認したくなります。</p>
<p id="30fe7b62-d25b-4545-a5a5-c2459edc0386">まず、起動後のSSH設定は、次のように確認できます。</p>
<div class="code-block-container">
<pre id="bb3c05b8-3c26-4e02-be81-a54200898854" data-name="preCode"><code class="hljs javascript" data-name="code">grep -i <span class="hljs-string">'^PasswordAuthentication'</span> /etc/ssh/sshd_config
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="6c3e0abc-4285-417b-9765-c364ed3fbcc1">パスワード認証が有効であれば、次のように表示されます。</p>
<div class="code-block-container">
<pre id="7402f167-fcf4-484a-bfc8-fc3a12572fc6" data-name="preCode"><code class="hljs" data-name="code">PasswordAuthentication yes
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="fe4a7111-25bd-4a21-abd7-ac224af4fa15">逆に、意図せず無効化されている場合は、次のようになります。</p>
<div class="code-block-container">
<pre id="3c6dc641-3e1a-454b-bf16-fd9103aee0d0" data-name="preCode"><code class="hljs" data-name="code">PasswordAuthentication no
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="7d27279a-4f6f-4c42-ab7c-04f7fc58618a">また、cloud-init が起動時に動作していたかを確認するには、ログを見る方法があります。</p>
<div class="code-block-container">
<pre id="59033b64-7a06-420d-9acd-a7de71dccd2f" data-name="preCode"><code class="hljs javascript" data-name="code">sudo grep -i <span class="hljs-string">'ssh\|pwauth\|PasswordAuthentication'</span> /<span class="hljs-keyword">var</span>/log/cloud-init.log
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="cd410d04-5436-4eb8-9a46-42e99da7d305">ただし、ログの出方は、OS、AMI、cloud-init のバージョンによって異なります。</p>
<p id="46a406f0-edd1-40f0-a12c-9dfb84a0e151">このコマンドで必ず原因が一発で分かる、というものではありません。</p>
<p id="6537b2ab-f742-4ec3-8ccd-c5581e21e9bb">重要なのは、起動後の /etc/ssh/sshd_config だけでなく、起動時に cloud-init が何を実行したのかも確認することです。</p>
<hr id="532b6207-9705-4a02-bca5-3838a53572f4" />
<h2 id="fea0d372-873c-4eef-87ee-2fbc5a5ece06" tabindex="-1"><span id="toc6">RHEL 8/9/10でも考え方は同じ</span></h2>
<p id="80d9fb34-3483-4aeb-b5e5-16e32ce00045">ここまでの話は、特定の古いRHEL環境だけの話ではありません。</p>
<p id="4fd849c2-b5c0-4b0a-97e1-b80a3ff40537">RHEL 8、RHEL 9、RHEL 10などのRHEL系OSでも、cloud-init がインスタンス起動時の初期設定に関与するという考え方は同じです。</p>
<p id="7b34d773-ba7f-4776-b32d-0f61909c63a7">そのため、AMIから新しいインスタンスを起動したときに、cloud-init の設定に基づいてSSH関連設定が反映される可能性があります。</p>
<p id="3cdcda2f-358c-43fb-9939-13725db0ec9f">ただし、OSバージョン、AMIの提供元、cloud-init のバージョンによって、デフォルト値や設定ファイルの構成は異なります。</p>
<p id="4067ee6c-5a55-405f-916a-145278335ebd">つまり、見るべきポイントは、RHELのバージョン名だけではありません。</p>
<ul id="88f5794f-8f96-4120-81ff-020f09f578f3">
<li>
<p id="5890182a-248c-48cd-877d-6d00d8d2f2dc">cloud-init が何を管理しているか</p>
</li>
<li>
<p id="b853ac3a-009d-47dd-a0cd-41b587270d7c">cloud.cfg や cloud.cfg.d に何が書かれているか</p>
</li>
<li>
<p id="3a5c6b11-cb95-4165-8e8b-e4bc3df49ce3">AMIから新規起動したときに何が再実行されるか</p>
</li>
<li>
<p id="08b96f81-facc-4498-a828-c2767d837778">sshd_config が最終的にどうなっているか</p>
</li>
<li>
<p id="99c803ed-60f3-4b42-a95a-308c62f127ff">SSHログインできなくなった場合の復旧経路があるか</p>
</li>
</ul>
<p id="dbf18ae7-fd97-4f45-9b0c-c7e898f80458">最新版でも見るべき本質は変わりません。</p>
<p id="eb04befc-262d-40b5-84f1-3229d282f6fa"><strong>「SSH設定ファイルを直したから終わり」ではなく、起動時にその設定を上書きする仕組みが残っていないかを見る。</strong></p>
<p id="85018583-0fa2-4e5e-b540-6cd0c3d70f74">これが重要です。</p>
<hr id="167b05c3-5f04-4967-893b-4cc042306742" />
<h2 id="edb89341-92e3-48e3-b264-7c021b332529" tabindex="-1"><span id="toc7">もし実際に入れなくなったら</span></h2>
<p id="625d23a1-24a4-4827-a7a6-62f444b797f4">実際にSSHログインできなくなった場合でも、環境によっては救出手段が残っていることがあります。</p>
<p id="40adc55e-c430-4b2c-b956-e3d0ad05780e">たとえば、EC2 Instance Connectが利用できる条件であれば、別経路で接続できる可能性があります。</p>
<p id="3fe2f20f-237e-4e40-9430-b5466023022c">また、SSM Agentが動作しており、必要なIAMロールやネットワーク経路が用意されている場合は、SSM Session Managerから接続できる可能性があります。</p>
<p id="d9bac4a6-23fd-4c85-a586-2ed40534eacb">さらに、NitroベースのインスタンスでEC2シリアルコンソールが有効化されていれば、ネットワーク経由のSSHに依存せずにトラブルシュートできる場合もあります。</p>
<p id="81b22517-6870-4cba-9b45-685d92990fef">ただし、これらは万能ではありません。</p>
<p id="abc7e2ec-c015-424f-b52d-e1f6a93f32ac">事前の有効化、IAM権限、対応OS、インスタンスタイプ、ネットワーク条件、SSM Agentの状態などに左右されます。</p>
<p id="bb442424-ce95-4b4e-b761-7fdbd28d17eb">障害が起きてから初めて使おうとしても、すぐに使えるとは限りません。</p>
<p id="0f73103a-194a-43e0-a501-bedce28cd82f">最低限、AMIを作成する前に、EC2 Instance ConnectやSSM Session Managerなど、SSH以外の接続経路が使える状態かを確認しておくことが、現実的な保険になります。</p>
<p id="94217794-29b4-41e9-a55b-7ffb0c93b00e">「入れなくなったら考える」では遅い場合があります。</p>
<hr id="aeb7e86b-f524-4a3c-8e3a-cffa7adc9ac7" />
<h2 id="7f748367-342f-46c6-887e-4674700e0d73" tabindex="-1"><span id="toc8">ただし、パスワード認証を推奨する話ではない</span></h2>
<p id="b01423ea-cb35-4bde-9812-fd7453112f14">ここで誤解してはいけないのは、この記事はSSHのパスワード認証を推奨する話ではない、ということです。</p>
<p id="460d999e-6a09-44be-aaa1-3a2e8961a0b2">本番環境では、SSH接続方式は慎重に設計すべきです。</p>
<p id="13363f16-53cf-4a8e-ae22-c47f575f8dc1">鍵認証を使うのか。<br />
踏み台サーバを経由するのか。<br />
SSM Session Managerを使うのか。<br />
IAMやMFAと組み合わせるのか。<br />
運用者のアクセス経路をどう制限するのか。<br />
障害時の緊急ログイン手段をどうするのか。</p>
<p id="ca89672f-2944-4070-9d1f-844e3af285b8">これらは、セキュリティ要件や運用要件に応じて決めるべきものです。</p>
<p id="2ec0305f-e2ea-4c92-b075-50e1372b9a60">今回伝えたいのは、</p>
<div class="code-block-container">
<pre id="a5a556a6-46f0-45ef-8c8e-52cafbbbda2a" data-name="preCode"><code class="hljs" data-name="code">パスワード認証を有効にしましょう
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="9ad23394-3ef0-4060-9f5e-d6119224d054">という話ではありません。</p>
<p id="3b24d5b1-96ae-4b6a-a259-a19c8877c123">そうではなく、</p>
<div class="code-block-container">
<pre id="caac8f7c-bef7-4a44-81f7-99333043faac" data-name="preCode"><code class="hljs" data-name="code">AMIから起動したとき、OS設定がそのまま維持されるとは限らない
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="55f6a13e-1c3e-47d3-a909-ca649e9a5142">という話です。</p>
<p id="d0aace8e-5a1e-4a98-9f22-b5e9d5d75bdb">もっと言えば、</p>
<div class="code-block-container">
<pre id="8cf49ba8-9db1-4c48-a845-da1e57263088" data-name="preCode"><code class="hljs" data-name="code">起動時に設定を書き換える仕組みを知らないと、
設計したつもりの状態でサーバが起動しない
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="788a7782-71d0-4878-99ff-611a6881587e">という話です。</p>
<hr id="4ad0c206-ecc7-49bb-b533-f14ae5c7148f" />
<h2 id="6ea0960b-1423-4771-af49-49913cd4f924" tabindex="-1"><span id="toc9">まとめ</span></h2>
<p id="440dc3e6-9b3d-47ab-b1e0-b681f47d1a47">今回の事象は、RHEL系のEC2環境でAMIからインスタンスを起動した際、SSHのパスワードログインができなくなったというものです。</p>
<p id="b4e09db0-793d-482c-acc9-45bba9b44597">原因は、cloud-init 側にSSHパスワード認証を無効化する設定が残っていたことでした。</p>
<div class="code-block-container">
<pre id="1a372398-12cf-4227-8e9a-558c0d446d55" data-name="preCode"><code class="hljs" data-name="code">ssh_pwauth: 0
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="b18263ba-8743-46a3-b6d2-c19d4288288c">この設定により、AMI起動時に cloud-init がSSH設定を反映し、PasswordAuthentication no になることがあります。</p>
<p id="004532ac-4b35-4f22-9a5d-b2605c9262c3">対策としては、必要に応じて cloud.cfg または cloud.cfg.d 配下の設定を確認し、SSHパスワード認証をどう扱うかを明示します。</p>
<div class="code-block-container">
<pre id="57c8f883-1000-44be-bdfd-2809c592b7cc" data-name="preCode"><code class="hljs" data-name="code">ssh_pwauth: 1
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="31822948-1889-43e3-9943-3be79c0d7dbd">そして、起動後の sshd_config が期待どおりになっているか確認します。</p>
<div class="code-block-container">
<pre id="8ae399a5-2388-477f-bd1b-2522d655085e" data-name="preCode"><code class="hljs" data-name="code">PasswordAuthentication yes
</code></pre>
<div class="a-button__inner" data-v-00506f85=""><span data-v-80ab2cbc=""><span class="visually-hidden" data-v-80ab2cbc="">copy</span><i class="a-icon a-icon--copy a-icon--size_small" aria-hidden="true" data-v-80ab2cbc=""></i></span></div>
</div>
<p id="0cd5f183-4076-45fe-8cb8-b490f92a3943">ただし、重要なのはパスワード認証を有効にすることではありません。</p>
<p id="682bd220-e548-40f1-91d8-f7a366b9ae63">本質は、<strong>クラウド環境では、OSの設定ファイルだけを見ても不十分</strong>だということです。</p>
<p id="af228afc-2b3d-4f32-9ab9-dd1b367d7013">AMI、cloud-init、ユーザーデータ、Launch Template、Auto Scaling、構成管理ツール、起動後スクリプト。<br />
こうした仕組みが、サーバ起動時や再作成時に設定を書き換えることがあります。</p>
<p id="699784fa-58ac-480c-9370-c4cca4da3939">AMIを使う設計では、最低限、次の観点を確認しておくべきです。</p>
<ul id="ec045af4-e5d0-4c69-8ecd-b856dd2b7c01">
<li>
<p id="015af15a-38c4-4dc9-969a-c0e17cb670ed">cloud.cfg や cloud.cfg.d にSSH関連設定が残っていないか</p>
</li>
<li>
<p id="21acd8ec-6e16-4736-b835-259f6249105e">AMI起動後に cloud-init が何を実行するか把握しているか</p>
</li>
<li>
<p id="b0879987-ea96-4968-a349-c6c4e7accf28">起動後に sshd_config が期待値になっているか確認したか</p>
</li>
<li>
<p id="1fb883ba-edac-4748-b88e-798b8b7a8b1a">SSHログインできなくなった場合の復旧経路があるか</p>
</li>
</ul>
<p id="b0ca5601-48d2-4d5d-a179-fd3138744322">「設定したはずなのに、なぜか反映されていない」。</p>
<p id="db0534a2-a1fc-4f55-80af-6875b56d492a">そういう事象に当たったとき、OSの設定ファイルだけでなく、起動時に何が動いているかを問う習慣が、現場での対応速度を変えます。</p>
<p id="929aa116-cd5b-45b9-88ab-196a0b21cc51">これは、基盤SEやインフラエンジニアだけでなく、クラウド上で動くシステムに関わるアプリケーションエンジニアにとっても大事な視点だと思います。</p>
<hr id="eca7a3da-c617-4306-b8f3-d8639cf9360e" />
<h2 id="13a242b4-1f49-4fb1-8422-674edecb85ac" tabindex="-1"><span id="toc10">関連記事</span></h2>
<p id="29a25e49-e7c3-453f-8ec1-a3d03e4efad2">今回の話は、単なるSSH設定の話ではなく、詳細設計・運用設計で「起動時に何が反映されるか」を見落とさない、という話でもあります。</p>
<p id="a74373b3-48ac-4d9e-bfc4-77c788da1cac">この考え方については、以下の記事でも整理しています。</p>
<p id="b531dedc-61a0-4cd6-baa1-46d8614e45d8"><a rel="nofollow" href="https://sys-univ.com/dev/detailed-design-overview/" target="_blank">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p id="ebf78501-a070-4777-8b88-b5478a8b8985">シリーズ全体は<a rel="nofollow noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/incident/sshfail/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>S3バケットにあるのに取得できない｜クロスアカウント構成で見落とした「オブジェクト所有者」の罠</title>
		<link>https://sys-univ.com/incident/s3-cross-account-object-owner/</link>
					<comments>https://sys-univ.com/incident/s3-cross-account-object-owner/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Sun, 21 Jun 2026 02:49:35 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[トラブル]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=2701</guid>

					<description><![CDATA[この記事では、クロスアカウント構成で「権限があるはずなのにS3オブジェクトを取得できない」原因と、それを防ぐために設計・テスト工程で何を見るべきかを整理します。 「設定は合っているはずなのに、取れない」 権限設定もした。 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">この記事では、クロスアカウント構成で「権限があるはずなのにS3オブジェクトを取得できない」原因と、それを防ぐために設計・テスト工程で何を見るべきかを整理します。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<p class="wp-block-paragraph">「設定は合っているはずなのに、取れない」</p>


<p class="wp-block-paragraph">権限設定もした。<br />
バケットも見える。<br />
テストも通った。</p>


<p class="wp-block-paragraph">それなのに、本番で特定のファイルだけ取得できない。</p>


<p class="wp-block-paragraph">こういう問題は、AWSの仕様を知らないというより、<strong>誰が作ったオブジェクトなのか</strong>まで設計・テストしていなかったことで起きます。</p>


<p class="wp-block-paragraph">今回は、S3のクロスアカウント構成で実際に起きた事象をもとに、単なる技術論ではなく、設計とテスト観点の話として整理します。</p>


<p class="wp-block-paragraph">AWSでS3を使っていると、ついこう考えてしまいます。</p>


<p class="wp-block-paragraph">「S3バケットへの権限を付ければ、その中のオブジェクトも操作できるはず」</p>


<p class="wp-block-paragraph">しかし、クロスアカウント構成では、この前提が崩れることがあります。</p>


<p class="wp-block-paragraph">バケットは見える。<br />
オブジェクトも存在する。<br />
ユーザーがアップロードしたファイルは取得できる。</p>


<p class="wp-block-paragraph">それなのに、AWSサービスが出力したオブジェクトだけ取得できない。</p>


<p class="wp-block-paragraph">一見すると、IAMポリシーの設定ミスに見えます。<br />
しかし、原因は単純な権限不足ではありませんでした。</p>


<p class="wp-block-paragraph">今回の本質は、S3の操作権限だけではなく、<strong>オブジェクトの所有者まで設計・テストしていたか</strong>という話です。</p>



  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-18" checked><label class="toc-title" for="toc-checkbox-18">目次</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">直接取りに行くのをやめ、バケット側のロールを使った</a></li><li><a href="#toc5" tabindex="0">テストで手動ファイルだけ見ていたら、この問題は見逃される</a></li><li><a href="#toc6" tabindex="0">「同じバケットなら同じ扱い」という思い込みが危ない</a></li><li><a href="#toc7" tabindex="0">「取れました」で終わらせないためのチェックポイント</a></li><li><a href="#toc8" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">バケットにはあるのに、なぜか取得できなかった</span></h2>


<p class="wp-block-paragraph">構成としては、アカウントAから、アカウントBのS3バケットにあるオブジェクトを取得する必要がありました。</p>


<p class="wp-block-paragraph">アカウントBにS3バケットがあり、そこに複数のオブジェクトが存在していました。</p>


<p class="wp-block-paragraph">その中には、ユーザーが手動でアップロードしたオブジェクトもあれば、AWSサービスが出力したオブジェクトもありました。</p>


<p class="wp-block-paragraph">たとえば、S3アクセスログやCloudTrailログのように、AWSサービス側の処理によってS3へ出力されるファイルです。</p>


<p class="wp-block-paragraph">また、AWSサービスではなくても、別アカウントのEC2やバッチ処理がS3へ書き込む構成では、同じように「誰が作成したオブジェクトなのか」が問題になることがあります。</p>


<p class="wp-block-paragraph">現象としては、次のような状態でした。</p>


<p class="wp-block-paragraph">ユーザーがアップロードしたオブジェクトは取得できる。<br />
しかし、AWSサービスが出力したオブジェクトは取得できない。</p>


<p class="wp-block-paragraph">CLIであれば、AccessDeniedや403 Forbiddenのようなエラーとして見えることがあります。</p>


<p class="wp-block-paragraph">ただし、このエラーだけを見ても、IAMポリシー不足なのか、バケットポリシーなのか、オブジェクト所有者なのかはすぐには分かりません。</p>


<p class="wp-block-paragraph">同じS3バケット内にあるにもかかわらず、取得できるものと取得できないものが混在していたのです。</p>


<p class="wp-block-paragraph">この時点で、単純な「バケットに対する権限不足」とは言い切れません。</p>


<p class="wp-block-paragraph">もしバケットそのものへのアクセス権限が不足しているのであれば、ユーザーがアップロードしたオブジェクトも取得できないはずです。</p>


<p class="wp-block-paragraph">しかし実際には、一部のオブジェクトは取得できていました。</p>


<p class="wp-block-paragraph">つまり、問題はバケット単位ではなく、<strong>オブジェクト単位の条件差</strong>にありました。</p>


<figure id="7fa459d4-ded0-4e78-bac2-828e84f533db" class="wp-block-image"><a href="https://assets.st-note.com/img/1780552246-n6aZJRfB9lkz3uwLD0sPQSc1.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780552246-n6aZJRfB9lkz3uwLD0sPQSc1.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">図1：同じS3バケット内で取得できるオブジェクトと取得できないオブジェクトが混在する</figcaption>
</figure>


<h2 class="wp-block-heading"><span id="toc2">見落としていたのは、バケットではなくオブジェクトの所有者だった</span></h2>


<p class="wp-block-paragraph">原因は、オブジェクトの所有者が異なっていたことです。</p>


<p class="wp-block-paragraph">S3では、バケットの所有者と、オブジェクトの所有者が常に同じとは限りません。</p>


<p class="wp-block-paragraph">特にクロスアカウント構成や、AWSサービスがS3に出力する構成では、この点を意識する必要があります。</p>


<p class="wp-block-paragraph">昔のS3では、ACLによってバケットやオブジェクト単位の権限を細かく制御する考え方が使われていました。その名残がある既存環境では、現在の新規バケットとは異なる前提で動いていることがあります。</p>


<p class="wp-block-paragraph">今回の場合、ユーザーがアップロードしたオブジェクトは、想定していた権限設計の範囲で操作できました。</p>


<p class="wp-block-paragraph">一方、AWSサービスが出力したオブジェクトは、所有者や権限の扱いが異なっていました。</p>


<p class="wp-block-paragraph">AWSサービスがS3にオブジェクトを出力する場合、利用者が手動でアップロードしたファイルと同じ所有者・同じ権限になるとは限りません。</p>


<p class="wp-block-paragraph">バケットのObject Ownership設定、ACLの扱い、サービス側の出力仕様によって、バケット所有者がそのまま自由に操作できるとは限らない状態が発生します。</p>


<p class="wp-block-paragraph">そのため、アカウントAからアカウントBのS3バケットに対する操作を許可していても、対象オブジェクトによっては取得できない状態になっていました。</p>


<p class="wp-block-paragraph">ここで重要なのは、次の点です。</p>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>「S3バケットにある」ことと「そのオブジェクトを操作できる」ことは同じではない。</strong></p>
</blockquote>


<p class="wp-block-paragraph">S3をファイルサーバーのように見ていると、この違いを見落とします。</p>


<p class="wp-block-paragraph">ディレクトリの中にファイルがある。<br />
だから、フォルダに権限を付ければ中のファイルも読める。</p>


<p class="wp-block-paragraph">オンプレのファイルサーバー感覚では、こう考えがちです。</p>


<p class="wp-block-paragraph">しかし、S3ではこの前提がそのまま通用しません。</p>


<p class="wp-block-paragraph">今回の直接原因は「オブジェクト所有者」でしたが、そもそもS3の権限設計は単一の概念では完結しません。</p>


<p class="wp-block-paragraph">S3では、バケット、オブジェクト、オブジェクト所有者、バケットポリシー、IAMロール、ACL、Object Ownershipなど、複数の要素が絡みます。</p>


<p class="wp-block-paragraph">現在のAWSでは、S3 Object OwnershipのBucket owner enforcedを使い、ACLを無効化して、バケットポリシーやIAMポリシーで制御する設計が基本です。新規バケットではBucket owner enforcedがデフォルトになっています。</p>


<p class="wp-block-paragraph">ただし、既存環境や移行案件では、過去に作成されたバケット、既存アプリケーション、ACL前提の処理、サービス出力、外部連携が残っていることがあります。</p>


<p class="wp-block-paragraph">そのため、「今のAWSではデフォルトがこうだから、この問題は起きない」とは言い切れません。</p>


<p class="wp-block-paragraph">既存環境では、今回のようにオブジェクト所有者やACLの考え方が残っていて、運用時に問題として表面化することがあります。</p>


<figure id="1d26c944-6264-4682-9a73-4f656471cb87" class="wp-block-image"><a href="https://assets.st-note.com/img/1780552157-nqPe7tudNMJRCkY5rEsjpI9X.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780552157-nqPe7tudNMJRCkY5rEsjpI9X.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">図2：S3の権限設計に関わる要素の関係</figcaption>
</figure>


<p class="wp-block-paragraph">このように、S3では「バケットに権限を付けたから終わり」ではありません。</p>


<p class="wp-block-paragraph">誰がバケットを持っているのか。<br />
誰がオブジェクトを作ったのか。<br />
そのオブジェクトの所有者は誰なのか。<br />
どのアカウント、どのIAMロールで操作するのか。</p>


<p class="wp-block-paragraph">ここまで整理しないと、実際の運用で詰まります。</p>


<h2 class="wp-block-heading"><span id="toc3">誰に権限を付けるかではなく、誰として操作するかを決めた</span></h2>


<p class="wp-block-paragraph">今回の対策を考えるうえで、最初に整理すべきだったのは、単に「誰にS3権限を付けるか」ではありません。</p>


<p class="wp-block-paragraph">見るべき観点は、次のようなものでした。</p>


<ul id="a3336fcb-b595-4136-917a-838f3edbb728" class="wp-block-list">
	<li>誰がバケットを所有しているのか。</li>


	<li>誰がオブジェクトを作成するのか。</li>


	<li>作成されたオブジェクトの所有者は誰になるのか。</li>


	<li>そのオブジェクトを誰が読むのか。</li>


	<li>読む主体はユーザーなのか、IAMロールなのか、別アカウントのサービスなのか。</li>


	<li>対象はユーザーがアップロードしたファイルだけなのか、AWSサービスが出力したファイルも含むのか。</li>
</ul>


<p class="wp-block-paragraph">ここまで整理して初めて、対策の方向性が決まります。</p>


<p class="wp-block-paragraph"><strong>現在のAWS設計として優先すべき方向は、S3 Object OwnershipをBucket owner enforcedにし、ACLを無効化して、バケット所有者に所有権を寄せることです。</strong></p>


<p class="wp-block-paragraph">新規プロジェクトであれば、基本的にはこの設計を第一候補にすべきです。</p>


<p class="wp-block-paragraph">この設計にできれば、オブジェクトごとのACL差分や所有者差分による混乱を減らせます。</p>


<p class="wp-block-paragraph">ただし、現場では理想形にすぐ寄せられないことがあります。</p>


<ul id="ba52f555-0cdd-4dd3-b266-3467a1256aef" class="wp-block-list">
	<li>既存アプリケーションがACLを前提にしている。</li>


	<li>外部サービスや既存ジョブの出力仕様が変えられない。</li>


	<li>過去に作成されたオブジェクトが大量にある。</li>


	<li>設定変更による影響範囲をすぐに確認できない。</li>


	<li>監査ログや運用ログの保管先としてすでに使われている。</li>
</ul>


<p class="wp-block-paragraph">こうした制約がある場合、いきなりBucket owner enforcedへ変更するのではなく、影響調査と段階的な移行が必要になります。</p>


<p class="wp-block-paragraph">今回も、根本的な方向性としてはBucket owner enforcedへの移行を検討すべき構成でした。</p>


<p class="wp-block-paragraph">ただし、既存環境では、すぐに設定変更できない事情がありました。</p>


<p class="wp-block-paragraph">そこで今回は、まず権限の使い方を整理する現実的な対策として、アカウントB側のIAMロールにスイッチして操作する方式を採用しました。</p>


<p class="wp-block-paragraph">いきなり理想形へ変更できないのであれば、まずは現在の権限設計のどこが曖昧だったのかを整理する必要があります。</p>


<p class="wp-block-paragraph">今回の改善前の考え方は、こうでした。</p>


<p class="wp-block-paragraph">「アカウントAに、アカウントBのS3バケットを操作する権限を与える」</p>


<p class="wp-block-paragraph">一見、正しそうに見えます。</p>


<p class="wp-block-paragraph">しかし、この考え方では、バケットに対する権限を中心に見ています。</p>


<p class="wp-block-paragraph">改善後は、考え方を変えました。</p>


<p class="wp-block-paragraph">「アカウントB側にIAMロールを作成し、アカウントAからそのロールにスイッチして、S3操作を行う」</p>


<p class="wp-block-paragraph">つまり、バケットが存在するアカウント側の権限設計に寄せました。</p>


<p class="wp-block-paragraph">これにより、アカウントAから直接アカウントBのS3を操作するのではなく、アカウントB側のロールとして操作する形にします。</p>


<p class="wp-block-paragraph">対策としては、次のいずれかを明確に決める必要があります。</p>


<ul id="703c9ebf-b962-4149-8a16-f5e665f6c77c" class="wp-block-list">
	<li>アカウントB側のIAMロールにスイッチして操作するのか。</li>


	<li>S3 Object Ownershipを見直して、バケット所有者に所有権を寄せるのか。</li>


	<li>サービス出力時の権限付与方式を見直すのか。</li>


	<li>既存オブジェクトについて、所有者やアクセス権の扱いを整理するのか。</li>


	<li>将来的にACL依存をなくす移行計画を立てるのか。</li>
</ul>


<p class="wp-block-paragraph">対策は、技術的な設定値だけで決めるものではありません。</p>


<ul id="a2a5286d-fc04-47bd-9ea6-73df85d5d132" class="wp-block-list">
	<li>運用で誰が取得するのか。</li>


	<li>障害時に誰が調査するのか。</li>


	<li>監査ログとして誰が参照するのか。</li>


	<li>保管期間中に別アカウントから読む必要があるのか。</li>


	<li>削除やライフサイクル管理は誰が行うのか。</li>
</ul>


<p class="wp-block-paragraph">ここまで含めて、対策を選ぶ必要があります。</p>


<h2 class="wp-block-heading"><span id="toc4">直接取りに行くのをやめ、バケット側のロールを使った</span></h2>


<p class="wp-block-paragraph">今回の対策では、アカウントB側にIAMロールを作成し、アカウントAからスイッチロールして操作する方式に変更しました。</p>


<p class="wp-block-paragraph">アカウントBのIAMロールとして操作することで、アカウントB側のアイデンティティでS3にアクセスする形になります。</p>


<p class="wp-block-paragraph">これにより、別アカウントから直接バケット内のオブジェクトを操作するのではなく、バケットを持つアカウント側の権限に寄せて操作できるようになります。</p>


<p class="wp-block-paragraph">改善前は、アカウントA側のIAMに対して、アカウントBのS3バケット操作を許可していました。</p>


<p class="wp-block-paragraph">しかし、これでは対象オブジェクトの所有者やサービス出力の扱いによって、取得できるものとできないものが発生しました。</p>


<p class="wp-block-paragraph">改善後は、バケットが存在するアカウントB側にS3操作用のIAMロールを用意しました。</p>


<p class="wp-block-paragraph">アカウントAのユーザーは、そのロールにスイッチします。</p>


<p class="wp-block-paragraph">そして、アカウントB側のロールとしてS3バケット内のオブジェクトを操作します。</p>


<p class="wp-block-paragraph">この形にすることで、少なくとも「アカウントAから直接、別アカウントのバケット内オブジェクトを操作する」という曖昧な構成を避けることができます。</p>


<p class="wp-block-paragraph">また、権限設計の説明もしやすくなります。</p>


<p class="wp-block-paragraph">「アカウントBのS3バケットを操作する場合は、アカウントBのIAMロールを使う」</p>


<p class="wp-block-paragraph">このように整理できるからです。</p>


<figure id="b4f88b01-19e5-4906-9e42-d4b8a01b4847" class="wp-block-image"><a href="https://assets.st-note.com/img/1780552096-HrDnYbeAp195q2ZPI0kdivhL.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780552096-HrDnYbeAp195q2ZPI0kdivhL.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">図3：改善前と改善後の構成比較</figcaption>
</figure>


<p class="wp-block-paragraph">運用手順としても、どのロールで作業するのかを明確にできます。</p>


<p class="wp-block-paragraph">これは地味ですが、現場ではかなり重要です。</p>


<p class="wp-block-paragraph">障害調査のときに、担当者ごとに違うIAMユーザーや違う権限で確認していると、現象が再現したりしなかったりします。</p>


<ul id="e1d01d87-75cd-4a5e-b52a-43a4896bc530" class="wp-block-list">
	<li>ある人は見える。</li>


	<li>別の人は見えない。</li>


	<li>CLIでは取れる。</li>


	<li>マネジメントコンソールでは取れない。</li>


	<li>アプリからは失敗する。</li>


	<li>運用端末からは成功する。</li>
</ul>


<p class="wp-block-paragraph">こうなると、原因調査が一気に複雑になります。</p>


<p class="wp-block-paragraph">権限設計は、セキュリティのためだけにあるのではありません。</p>


<p class="wp-block-paragraph">障害時に、同じ条件で確認できるようにするためにも必要です。</p>


<h2 class="wp-block-heading"><span id="toc5">テストで手動ファイルだけ見ていたら、この問題は見逃される</span></h2>


<p class="wp-block-paragraph">今回の話で一番重要なのは、対策そのものではありません。</p>


<p class="wp-block-paragraph">本来、テスト工程で何を確認すべきだったのか、という点です。</p>


<p class="wp-block-paragraph">もしテストで、ユーザーが手動アップロードしたファイルだけを使っていたら、この問題は見逃されます。</p>


<p class="wp-block-paragraph">なぜなら、そのファイルは取得できてしまうからです。</p>


<p class="wp-block-paragraph">「S3からファイル取得できました」<br />
「クロスアカウントアクセスできました」<br />
「権限設定は問題ありません」</p>


<p class="wp-block-paragraph">このようなテスト結果になってしまいます。</p>


<p class="wp-block-paragraph">しかし、本番運用で実際に取得したいのは、ユーザーが手動アップロードしたファイルとは限りません。</p>


<ul id="83ca67e3-d2d3-4d51-9944-80c81b8cbeec" class="wp-block-list">
	<li>AWSサービスが出力したログファイルです。</li>


	<li>運用バッチが出力したファイルです。</li>


	<li>監査用に自動生成されたファイルです。</li>


	<li>障害調査で必要になるファイルです。</li>
</ul>


<p class="wp-block-paragraph">つまり、テストデータの作り方が間違っていると、設計ミスを検知できません。</p>


<p class="wp-block-paragraph">今回であれば、少なくとも次の観点でテストする必要がありました。</p>


<ul id="8cf61c33-3f94-4c4e-a2d7-20d6bca99630" class="wp-block-list">
	<li>ユーザーがアップロードしたオブジェクトを取得できるか。</li>


	<li>AWSサービスが出力したオブジェクトを取得できるか。</li>


	<li>別アカウントから取得できるか。</li>


	<li>想定するIAMロールで取得できるか。</li>


	<li>運用担当者の作業手順で取得できるか。</li>


	<li>CLI、アプリ、運用ジョブなど、実際の利用経路で取得できるか。</li>


	<li>取得できない場合に、どのログやエラーで原因を追えるか。</li>
</ul>


<p class="wp-block-paragraph">ここまで確認して、初めて「運用で使える」と言えます。</p>


<p class="wp-block-paragraph">単体テストでS3の設定値を確認するだけでは足りません。</p>


<p class="wp-block-paragraph">結合テストでアカウント間のアクセスを確認するだけでも足りません。</p>


<p class="wp-block-paragraph">システムテストや運用テストでは、本番と同じようにAWSサービスが出力したオブジェクトを使い、実際の運用手順で取得できるかを確認する必要があります。</p>


<p class="wp-block-paragraph">ここを省略すると、テストでは成功したのに、本番運用で失敗します。</p>


<figure id="f5dc4278-d585-47d1-80be-ea7547c57614" class="wp-block-image"><a href="https://assets.st-note.com/img/1780551733-9RSLH47irZ5d3fxpmz8PnIac.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780551733-9RSLH47irZ5d3fxpmz8PnIac.png?width=1200" alt="画像" /></a>
<figcaption class="wp-element-caption">図4：設計とテスト観点の対応</figcaption>
</figure>


<h2 class="wp-block-heading"><span id="toc6">「同じバケットなら同じ扱い」という思い込みが危ない</span></h2>


<p class="wp-block-paragraph">今回の気づきは、S3の権限設計は「バケットにアクセスできるか」だけで終わらないということです。</p>


<p class="wp-block-paragraph">特にクロスアカウント構成では、次のような思い込みが危険です。</p>


<p class="wp-block-paragraph">S3バケットに権限を付ければ、中のオブジェクトも読める。<br />
同じバケットにあるオブジェクトなら、同じように操作できる。<br />
テスト用に手動で置いたファイルが取れれば、本番のログファイルも取れる。<br />
AWSサービスが出力したファイルも、ユーザーがアップロードしたファイルと同じ扱いになる。<br />
IAMポリシーだけ見れば原因が分かる。</p>


<p class="wp-block-paragraph">これらは、実務では危ない前提です。</p>


<p class="wp-block-paragraph">S3はシンプルに見えます。</p>


<p class="wp-block-paragraph">バケットを作る。<br />
ファイルを置く。<br />
権限を付ける。<br />
取得する。</p>


<p class="wp-block-paragraph">表面的にはそれだけに見えます。</p>


<p class="wp-block-paragraph">しかし、複数アカウント、AWSサービス出力、ログ保管、監査、運用ジョブが絡むと、一気に設計論点が増えます。</p>


<p class="wp-block-paragraph">だからこそ、詳細設計では「S3バケット名」「保存先プレフィックス」「IAMポリシー」だけを書いて終わりにしてはいけません。</p>


<p class="wp-block-paragraph">誰が作るのか。<br />
誰が所有するのか。<br />
誰が読むのか。<br />
誰が消すのか。<br />
誰が障害時に調べるのか。</p>


<p class="wp-block-paragraph">ここまで書かないと、運用で使える設計にはなりません。</p>


<h2 class="wp-block-heading"><span id="toc7">「取れました」で終わらせないためのチェックポイント</span></h2>


<p class="wp-block-paragraph">ここからは、同じ問題を防ぐための具体的なチェックリストです。</p>


<p class="wp-block-paragraph">まず、S3を使う設計では、少なくとも次の項目を確認します。</p>


<ul id="526b979a-0a80-4c3a-94ff-842e7c8e7a9c" class="wp-block-list">
	<li>バケット所有アカウント。</li>


	<li>オブジェクト作成主体。</li>


	<li>オブジェクト所有者。</li>


	<li>アクセスするアカウント。</li>


	<li>アクセスに使うIAMロール。</li>


	<li>AWSサービスが出力するオブジェクトの有無。</li>


	<li>クロスアカウントアクセスの有無。</li>


	<li>S3 Object Ownershipの設定。</li>


	<li>ACLを使うのか、使わないのか。</li>


	<li>運用時に参照・取得・削除する主体。</li>


	<li>将来的にBucket owner enforcedへ移行できるか。</li>
</ul>


<p class="wp-block-paragraph">次に、テスト工程では、テストデータの作り方を明確にします。</p>


<ul id="564820f3-20ea-42b8-a6ac-aee3968a0833" class="wp-block-list">
	<li>手動でアップロードしたファイルだけで試験しない。</li>


	<li>AWSサービスが実際に出力したファイルで試験する。</li>


	<li>本番運用で使うIAMロールで試験する。</li>


	<li>別アカウントからの取得を試験する。</li>


	<li>運用手順書どおりに取得できるか確認する。</li>


	<li>失敗時のエラー確認方法も試験する。</li>
</ul>


<p class="wp-block-paragraph">そして、レビュー時には次の質問を入れます。</p>


<ul id="7080233e-39d1-4318-9bde-91c15c00cbfe" class="wp-block-list">
	<li>「そのオブジェクトは誰が作るのか」</li>


	<li>「そのオブジェクトの所有者は誰になるのか」</li>


	<li>「本番で取得するファイルと、テストで使ったファイルは同じ条件か」</li>


	<li>「AWSサービスが出力したファイルでも確認したか」</li>


	<li>「運用担当者が使うロールで確認したか」</li>


	<li>「ACLに依存した設計が残っていないか」</li>


	<li>「Bucket owner enforcedにした場合の影響を確認したか」</li>
</ul>


<p class="wp-block-paragraph">この質問を入れるだけで、今回のような問題はかなり防ぎやすくなります。</p>


<h2 class="wp-block-heading"><span id="toc8">まとめ</span></h2>


<p class="wp-block-paragraph">今回の事象は、S3のクロスアカウントアクセスにおけるオブジェクト所有者の問題でした。</p>


<p class="wp-block-paragraph">ただし、本質はAWSの細かい仕様そのものではありません。</p>


<p class="wp-block-paragraph">本質は、次の一文です。</p>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>設計で決めていないことは、テストでも確認されない。</strong></p>
</blockquote>


<p class="wp-block-paragraph">S3バケットに権限を付ける。<br />
IAMポリシーを書く。<br />
ロールを作る。<br />
テストでファイルを取得する。</p>


<p class="wp-block-paragraph">これだけでは、まだ足りません。</p>


<p class="wp-block-paragraph">本番で実際に扱うオブジェクトは、誰が作るのか。<br />
そのオブジェクトは、誰の所有になるのか。<br />
どのアカウントから、どのロールで、どの手順で取得するのか。<br />
障害時に、誰が調査できるのか。</p>


<p class="wp-block-paragraph">ここまで設計して、初めて運用に耐える構成になります。</p>


<p class="wp-block-paragraph">クラウドサービスは便利です。</p>


<p class="wp-block-paragraph">しかし、サービスが自動で出力するものほど、利用者が手で作ったものと同じ前提で扱ってはいけません。</p>


<p class="wp-block-paragraph">「作成できた」<br />
「保存できた」<br />
「バケットに存在する」</p>


<p class="wp-block-paragraph">そこで安心してはいけません。</p>


<p class="wp-block-paragraph">本当に確認すべきなのは、その先です。</p>


<p class="wp-block-paragraph"><strong>必要な人が、必要なタイミングで、必要な権限で、そのオブジェクトを扱えるか。</strong></p>


<p class="wp-block-paragraph">そこまで見て、初めて設計とテストがつながります。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<p class="wp-block-paragraph"><strong>関連記事</strong></p>


<p class="wp-block-paragraph">今回の記事で扱った「設定したか」ではなく、「実運用で誰が、どの権限で、何を扱えるか」まで確認する考え方は、以下の記事でも整理しています。</p>
<p><a href="https://sys-univ.com/dev/detailed-design-overview/">【前編】詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>
<p>シリーズ全体は<a rel="noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/incident/s3-cross-account-object-owner/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>バックアップ設定の「5日保存」は、5営業日分とは限らない｜AWS Backupの保持期間から考える、詳細設計の落とし穴</title>
		<link>https://sys-univ.com/incident/awsbackup/</link>
					<comments>https://sys-univ.com/incident/awsbackup/#respond</comments>
		
		<dc:creator><![CDATA[ナギ]]></dc:creator>
		<pubDate>Thu, 06 Oct 2022 06:01:29 +0000</pubDate>
				<category><![CDATA[AWS]]></category>
		<category><![CDATA[トラブル]]></category>
		<guid isPermaLink="false">https://sys-univ.com/?p=1521</guid>

					<description><![CDATA[バックアップ要件には、ほぼ必ず保存期限の指定があります。 たとえば、こんな要件です。 バックアップデータを5日分保存すること 一見すると、単純な要件に見えます。 バックアップソフトの保持期間を5日に設定すればよい。 AW [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">バックアップ要件には、ほぼ必ず保存期限の指定があります。</p>


<p class="wp-block-paragraph">たとえば、こんな要件です。</p>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">バックアップデータを5日分保存すること</p>
</blockquote>


<p class="wp-block-paragraph">一見すると、単純な要件に見えます。<br />
<br />
バックアップソフトの保持期間を5日に設定すればよい。<br />
<br />
AWS Backupであれば、ライフサイクルの保持期間を5日にすればよい。そう考えたくなります。</p>


<p class="wp-block-paragraph">しかし、ここで確認すべきことがあります。</p>


<p class="wp-block-paragraph">この「5日」は、カレンダー上の5日なのか。<br />
それとも、業務日としての5日なのか。</p>


<p class="wp-block-paragraph">この確認を曖昧にしたまま設計すると、バックアップジョブは正常に動いているのに、実は業務要件を満たしていない、という状態になることがあります。</p>



  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-20" checked><label class="toc-title" for="toc-checkbox-20">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">「5日」と「5営業日」は違う</a></li><li><a href="#toc2" tabindex="0">土日や大型連休をまたぐと、要件未達になることがある</a></li><li><a href="#toc3" tabindex="0">バックアップ要件で確認すべきこと</a></li><li><a href="#toc4" tabindex="0">現実的な３つの対策</a></li><li><a href="#toc5" tabindex="0">これは詳細設計で見つけるべき論点である</a></li><li><a href="#toc6" tabindex="0">まとめ</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">「5日」と「5営業日」は違う</span></h2>


<p class="wp-block-paragraph">要件が次のようなものだったとします。</p>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">バックアップデータを5営業日分保存すること</p>
</blockquote>


<p class="wp-block-paragraph">この場合、単純に保持期間を5日に設定してよいとは限りません。</p>


<p class="wp-block-paragraph">なぜなら、多くのバックアップ製品やクラウドサービスの保持期間は、営業日ではなく、カレンダー上の日数ベースで管理されるからです。</p>


<p class="wp-block-paragraph">AWS Backupを例にすると、バックアップのライフサイクルでは、リカバリポイントを作成後、何日で削除するかを指定します。</p>


<p class="wp-block-paragraph"><strong>つまり、基本的には「作成後なん日」という考え方です。</strong></p>


<p class="wp-block-paragraph">土日祝日や会社独自の休日カレンダーを考慮して保持期間を調整する。</p>


<p class="wp-block-paragraph">こうした営業日ベースの世代管理を、標準の保持期間設定だけで実現できるとは限りません。</p>


<p class="wp-block-paragraph">AWS Backupではスケジュール設定により、取得する曜日や時間を制御することはできます。</p>


<p class="wp-block-paragraph">しかしこれはあくまで「いつバックアップを取得するか」の話です。「何営業日分のバックアップを保持するか」とは別の話です。</p>


<p class="wp-block-paragraph">ここを混同すると、設計ミスになります。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<h2 class="wp-block-heading"><span id="toc2">土日や大型連休をまたぐと、要件未達になることがある</span></h2>


<p class="wp-block-paragraph">たとえば、バックアップを毎日取得し、保持期間を5日に設定したとします。</p>


<p class="wp-block-paragraph">土日をまたぐと、保持されているバックアップの中に土日分が含まれます。</p>


<p class="wp-block-paragraph">その結果、業務日として見ると、5営業日分ではなく3営業日分程度しか残っていない、ということが起こり得ます。</p>


<figure id="bf956707-745a-4a17-95d8-c72339d6aa1f" class="wp-block-image"><a href="https://assets.st-note.com/img/1780535983-QecqAItEHwJM7RnNvXaux9zs.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780535983-QecqAItEHwJM7RnNvXaux9zs.png?width=1200" alt="画像" /></a></figure>


<p class="wp-block-paragraph">さらに、年末年始、ゴールデンウィーク、会社独自の休業日を挟む場合はもっと問題が大きくなります。</p>


<p class="wp-block-paragraph">5日間の連休がある場合、保持期間を5日にしていると、連休前に取得したバックアップが連休明け時点で削除対象になっている可能性があります。</p>


<p class="wp-block-paragraph">システム上は、保持期間5日で正しく動いている。バックアップジョブも正常終了している。リカバリポイントも存在している。</p>


<p class="wp-block-paragraph">それでも、業務要件としての「5営業日分保存」は満たせていない可能性があります。</p>


<p class="wp-block-paragraph">障害が起きているわけではありません。<br />
ジョブが失敗しているわけでもありません。製品の不具合でもありません。</p>


<p class="wp-block-paragraph">ただ、要件の解釈と製品仕様がずれている。その結果、設計として不足している状態になります。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<h2 class="wp-block-heading"><span id="toc3">バックアップ要件で確認すべきこと</span></h2>


<p class="wp-block-paragraph">バックアップ保存期限の要件が出てきたら、少なくとも次の点は確認する必要があります。</p>


<ul id="f2338537-7d72-4c65-b085-f7e33df2afe8" class="wp-block-list">
	<li>保存期限の「日」はカレンダー上の日数か、営業日か</li>


	<li>土日祝日、年末年始、大型連休をどう扱うか</li>


	<li>必要なのは「日数保持」なのか「世代保持」なのか</li>


	<li>復旧時に必要なのは、直近何営業日分なのか、特定時点なのか</li>


	<li>月次・年次・決算期など、長期保持が別途必要か</li>
</ul>


<p class="wp-block-paragraph">特に重要なのは、次の3つは同じ意味ではないということです。</p>


<ul id="aba13520-6be5-4d4d-b871-9421b4e8d31e" class="wp-block-list">
	<li>5日保持：期間の話</li>


	<li>5世代保持：バックアップ取得回数の話</li>


	<li>5営業日分保持：休日カレンダーを考慮した復旧可能時点の話</li>
</ul>


<p class="wp-block-paragraph">似ています。しかし、設計上は別物です。この違いを曖昧にしたまま詳細設計に入ると、後工程で問題になります。</p>


<p class="wp-block-paragraph">また、要件の言葉をそのまま受け取らず、製品仕様にぶつけるための問いに変換する習慣も重要です。</p>


<p class="wp-block-paragraph">たとえば、次のように考えます。</p>


<figure id="f71c43e9-1712-433c-9722-f6fc9c7a417a" class="wp-block-image"><a href="https://assets.st-note.com/img/1780041858-4wviIKacmsbjlQ9Uq582n3r1.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780041858-4wviIKacmsbjlQ9Uq582n3r1.png?width=1200" alt="画像" /></a></figure>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<h2 class="wp-block-heading"><span id="toc4">現実的な３つの対策</span></h2>


<p class="wp-block-paragraph">休日カレンダーを考慮した世代管理機能がない場合、現実的な対策は大きく3つです。</p>


<figure id="2d114355-fceb-4a83-aa1b-05b1fb65ab16" class="wp-block-image"><a href="https://assets.st-note.com/img/1780041978-lXrAuH5fZ0sqUgyVKaPSnhmI.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780041978-lXrAuH5fZ0sqUgyVKaPSnhmI.png?width=1200" alt="画像" /></a></figure>


<p class="wp-block-paragraph"><strong>1　保持期間を長めに設定する</strong></p>


<p class="wp-block-paragraph">5営業日分を確実に残したいのであれば、土日祝日や大型連休を考慮して、10日、14日など余裕を持った保持期間にする。</p>


<p class="wp-block-paragraph">これで要件を満たせるなら、構成はシンプルです。<br />
ただし、バックアップ容量が増え、ストレージコストも増えます。</p>


<p class="wp-block-paragraph"><strong>2　バックアップ取得はAWS Backupなどに任せ、世代管理をジョブ管理側で制御する</strong></p>


<p class="wp-block-paragraph">営業日、祝日、会社休日に柔軟に対応しやすい一方で、ジョブ設計、運用設計、監視、試験項目が増えます。</p>


<p class="wp-block-paragraph"><strong>3　AWS CLIやLambdaなどを使って、独自に削除・保持制御を実装する</strong></p>


<p class="wp-block-paragraph">追加のジョブ管理製品なしで柔軟に制御できますが、スクリプト開発、試験、保守、誤削除防止の設計が必要になります。</p>


<p class="wp-block-paragraph">特に削除処理を独自に作る場合、単に不要なバックアップを削除すればよいわけではありません。<br />
誤削除防止、削除ログ、削除失敗時の検知、復旧テストまで含めて設計する必要があります。</p>


<p class="wp-block-paragraph">要件・製品仕様・運用仕様のズレは、次のように整理すると分かりやすくなります。</p>


<figure id="ff5aba76-fa22-4fe9-8325-216d923334ea" class="wp-block-image"><a href="https://assets.st-note.com/img/1780042052-lOnsTxwzr6DXKbWIh4Vmq9AH.png?width=2000&amp;height=2000&amp;fit=bounds&amp;quality=85"><img decoding="async" src="https://assets.st-note.com/img/1780042052-lOnsTxwzr6DXKbWIh4Vmq9AH.png?width=1200" alt="画像" /></a></figure>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<h2 class="wp-block-heading"><span id="toc5">これは詳細設計で見つけるべき論点である</span></h2>


<p class="wp-block-paragraph">今回の話は、バックアップ設計だけの話ではありません。</p>


<p class="wp-block-paragraph">詳細設計で考えるべきことの典型例です。</p>


<p class="wp-block-paragraph">基本設計で「バックアップを5営業日分保存する」と書くことはできます。しかし詳細設計ではそこで終わりません。<br />
<br />
実際に採用する製品やサービスで、</p>


<p class="wp-block-paragraph">その要件をどう実現するのか。<br />
標準機能で実現できるのか。<br />
設定だけで足りるのか。<br />
運用で補う必要があるのか。<br />
スクリプトやジョブ管理が必要なのか。<br />
<br />
その場合、監視、ログ、異常時対応、試験はどうするのか。<br />
ここまで確認して、初めて設計として実装可能になります。</p>


<p class="wp-block-paragraph">詳細設計書にはパラメータを書く必要がありますが、パラメータだけでは弱いです。<br />
<br />
「保持期間：14日」とだけ書かれていても、なぜ14日なのかが分かりません。</p>


<p class="wp-block-paragraph">本来はこういう根拠が必要です。</p>


<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">要件は5営業日分の保持。標準機能では営業日単位の保持制御ができないため、土日祝日および大型連休を考慮し、保持期間を14日に設定する。これにより、通常の土日祝日を含む期間でも5営業日分のリカバリポイントを保持する。</p>
</blockquote>


<p class="wp-block-paragraph">こう書いておけば、レビューでも説明できます。<br />
運用担当にも伝わります。テスト担当も、何を確認すべきか分かります。</p>


<p class="wp-block-paragraph">後から気づくと、設計書の修正、スクリプト追加、試験項目の追加、運用手順書の修正、顧客説明、コスト再見積もりが発生します。<br />
一つひとつは小さく見えても、後工程では明確な手戻りです。</p>


<p class="wp-block-paragraph">詳細設計とは、パラメータシートを埋める作業ではありません。<br />
<br />
基本設計で決めた内容を、製品仕様、制約、運用条件に照らして、構築できる形、試せる形、運用できる形に落とし込む工程です。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<h2 class="wp-block-heading"><span id="toc6">まとめ</span></h2>


<p class="wp-block-paragraph">「5日保存」は、単純にバックアップソフトへ5日と設定すればよい、という話ではありません。</p>


<p class="wp-block-paragraph">その5日がカレンダー上の日数なのか、営業日なのか。土日祝日や大型連休をどう扱うのか。何世代必要なのか。どの時点に復旧できる必要があるのか。これを確認しないまま設計すると、バックアップジョブは正常でも、業務要件を満たせない可能性があります。</p>


<p class="wp-block-paragraph">バックアップは、取れていればよいわけではありません。必要な時点に、必要な期間分、確実に戻せること。そこまで確認して、初めてバックアップ要件を満たしていると言えます。</p>


<p class="wp-block-paragraph">こういうズレを構築前に見つけるのが、詳細設計の仕事です。</p>


<hr class="wp-block-separator has-alpha-channel-opacity" />

<p class="wp-block-paragraph">この考え方については、以下の記事でも整理しています。</p>


<p class="wp-block-paragraph"><a href="https://sys-univ.com/dev/detailed-design-part2-monitoring-security/" target="_blank">〖後編②〗詳細設計で決めること｜基本設計を「構築・テスト・運用できる形」に落とし込む工程</a></p>


<p class="wp-block-paragraph">シリーズ全体は<a rel="noopener" href="https://note.com/k_s7906/m/mc19593a012e2" target="_blank">「実務で使えるシステム開発方法論」マガジン</a>にまとめています。</p>

<p>&nbsp;</p>

<p class="wp-block-paragraph">&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sys-univ.com/incident/awsbackup/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
