<?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>RDS &#8211; エンジニア見習い</title>
	<atom:link href="https://otonan-syusyoku.work/archives/tag/rds/feed" rel="self" type="application/rss+xml" />
	<link>https://otonan-syusyoku.work</link>
	<description>三流プログラマー</description>
	<lastBuildDate>Thu, 12 Feb 2026 06:29:36 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://otonan-syusyoku.work/wp-content/uploads/2023/10/cropped-名称未設定のデザイン-16-32x32.png</url>
	<title>RDS &#8211; エンジニア見習い</title>
	<link>https://otonan-syusyoku.work</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>CDKで管理しているRDSを暗号化したい</title>
		<link>https://otonan-syusyoku.work/archives/2198</link>
					<comments>https://otonan-syusyoku.work/archives/2198#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Thu, 12 Feb 2026 06:29:36 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[生涯独学]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[CDK]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[RDS]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=2198</guid>

					<description><![CDATA[どうも、PHPerです。 先日、業務にて「既存のRDSのストレージを暗号化したい」という、シンプルかつ重たい要件が降ってきました。 これの何が困るかというと、皆様ご存知の通りRDSの仕様です。 RDSは作成後の暗号化ステ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">どうも、PHPerです。</p>



<p class="wp-block-paragraph">先日、業務にて<strong>「既存のRDSのストレージを暗号化したい」</strong>という、シンプルかつ重たい要件が降ってきました。</p>



<p class="wp-block-paragraph">これの何が困るかというと、皆様ご存知の通りRDSの仕様です。 RDSは<strong>作成後の暗号化ステータスの変更ができません</strong>。つまり、<strong>既存のRDSを暗号化するためには、「暗号化有効」設定で作り直す（再作成する）必要</strong>があります。 </p>



<p class="wp-block-paragraph"><a href="https://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automatically-remediate-unencrypted-amazon-rds-db-instances-and-clusters.html" target="_blank" rel="noreferrer noopener">参考: Amazon RDS DB インスタンスおよびクラスターの暗号化 &#8211; AWS Prescriptive Guidance</a></p>



<p class="wp-block-paragraph">さらに今回はインフラを <strong>AWS CDK</strong> で管理しています。<br> 単純にCDKのコードを書き換えてデプロイすると、CloudFormationの仕様により「リソースの置換」が発生し、予期せぬダウンタイムやデータ損失のリスクがあります。<br>また、よくある「スナップショットから復元して差し替え」という手法も、CDKのState管理との兼ね合いで今回は採用できませんでした。</p>



<p class="wp-block-paragraph">様々な制約がある中、「既存データを維持しつつ」「CDK管理のまま」暗号化リソースへ移行できたので、その手法を共有します。</p>



<h2 class="wp-block-heading">今回の要件と制約</h2>



<p class="wp-block-paragraph">今回のミッションにおける前提条件は以下の通りです。</p>



<ul class="wp-block-list">
<li><strong>既存RDSの暗号化</strong>（最重要）</li>



<li>既存データをそのまま移行できること</li>



<li>アプリ側の変更を避けるため、<strong>エンドポイント（またはDNS）の変更がないこと</strong></li>



<li><strong>ダウンタイムは許容</strong>（ALBでメンテナンス画面を挟む前提）</li>



<li>バッチ処理が稼働していない夜間帯での作業</li>



<li><strong>CDKコードの変更は最小限</strong>に留め、今後もCDKで管理し続けること</li>
</ul>



<h2 class="wp-block-heading">結論：CDKデプロイを3回行う</h2>



<p class="wp-block-paragraph">結論から言うと、<strong>「削除ポリシーを変更して既存RDSをCDK管理から切り離し、新規で暗号化RDSを作成する」</strong>という力技で解決しました。</p>



<p class="wp-block-paragraph">具体的には以下の3ステップでデプロイを行います。</p>



<ol start="1" class="wp-block-list">
<li><code>RemovalPolicy.RETAIN</code> を設定（既存保護）</li>



<li><code>instanceIdentifier</code> を変更（既存切り離し）</li>



<li><code>storageEncrypted: true</code> を指定（新規作成）</li>
</ol>



<h3 class="wp-block-heading">なぜこの手順が必要なのか？（ハマりポイント）</h3>



<p class="wp-block-paragraph">通常、CDKで管理されているリソースに対し、<code>instanceIdentifier</code>（物理ID）を固定したまま <code>storageEncrypted: true</code> に変更してデプロイしようとすると、以下のエラーが発生して失敗します。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>CloudFormation cannot update a stack when a custom-named resource requires replacing</strong></p>
</blockquote>



<p class="wp-block-paragraph">これは、「カスタム名（明示的な名前）がついているリソースを置換（削除＆作成）することはできない」というCloudFormationの安全装置です。これを回避するために、あえて識別子を変更して別リソースとして認識させる必要があります。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">手順詳細</h2>



<h3 class="wp-block-heading">1. 削除ポリシーの変更</h3>



<p class="wp-block-paragraph">まず、既存のRDSがCDKのスタック操作によって削除されないようにします。 これをやらないと、次の手順で「既存RDSの削除」が走ってしまい、データが消えます（超重要）。</p>



<p class="wp-block-paragraph">コード スニペット</p>



<pre class="wp-block-code"><code>new rds.DatabaseInstance(this, 'RdsInstance', {
  instanceIdentifier: 'my-prod-db', // 現在の識別子
  // ...
  removalPolicy: cdk.RemovalPolicy.RETAIN, // ここを追加！
});
</code></pre>



<p class="wp-block-paragraph">この状態で一度 <strong><code>cdk deploy</code></strong> します。 これで、このRDSはスタックから削除される際も、AWS上にはリソースが残るようになります。</p>



<h3 class="wp-block-heading">2. instanceIdentifier の変更</h3>



<p class="wp-block-paragraph">次に、既存のRDSをCDKの管理下から外す（Orphanにする）作業です。 CDK上の識別子を、既存のものとは別の名前に書き換えます。</p>



<p class="wp-block-paragraph">コード スニペット</p>



<pre class="wp-block-code"><code>new rds.DatabaseInstance(this, 'RdsInstance', {
  instanceIdentifier: 'my-prod-db-temp', // 3と被らない一時的な名前に変更
  // ...
  removalPolicy: cdk.RemovalPolicy.RETAIN,
});
</code></pre>



<p class="wp-block-paragraph">この状態で <strong><code>cdk deploy</code></strong> します。</p>



<p class="wp-block-paragraph"><strong>何が起きるか：</strong><br> CloudFormationは「<code>my-prod-db</code> を管理から外し、新しく <code>my-prod-db-temp</code> を作る」という挙動をします。 ステップ1で <code>RETAIN</code> を設定しているため、<strong>旧RDS（データ入り）は削除されずにそのまま残ります。</strong> <br>※この時点でアプリはまだ旧RDSを見ています。</p>



<h3 class="wp-block-heading">3. いよいよ暗号化RDSの構築</h3>



<p class="wp-block-paragraph">最後に、本命の「暗号化されたRDS」を作成します。</p>



<p class="wp-block-paragraph">コード スニペット</p>



<pre class="wp-block-code"><code>new rds.DatabaseInstance(this, 'RdsInstance', {
  instanceIdentifier: 'my-prod-db', // 元の名前に戻す（ここが変わるとエンドポイント変わるので注意）
  storageEncrypted: true,           // 暗号化をON
  removalPolicy: cdk.RemovalPolicy.RETAIN,
  // ...
});
</code></pre>



<p class="wp-block-paragraph">この状態で <strong><code>cdk deploy</code></strong> します。</p>



<p class="wp-block-paragraph"><strong>注意点：</strong><br>もし <code>instanceIdentifier</code> を手順1と同じ名前（<code>my-prod-db</code>）に戻したい場合、手順2の時点でAWS上に古い <code>my-prod-db</code> が残っているため、名前重複でエラーになる可能性があります。<br>その場合は、<strong>AWSマネジメントコンソールまたはCLIから、古いRDS（手順2で切り離されたもの）の識別子を手動で <code>my-prod-db-old</code> などにリネーム</strong> してからデプロイしてください。</p>



<p class="wp-block-paragraph">これで、暗号化された空っぽのRDSが立ち上がりました。</p>



<h2 class="wp-block-heading">データ移行</h2>



<p class="wp-block-paragraph">新旧2つのRDSが存在している状態になりました。</p>



<ul class="wp-block-list">
<li><strong>旧RDS</strong>
<ul class="wp-block-list">
<li>データあり</li>



<li>非暗号化</li>



<li>CDK管理外</li>
</ul>
</li>



<li><strong>新RDS</strong>
<ul class="wp-block-list">
<li>データなし</li>



<li>暗号化済み</li>



<li>CDK管理下</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">データ量がそれほど多くない（数GB〜数十GB程度）ため、今回はシンプルに <code>mysqldump</code> で移行を行いました。TB級の場合は AWS DMS (Database Migration Service) の利用を検討してください。</p>



<pre class="wp-block-code"><code># SSM Session Manager 等で踏み台サーバーに接続

# 1. 旧RDSからデータをエクスポート（パイプで圧縮して転送時間を短縮）
mysqldump -h &#91;旧RDSエンドポイント] -u &#91;ユーザー名] -p \
  --single-transaction --routines --triggers \
  --databases &#91;対象のスキーマ] \
  | gzip &gt; dump.sql.gz

# 2. 新RDSへインポート
zcat dump.sql.gz | mysqldump -h &#91;新RDSエンドポイント] -u &#91;ユーザー名] -p
</code></pre>



<p class="wp-block-paragraph">データの移行が完了したら、アプリケーションの接続先が新RDSに向いていることを確認し、メンテナンスを解除します。</p>



<h2 class="wp-block-heading">後片付け</h2>



<p class="wp-block-paragraph">無事稼働確認が取れたら、不要なリソースを削除してお財布を守りましょう。</p>



<ol start="1" class="wp-block-list">
<li><strong>手順2で立ち上がった一時的なRDS</strong>（CDKの管理からは外れているはずですが、念の為確認して削除）</li>



<li><strong>手順1以前から存在していた旧RDS</strong>（リネームした <code>my-prod-db-old</code> など）</li>
</ol>



<p class="wp-block-paragraph">スナップショットが取れていることを確認した上で、マネジメントコンソールから削除しました。</p>



<h2 class="wp-block-heading">(おまけ) 試したけどうまくいかなかったこと</h2>



<h3 class="wp-block-heading"><code>cdk import</code> での既存リソース取り込み</h3>



<p class="wp-block-paragraph">既存のリソースをリネームして、新しいスタックに取り込もうと <code>cdk import</code> を試みましたが、以下のようなメッセージが出てスキップされました。</p>



<pre class="wp-block-code"><code>TmpStack: no new resources compared to the currently deployed stack, skipping import.
</code></pre>



<p class="wp-block-paragraph">また、定義と実リソースのプロパティ（暗号化の有無）が食い違っているため、インポート自体が整合性エラーになる可能性が高いです。</p>



<h3 class="wp-block-heading"><code>DatabaseInstanceFromSnapshot</code> の利用</h3>



<p class="wp-block-paragraph">スナップショットから復元するCDKのクラスですが、これをメインの定義にしてしまうと、常に「スナップショットから作られた状態」が正となり、パラメータグループやバージョン更新などの運用時にドリフト（設定乖離）の管理が面倒になると判断し、今回は見送りました。</p>



<h2 class="wp-block-heading">まとめ</h2>



<p class="wp-block-paragraph">CDKで管理しているステートフルなリソース（RDSなど）の「再作成必須な変更」は非常に神経を使います。 <strong>「Retainで保護」→「Identifier変更で管理から切り離し」→「新規作成」</strong> というフローは、RDSに限らず他のリソースでも応用が効くテクニックなので、覚えておいて損はないはずです。</p>



<p class="wp-block-paragraph">なにはともあれですが、RDSは最初から暗号化しましょう。これだけは覚えて頂けると。。。</p>



<p class="wp-block-paragraph">同じ悩みを抱えるPHPer（およびAWS使い）の助けになれば幸いです！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/2198/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【CDKで構築】AWS ECS/RDSの監視・オートスケール基盤を自動構築しSlack通知する方法</title>
		<link>https://otonan-syusyoku.work/archives/2168</link>
					<comments>https://otonan-syusyoku.work/archives/2168#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 19 Nov 2025 04:44:12 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[業務]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[ECS]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[監視]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=2168</guid>

					<description><![CDATA[ECS FargateとRDSでPHPアプリケーションを運用する際、リソースの異常検知や負荷に応じたスケール管理は必須です。 しかし、これらの仕組みを個別に手動で設定するのは手間がかかります。 本記事では、AWS CDK [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><span class="">ECS FargateとRDSでPHPアプリケーションを運用する際、</span><span class="">リソースの異常検知や負荷に応じたスケール管理は必須です。<br />
</span><span class="">しかし、</span><span class="">これらの仕組みを個別に手動で設定するのは手間がかかります。</span></p>
<p><span class="">本記事では、</span><b class="">AWS CDK</b><span class="">（Cloud Development Kit）を用いて、</span><span class="">ECSとRDSの</span><b class="">監視アラーム</b><span class="">、</span><span class="">ECSの</span><b class="">オートスケーリング</b><span class="">、</span><span class="">そしてそのイベントを</span><b class="">Slack</b><span class="">に集約する通知基盤を<strong>IaC</strong>として一括で構築する方法を解説します。</span></p>
<p>&nbsp;</p>
<h2>監視・通知アーキテクチャの全体像</h2>
<p>採用するアーキテクチャは以下の通りです。</p>
<div class="table-block-component"></div>
<div>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr style="background-color: #5aabe8;">
<td style="width: 33.3333%;"><span style="color: #ffffff;">機能</span></td>
<td style="width: 33.3333%;"><span style="color: #ffffff;">AWSサービス</span></td>
<td style="width: 33.3333%;"><span style="color: #ffffff;">役割</span></td>
</tr>
<tr>
<td style="width: 33.3333%;"><b>監視</b></td>
<td style="width: 33.3333%;">CloudWatch</td>
<td style="width: 33.3333%;">メトリクスを収集・アラーム発報</td>
</tr>
<tr>
<td style="width: 33.3333%;"><b>自動応答</b></td>
<td style="width: 33.3333%;">Application Auto Scaling</td>
<td style="width: 33.3333%;">ECSの負荷に応じてタスク数を自動調整</td>
</tr>
<tr>
<td style="width: 33.3333%;"><b>通知ルーティング</b></td>
<td style="width: 33.3333%;">Amazon SNS</td>
<td style="width: 33.3333%;">アラームやスケーリングイベントを中継</td>
</tr>
<tr>
<td style="width: 33.3333%;"><b>通知先</b></td>
<td style="width: 33.3333%;">AWS Chatbot <span class="math-inline" data-math="\rightarrow">$\rightarrow$</span> Slack</td>
<td style="width: 33.3333%;">SNSからの通知を整形しSlackへ送信</td>
</tr>
</tbody>
</table>
</div>
<div></div>
<h2>事前準備: AWS ChatbotとSlackの連携</h2>
<p>CDKデプロイの前に、AWSアカウントとSlackを連携させるための<b>AWS Chatbotクライアント</b>を作成しておく必要があります。</p>
<ol start="1">
<li>AWS Chatbotコンソールで、<b>Slackワークスペース</b>と<b>チャンネル</b>を連携させます。</li>
<li>この設定により、通知先の<b>SlackチャンネルID</b>と<b>ワークスペースID</b>が取得できます。これらはCDKコード内で使用します。</li>
</ol>
<div class="sc_toggle_box">
<div class="sc_toggle_title">CDKでAWS Chatbot連携が完結しない理由</div>
<div class="sc_toggle_content">
<h3>1. 外部サービスとの認証（OAuthプロセス）が必要</h3>
<p>AWS Chatbotは、AWSアカウントと外部サービス（SlackやMicrosoft Teams）の連携を提供します。この連携は、Slack側でAWS Chatbotアプリをインストールし、AWSアカウントへのアクセスを許可するOAuth認証プロセスをユーザー（管理者）がブラウザ上で行う必要があります。</p>
<p>CDKはAWSアカウント内のリソースをプログラマブルにデプロイしますが、Slackワークスペース側の認証フローをプログラムで自動実行することは、セキュリティ上の理由からできません。</p>
<h3>2. AWS Chatbot Clientの事前設定が必要</h3>
<p>CDKのaws-chatbotモジュールで定義できるのは、連携が完了したワークスペースを参照し、その上でチャンネル設定（どのSNSトピックの通知をどのSlackチャンネルに送るか）を行う部分のみです。</p>
<p>CDKでnew chatbot.SlackChannelConfiguration(&#8230;)を作成する前に、通知先のSlackワークスペースID (slackWorkspaceId) を特定する必要があります。このワークスペースIDは、手動でChatbotコンソールからSlackとの連携を完了させた際に初めてAWS側に登録される情報です。</p>
</div>
</div>
<p>&nbsp;</p>
<h2>監視とオートスケール基盤の構築</h2>
<p>今回は、ECSサービスとRDSインスタンスが既に存在することを前提に、その監視・スケール設定を定義するCDKスタックを作成します。</p>
<h3>CDKスタックのセットアップ</h3>
<p>必要なCDKライブラリをインポートし、スタックを定義します。</p>
<p>&nbsp;</p>
<div>
<pre class="line-numbers"><code class="language-js">// lib/monitoring-stack.ts

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as sns from 'aws-cdk-lib/aws-sns';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as actions from 'aws-cdk-lib/aws-cloudwatch-actions';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import * as autoscaling from 'aws-cdk-lib/aws-applicationautoscaling';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as chatbot from 'aws-cdk-lib/aws-chatbot';

// 環境依存の定数を定義 (適宜置き換えてください)
const CLUSTER_NAME = 'your-ecs-cluster-name';
const SERVICE_NAME = 'your-ecs-service-name';
const RDS_IDENTIFIER = 'your-rds-instance-identifier';
const SLACK_CHANNEL_ID = 'C01234567'; // 取得したチャンネルID
const SLACK_WORKSPACE_ID = 'T01234567'; // 取得したワークスペースID

export class MonitoringStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 既存のECSサービスを参照
    const ecsService = ecs.FargateService.fromFargateServiceAttributes(this, 'ExistingEcsService', {
      serviceArn: cdk.Stack.of(this).formatArn({
        service: 'ecs',
        resource: 'service',
        resourceName: `${CLUSTER_NAME}/${SERVICE_NAME}`,
        sep: '/',
      }),
      cluster: ecs.Cluster.fromClusterAttributes(this, 'ExistingCluster', {
        clusterName: CLUSTER_NAME,
        vpc: ({} as any), // 参照のため空オブジェクト
        securityGroups: [],
      }),
    });
  }
}</code></pre>
<p>&nbsp;</p>
</div>
<h3>通知用SNSトピックとChatbotの設定</h3>
<p>アラームやイベントが通知を送るSNSトピックを作成し、それをAWS Chatbotに連携させます。</p>
<p><response-element class="" ng-version="0.0.0-PLACEHOLDER"><code-block _nghost-ng-c519592647="" class="ng-tns-c519592647-2197 ng-star-inserted"></code-block></response-element></p>
<div _ngcontent-ng-c519592647="" class="code-block ng-tns-c519592647-2197 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[[&quot;r_a2c461939f765a9a&quot;,&quot;c_86e1e1d55e25872e&quot;,null,&quot;rc_330331dc660dc0f2&quot;,null,null,&quot;ja&quot;,null,1,null,null,1,0]]">
<div _ngcontent-ng-c519592647="" class="code-block-decoration header-formatted gds-title-s ng-tns-c519592647-2197 ng-star-inserted"><span _ngcontent-ng-c519592647="" class="ng-tns-c519592647-2197"></span></div>
</div>
<pre class="line-numbers"><code class="language-js">// 1. 通知用SNSトピックの作成
    const alarmTopic = new sns.Topic(this, 'AlarmTopic', {
      displayName: 'System-Monitoring-Notifications',
    });

    // 2. AWS ChatbotとSNSトピックの連携 (Slackへのルーティング)
    new chatbot.SlackChannelConfiguration(this, 'ChatbotConfig', {
      slackChannelConfigurationName: 'EcsRdsMonitoring',
      slackWorkspaceId: SLACK_WORKSPACE_ID,
      slackChannelId: SLACK_CHANNEL_ID,
      notificationTopics: [alarmTopic], // このトピックへの通知がSlackに送られる
    });</code></pre>
<h3>ECSとRDSの監視アラーム設定</h3>
<p>主要なメトリクスに対してCloudWatchアラームを作成し、アクションとして上記SNSトピックを設定します。</p>
<pre class="line-numbers"><code class="language-js">// --- ECS Fargate アラーム ---
    // ECS CPU利用率が80%を超えた場合にアラーム
    const ecsCpuAlarm = new cloudwatch.Alarm(this, 'EcsCpuHighAlarm', {
      metric: cloudwatch.Metric.fromNamespaceAndName('AWS/ECS', 'CPUUtilization').with({
        dimensionsMap: { ClusterName: CLUSTER_NAME, ServiceName: SERVICE_NAME },
      }),
      threshold: 80, 
      evaluationPeriods: 2,
      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
      alarmDescription: 'ECS Service CPU utilization is too high.',
    });
    ecsCpuAlarm.addAlarmAction(new actions.SnsAction(alarmTopic));
    // ecsCpuAlarm.addOkAction(new actions.SnsAction(alarmTopic)); // 復旧時も通知したい場合は追加

    // --- RDS アラーム ---
    // RDS CPU利用率が70%を超えた場合にアラーム
    const rdsCpuAlarm = new cloudwatch.Alarm(this, 'RdsCpuHighAlarm', {
      metric: cloudwatch.Metric.fromNamespaceAndName('AWS/RDS', 'CPUUtilization').with({
        dimensionsMap: { DBInstanceIdentifier: RDS_IDENTIFIER },
      }),
      threshold: 70, 
      evaluationPeriods: 3,
      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
      alarmDescription: 'RDS CPU utilization is too high.',
    });
    rdsCpuAlarm.addAlarmAction(new actions.SnsAction(alarmTopic));</code></pre>
<h3>ECSサービスのオートスケーリング設定</h3>
<p>ECSサービスをCPU利用率$60%$を目標に自動スケーリングするように設定します。</p>
<p><response-element class="" ng-version="0.0.0-PLACEHOLDER"><code-block _nghost-ng-c519592647="" class="ng-tns-c519592647-2199 ng-star-inserted"></code-block></response-element></p>
<div _ngcontent-ng-c519592647="" class="code-block ng-tns-c519592647-2199 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[[&quot;r_a2c461939f765a9a&quot;,&quot;c_86e1e1d55e25872e&quot;,null,&quot;rc_330331dc660dc0f2&quot;,null,null,&quot;ja&quot;,null,1,null,null,1,0]]">
<div _ngcontent-ng-c519592647="" class="code-block-decoration header-formatted gds-title-s ng-tns-c519592647-2199 ng-star-inserted">
<pre class="line-numbers"><code class="language-js">// 3. ECSサービスのオートスケーリング設定
    // サービスのDesired Countをスケーリング対象にする
    const scalableTarget = autoscaling.ScalableTarget.forEcsService(this, 'EcsScalableTarget', {
      service: ecsService,
      minCapacity: 1, // 最小タスク数
      maxCapacity: 5, // 最大タスク数
    });

    // 目標CPU利用率 60% を維持するように調整するターゲット追跡スケーリングポリシー
    scalableTarget.scaleToTrackMetric('CpuScalingPolicy', {
      metric: ecsService.metricCpuUtilization(), 
      targetValue: 60,
      scaleOutCooldown: cdk.Duration.seconds(60),
      scaleInCooldown: cdk.Duration.seconds(300),
    });</code></pre>
</div>
<h3>オートスケールイベントのSlack通知設定</h3>
<p>スケーリング操作の成功イベントをEventBridgeで捕捉し、Slackに通知します。</p>
<p><response-element class="" ng-version="0.0.0-PLACEHOLDER"><code-block _nghost-ng-c519592647="" class="ng-tns-c519592647-2200 ng-star-inserted"></code-block></response-element></p>
<div _ngcontent-ng-c519592647="" class="code-block ng-tns-c519592647-2200 ng-animate-disabled ng-trigger ng-trigger-codeBlockRevealAnimation" jslog="223238;track:impression,attention;BardVeMetadataKey:[[&quot;r_a2c461939f765a9a&quot;,&quot;c_86e1e1d55e25872e&quot;,null,&quot;rc_330331dc660dc0f2&quot;,null,null,&quot;ja&quot;,null,1,null,null,1,0]]">
<div _ngcontent-ng-c519592647="" class="code-block-decoration header-formatted gds-title-s ng-tns-c519592647-2200 ng-star-inserted">
<pre class="line-numbers"><code class="language-js">// 4. オートスケールイベントを捕捉しSNSトピックへルーティング
    new events.Rule(this, 'AutoScalingNotificationRule', {
      description: 'Notify Slack on successful ECS Auto Scaling events.',
      eventPattern: {
        source: ['aws.application-autoscaling'],
        detailType: ['Application Auto Scaling Policy Execution'],
        detail: {
          // 成功したスケーリング操作のみを通知
          statusCode: ['Successful'], 
        },
      },
      // ターゲットは既存のSNSトピック
      targets: [new targets.SnsTopic(alarmTopic)],
    });</code></pre>
</div>
<h2>まとめ</h2>
<p>CDKを使うことで、<b>TypeScriptコード</b>で以下の堅牢な運用基盤を構築できました。</p>
<ol start="1">
<li>ECS/RDSの重要なメトリクス監視</li>
<li>CloudWatch AlarmsとChatbotによるSlackへの即時通知</li>
<li>ECSサービスの負荷に応じた自動スケーリング（スケールイン/アウト）</li>
<li>スケーリング操作完了時の通知</li>
</ol>
<p>インフラをコード化することで、再現性、バージョン管理、レビューが可能になり、システムの信頼性が大きく向上します。</p>
<div _ngcontent-ng-c519592647="" class="code-block-decoration header-formatted gds-title-s ng-tns-c519592647-2200 ng-star-inserted"></div>
</div>
</div>
<p>&nbsp;</p>
<div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/2168/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>【AWS】ワイだけのポケットリファレンス</title>
		<link>https://otonan-syusyoku.work/archives/1710</link>
					<comments>https://otonan-syusyoku.work/archives/1710#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Mon, 15 Apr 2024 00:21:45 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[業務]]></category>
		<category><![CDATA[生涯独学]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[RDS]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1710</guid>

					<description><![CDATA[未来の自分が幸せになることを願ってAWSの各作業をここに記します。 &#160; RDS RDSの自動起動対策 RDSは7日間の停止後に自動で起動してしまう仕様が存在する。 稼働していないシステムで使用しているRDSは止 [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>未来の自分が幸せになることを願ってAWSの各作業をここに記します。</p>
<p>&nbsp;</p>
<h2>RDS</h2>
<h3>RDSの自動起動対策</h3>
<p>RDSは<strong>7日間の停止後に自動で起動してしまう仕様</strong>が存在する。</p>
<p>稼働していないシステムで使用しているRDSは止めておきたいという要望が上がってきた。</p>
<p>7日間ごとに停止を手動で行うのは面倒くさすぎるし、ヒューマンエラーが発生する可能性がある。</p>
<p>そんな時に EventManeger にてRDSの自動停止を達成する事ができた。</p>
<p>やったこととしては、以下の通り。</p>
<ul>
<li>RDSの自動停止/起動 のスクリプトをLambda で定義</li>
<li>Lambdaスクリプトを EventManeger にて7日周期で実行するように定義
<ul>
<li><span class="sc_marker blue"><strong>起動 → 停止 の順番で実行するようにしないと、RDS本体の再起動とLambdaスクリプトの停止処理が同時刻に実行されてしまい、自動停止が出来ないよ</strong></span></li>
</ul>
</li>
</ul>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">参考記事</div>
<div class="sc_frame">
<p><a href="https://repost.aws/ja/knowledge-center/rds-stop-seven-days">https://repost.aws/ja/knowledge-center/rds-stop-seven-days</a></p>
</div>
</div>
<h3>Aurora</h3>
<p>クラスターとインスタンスという概念がある。</p>
<h3>Blue/Greenデプロイ</h3>
<p><strong>ダウンタイムを限りなく減らすデプロイ手法</strong>のこと。（2系統の環境を作成し、ユーザーが使用しているシステムに影響を少なくする）</p>
<p>当手法では、<strong>エンドポイントの切り替えを行う必要がない</strong>ため、プログラマー目線だとかなり作業が楽。（インフラ担当の作業範囲で収まるため）</p>
<p>&nbsp;</p>
<p>実際に経験したユースケースは以下の通り。</p>
<ul>
<li>RDS for MySQL の5系から8系へのアップグレード</li>
<li>インスタンスサイズの変更</li>
</ul>
<p>&nbsp;</p>
<p>上記対応を行った際の<strong>ダウンタイムは2 ~ 3分程度で切り替え</strong>が行われた。これはかなり凄いことだと思う。<br />
以前までの対応だと、以下の対応があると思われるが、当手法ではコンパネから手軽に実施することができる。</p>
<ul>
<li>本番環境とは別にMySQLサーバーを構築し、各種テストを実施後に現環境と旧環境の切り替え<br />
切り替え後はエンドポイントの切り替えを行う必要がある。</li>
<li>システムメンテナンス期間を設け、現環境の変更を行う。</li>
</ul>
<p>&nbsp;</p>
<p>Blue/Greenデプロイは素晴らしい。。。</p>
<h3>インスタンスタイプのサポート期日は守ろう</h3>
<p>とあるタスクにて、<strong>RDSの インスタンスタイプのアップグレード &amp; MySQLのバージョンアップ </strong>の作業があった。</p>
<p>その際の作業方法として、ダウンタイムを可能な限り削減するべくBlue/Greenデプロイを想定していたが、T2系インスタンスのサポートが終了していたため、Blue/Greenの作成が出来なかった。</p>
<p>本来であれば Blue/Green を作成後にGreen環境でインスタンスタイプのアップグレードとMySQLのバージョンアップを考えていたが、こうも上手くいかないとは思わなかった。</p>
<p>代替手段として、<span class="sc_marker blue"><strong>RDSのスナップショットからサポートされているインスタンスタイプで新規インスタンスを起動し、アプリケーションのエンドポイントを切り替える方法</strong></span>を考えたが、エンジニアが関与していないシステム（Redash等が上がっていたが、複数のサービスが連携していると報告が上がってきた）があるため、この手法は取れなかった。</p>
<p>&nbsp;</p>
<p>そのため、エンドユーザーにダウンタイムを許容してもらう形で現行環境のRDSをインプレースで対応することになった。</p>
<p>エンジニアのプライドとして許せなかったが、前任の構築者が既にいなかったことやI/Oの遅さからユーザーからのクレームがあり早急に対応する必要があったので仕方がない結果となった。<br />
（このタスクは他チームのインフラを面倒みることになっていたので余計に情報が絡み合ってめんどくさかった）</p>
<p>&nbsp;</p>
<p>最終的には深夜作業で対応することになり、なんとか目的を達成することが出来た。</p>
<p>&nbsp;</p>
<p>今後の教訓としては、インスタンスタイプのサポート期限は守ろう。</p>
<h3>パラメータグループはデフォルトを使うな</h3>
<p>時間がないからと言って、AWSが用意しているパラメータグループを使うな。</p>
<p>以下の問題が起きる</p>
<ul>
<li>Slow Query の出力がない</li>
<li>クエリの実行時間の制限がない</li>
</ul>
<p>問題の発生に気付けないのは大きな問題だ。</p>
<p>[getpost id=&#8221;1829&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>EC2</h2>
<h3>Amazon Linux2023 は remiリポジトリが使えないぞ</h3>
<p>Amazonlinux2023 はAWSさんが独自で管理しているOSらしいので、remi リポジトリがサポートされていない。</p>
<p>epel も使えない。</p>
<blockquote><p>Q: AL2023 は AL2 のような Amazon-Linux-Extras を搭載していますか?</p>
<p>A: いいえ。AL2023 には extras はありません。言語ランタイムなどの高レベルのソフトウェアパッケージの場合、四半期ごとのリリースを使用して、リポジトリで提供されるデフォルトパッケージに加えて、個別の名前空間化されたパッケージとしてメジャー/マイナー更新をパッケージに追加します。 例えば、Amazon Linux 2023 のデフォルトの Python バージョンは 3.8 である可能性がありますが、Python 3.9 (python39) が利用可能になると、別の名前空間化されたパッケージとして追加されます。これらの追加パッケージは、アップストリームリリース頻度とサポートモデルに厳密に従います。また、それらのサポートポリシーは、コンプライアンスとセキュリティのユースケースのために、パッケージマネージャーによってアクセスされることがあります。デフォルトパッケージは、AL2023 の存続期間を通じてサポート対象であり続けます。</p></blockquote>
<p>&nbsp;</p>
<p>サポート切れの PHP7.4 を使いたいという要件を達成するため、PHPの公式サイトからソースをビルドする事を考えたが、 php-fpm の導入及び関連する拡張機能の有効化の方法が分からなかったため、当手法は断念。</p>
<p>代わりに <strong>Rocky Linux</strong> を選択し、remi リポジトリからPHP7.4のインストールを行った。</p>
<p>（そもそもサポートの切れている言語Version 使うなよというお話でした</p>
<p>&nbsp;</p>
<h3>OSのメンテナンスは定期的に</h3>
<p><span class="sc_marker blue"><strong>10年近く稼働している一度もOSの再起動を行ったことのない EC2 のメンテナンス作業を行うタスクがあった。<br />
</strong></span>（何で誰も手つけて来なかったの？馬鹿じゃないの？</p>
<p>&nbsp;</p>
<p>構築した人は既におらず、インスタンスの中身がどうなっているかわからない状況だったため、作業前に以下の対応を行った。</p>
<ul>
<li>EBS バックアップ取得</li>
<li>AMI バックアップ取得</li>
<li>インスタンスの中で使用しているプログラムについての調査
<ul>
<li>各種言語のバージョン(拡張機能</li>
<li>cron</li>
<li>シェル</li>
</ul>
</li>
<li>VPCの構成</li>
</ul>
<p>&nbsp;</p>
<p>とりあえず結果からいうとデータの損失等が発生せず作業を終了することができた。</p>
<p>（やったこととしては、<strong>インスタンスサイズのアップグレード </strong>と <strong>ストレージのアップグレード</strong>。</p>
<p>&nbsp;</p>
<p>若者に伝えたいのが定期的にメンテナンスを行うことと運用がしやすいように設計書なり構成図なりを残すこと。<br />
（まじで何でも良いので、データとして残すことをオススメします。分かる人が見たら多少ズレのある設計書でもなんとなく予想がつくため。</p>
<h2>ALB</h2>
<h3>リスナールールのデフォルトルールは503返したほうが無難</h3>
<p>ALB は2つ以上のパブリックサブネットを設定する必要があります。</p>
<p>Route53 の Aレコード にALBのエイリアスを設定している場合は、ALBのパブリックIPが返ってくるようになる。</p>
<pre class="line-numbers"><code class="language-other">nslookup xxxx.com</code></pre>
<p>返却されるIPにアクセスするとALBで設定されているリスナールールに従った、ルーティングが行われる。</p>
<p>そのため、リスナールールのデフォルトルールが APPサーバーへのルーティングを行うターゲットグループを指定すると ALB のパブリックIP でアクセスすることができるようになってしまう。</p>
<p>これの怖いところが、EC2のセキュリティグループでは弾くことが不可能なため、意図しないルーティングが行われてしまう可能性があることです。</p>
<p>直近、 us-west-2 から大量のアクセスが来てしまい、アプリケーションサーバーが落ちるといった事業が発生してしまった。<br />
リスナールールの設定は適切に。。。</p>
<p>[getpost id=&#8221;2083&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1710/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>UbuntuにてMySQLコマンドだけ使いたい場合の備忘録</title>
		<link>https://otonan-syusyoku.work/archives/1446</link>
					<comments>https://otonan-syusyoku.work/archives/1446#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 17 Dec 2023 11:56:09 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1446</guid>

					<description><![CDATA[ワシはRDSに繋げたいだけなんじゃ！ 先日 RDS を構築した際に EC2 と接続ができなくて泣きたくなった。 原因はシンプルで EC2 に MySQL クライアントが存在しませんよという内容です。 クラウド先（RDS） [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>ワシはRDSに繋げたいだけなんじゃ！</h2>
<p>先日 RDS を構築した際に EC2 と接続ができなくて泣きたくなった。</p>
<p>原因はシンプルで <span class="sc_marker blue"><strong>EC2 に MySQL クライアントが存在しませんよ</strong></span>という内容です。</p>
<p>クラウド先（RDS）には MySQL が存在しているのに、わざわざ EC2 に MySQL 本体をインストールするのもなぁと思っていたのですが、ちょっと工夫するだけで EC2 から接続できるようにすることができることを知ったので共有ですぅぅぅ〜</p>
<p>[getpost id=&#8221;1426&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<p>[getpost id=&#8221;1448&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>いざ実践</h2>
<ul>
<li>とりあえずアプデ
<pre class="line-numbers"><code class="language-other">sudo apt update
</code></pre>
</li>
<li>mysql-client のパッケージを検索<br />
なんかいい感じのやつ出てくるよ</p>
<pre class="line-numbers"><code class="language-other">apt search mysql-clien</code></pre>
</li>
<li>最小を入れたい<br />
(お使いのバージョンに合わせたものを指定してね<br />
(client を入れれば MySQL コマンドが使えるよ</p>
<pre class="line-numbers"><code class="language-other">apt install mysql-client-core-8.x</code></pre>
</li>
<li>MySQL に接続
<pre class="line-numbers"><code class="language-other">mysql -h rds.amazonaws.com -P 3306 -u rds -p</code></pre>
</li>
</ul>
<h2>失敗時のエラー</h2>
<h3>権限不足</h3>
<pre class="line-numbers"><code class="language-other">Permission denied</code></pre>
<ul>
<li>Ubuntu で入ったから何となく行けてんのかと思いきや…</li>
<li>sudo しなさいよ</li>
</ul>
<h3>接続失敗</h3>
<pre class="line-numbers"><code class="language-other">ERROR 2003 (HY000): Can't connect to MySQL server on</code></pre>
<ul>
<li>RDS の設定漏れ</li>
<li>EC2 からの接続許可</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1446/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RDSでフェイルオーバー試してみたよ</title>
		<link>https://otonan-syusyoku.work/archives/1448</link>
					<comments>https://otonan-syusyoku.work/archives/1448#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Wed, 18 Oct 2023 13:52:33 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[サーバー]]></category>
		<category><![CDATA[フェイルオーバー]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1448</guid>

					<description><![CDATA[DBのあるべき姿の冗長構成 みなさんはDBの冗長構成を取っていますか？ 冗長構成とは簡単に言うと、 システムやサービスの障害が発生した場合に、自動的に別のバックアップシステムやリソースに切り替え、中断を最小限に抑える仕組 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>DBのあるべき姿の冗長構成</h2>
<p>みなさんはDBの冗長構成を取っていますか？</p>
<p>冗長構成とは簡単に言うと、<br />
<strong>システムやサービスの障害が発生した場合に、自動的に別のバックアップシステムやリソースに切り替え、中断を最小限に抑える仕組み</strong><br />
になります。</p>
<p>&nbsp;</p>
<p>冗長構成を取っていると <span class="sc_marker blue"><strong>DB に障害が発生した際でも被害を最小限に抑えてシステム運用することが可能</strong></span>となっています。</p>
<p>データに破損が起きると案件次第では損害賠償に発展したり、ユーザーへの悪影響が生じたりするなどビジネスチャンスを失ってしまいます。</p>
<p>可能な限り冗長構成を取るようにしましょう〜</p>
<h2>RDS for MySQL でフェイルオーバー試してみた</h2>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title"><span class="sc_frame_icon"><i class="fa fa-bolt" aria-hidden="true"><span>fa-bolt</span></i></span>注意</div>
<div class="sc_frame note">
<p>RDS はちゃんとお金かかります！<br />
自分で払える範囲のスペックで構築してください！<br />
後、検証が終わったら RDS は閉じてください！！！<br />
※RDS は停止してもお金がかかります。。。。(インスタンス料金, データベースストレージ料金, バックアップストレージ料金)</p>
</div>
</div>
<h3>事前準備</h3>
<p>EC2 と RDS の構築は済まして置いてください。</p>
<p>その上で1秒毎にDBへデータを登録する処理を PHP で書いていきます。</p>
<pre class="line-numbers"><code class="language-php">&lt;?php
ini_set('mysqlnd.net_read_timeout', 3);
$i = 0;
$end_time = time() + 600;
while (time() &lt; $end_time) {
  $result = hoge();
  sleep(1);
  echo $i . ":" . $result . "\n";
  $i++;
}

function hoge () {
  $result = 'connectionWaiting';
  try {
    $dbh = new PDO(
      'mysql:host=database-1.cizcjskkh2r7.ap-northeast-1.rds.amazonaws.com;dbname=testDB;charset=UTF8mb4',
      'admin',
      'password',
    );
    $dbh-&gt;setAttribute(PDO::ATTR_TIMEOUT, 3);
    $sql = "INSERT INTO testTable (created) VALUES ('" . date('Y-m-d h:i:s') . "')";
    if ($dbh-&gt;query($sql)) {
      $result = 'Succees';
    } else {
      $result = 'Faile';
    }
  } catch (PDOException $e) {
    $request = 'Die';
  }
  return $result;
}
?&gt;</code></pre>
<h3>いざ実行</h3>
<h4>PHPの実行</h4>
<pre class="line-numbers"><code class="language-php">php index.php</code></pre>
<h4>RDS の再起動</h4>
<p>RDS はフェイルオーバー での再起動ができるので、フェイルオーバーのオプションを付けて再起動を行います。</p>
<p>まずはデータ登録処理のPHPを実行します。<br />
フェイルオーバー実行前のデータ↓</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; select * from testTable;
+----+---------------------+
| id | created             |
+----+---------------------+
| 1 | 2023-10-18 10:39:07 |
| 2 | 2023-10-18 10:39:08 |
| 3 | 2023-10-18 10:39:09 |
| 4 | 2023-10-18 10:39:10 |
| 5 | 2023-10-18 10:39:11 |
| 6 | 2023-10-18 10:39:12 |
+----+---------------------+</code></pre>
<p>&nbsp;</p>
<p>フェイルオーバー実行後のデータ↓</p>
<pre class="line-numbers"><code class="language-other">mysql&gt; select * from testTable;
+----+---------------------+
| id | created |
+----+---------------------+
| 50 | 2023-10-18 10:39:57 |
| 51 | 2023-10-18 10:39:58 |
| 52 | 2023-10-18 10:39:59 |
| 53 | 2023-10-18 10:40:00 |
| 54 | 2023-10-18 10:40:01 |
| 55 | 2023-10-18 10:40:02 |
| 56 | 2023-10-18 10:40:03 |
| 57 | 2023-10-18 10:40:04 |        ← 再起動で止まったところと思われる箇所
| 58 | 2023-10-18 10:41:10 |        ← 再起動完了したところと思われる箇所
| 59 | 2023-10-18 10:41:11 |
| 60 | 2023-10-18 10:41:12 |
| 61 | 2023-10-18 10:41:14 |
| 62 | 2023-10-18 10:41:15 |
| 63 | 2023-10-18 10:41:16 |
| 64 | 2023-10-18 10:41:17 |
| 65 | 2023-10-18 10:41:18 |
| 66 | 2023-10-18 10:41:19 |
| 67 | 2023-10-18 10:41:20 |
| 68 | 2023-10-18 10:41:21 |
| 69 | 2023-10-18 10:41:22 |
+----+---------------------+</code></pre>
<h3>わかったこと</h3>
<ul>
<li>データは途切れるが、DB の復旧とともにデータ登録が可能となる
<ul>
<li>被害が大きくなりにくい</li>
<li>エンドポイントが変更されないので、プログラム側で特別な処理は不要（超嬉しい）</li>
</ul>
</li>
<li>難しい設定は不要
<ul>
<li>天下の Oracle 様が解説している高可用性構成の作り方<br />
<a href="https://www.oracle.com/jp/a/tech/docs/technical-resources/120127-mysql-ha.pdf">https://www.oracle.com/jp/a/tech/docs/technical-resources/120127-mysql-ha.pdf</a><br />
<a href="https://downloads.mysql.com/presentations/01_201311_MySQL_JP_Tech-Tour.pdf">https://downloads.mysql.com/presentations/01_201311_MySQL_JP_Tech-Tour.pdf</a></li>
</ul>
</li>
</ul>
<h3>わかっていないこと</h3>
<ul>
<li>大量のデータになった場合の復旧時間
<ul>
<li>今回の検証でもすぐに終わるときもあれば、３分以上かかる場合もあった</li>
</ul>
</li>
<li>PHP 側に `ini_set(‘mysqlnd.net_read_timeout’, 3)` を入れないと再起動が完了しても処理が継続しない
<ul>
<li>RDS 側でデッドロックが走っている？</li>
<li>接続先を探している？</li>
<li>RDS 側に設定が必要？</li>
<li>とりあえずプログラムでちょっとした工夫は必要そう</li>
</ul>
</li>
</ul>
<h2>まとめ</h2>
<p>今回の検証で RDS を使用して冗長性を確保することができたのではないかなぁという所感です〜</p>
<p>実際に検証を通して冗長性のある構成とはこんな感じなんだなぁと言うのがしれたのはかなり大きいです。笑</p>
<p>&nbsp;</p>
<p>実際、 DB を使わないシステムは限りなく少ないので DB が死んでも大丈夫と言える構成を取ることでビジネスチャンスを失わないというのはかなり大切だと考えています。</p>
<p>引き続き検証を続けていく必要がありそうです〜</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1448/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>僕が考えるRDSを激推する理由</title>
		<link>https://otonan-syusyoku.work/archives/1426</link>
					<comments>https://otonan-syusyoku.work/archives/1426#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Thu, 21 Sep 2023 14:42:53 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[業務]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[RDS]]></category>
		<category><![CDATA[フェイルオーバー]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1426</guid>

					<description><![CDATA[僕が考えるRDS を激推する理由 バックアップが楽ちん RDS を推したい理由の上位にくるのがバックアップの手軽さです。 AWS の公式にも記載がある通り、バックアップを自動で取ってくれます。 過去に クラウドサーバー  [&#8230;]]]></description>
										<content:encoded><![CDATA[<h2>僕が考えるRDS を激推する理由</h2>
<h3>バックアップが楽ちん</h3>
<p>RDS を推したい理由の上位にくるのが<strong>バックアップの手軽さ</strong>です。</p>
<p>AWS の公式にも記載がある通り、バックアップを自動で取ってくれます。</p>
<p>過去に クラウドサーバー 上にインストールした MySQL のバックアップ手法として、<strong>cron にて AWS SDK for PHP を用いて S3にダンプファイルを保管</strong>する手法を取っていた自分からすると RDS のバックアップはかなり楽ちんです。<br />
だって、以下の設定が不要になりますからね。笑</p>
<ol>
<li>AWS SDK for PHP のインストール</li>
<li>cron にて日次の実行処理を記述</li>
<li>S3 に送信処理を記述</li>
</ol>
<blockquote><p>デフォルトで有効になっている Amazon RDS の自動バックアップ機能により、データベースとトランザクションログがバックアップされます。Amazon RDS では DB インスタンスのストレージボリュームのスナップショットを自動的に作成し、個々のデータベースだけではなく、その DB インスタンス全体をバックアップします。</p>
<p>このバックアップは、バックアップウィンドウと呼ばれるユーザーが設定可能な 30 分間隔の時間に 1 日 1 回行われます。自動バックアップは、お客様が設定した日数の間、保持されます (バックアップ保持期間と呼ばれます)。自動バックアップの保持期間は、最大 35 日間まで設定できます。</p>
<p><cite class="blockquote_ref"> <a href="https://aws.amazon.com/jp/rds/features/backup/#%E8%87%AA%E5%8B%95%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97" target="_blank" rel="noopener noreferrer">Amazon RDS のバックアップと復元</a> </cite></p></blockquote>
<p>&nbsp;</p>
<p>また、 RDS には自動バックアップに加えてポイントインタイムリカバリという機能があり、特定の時点に戻すことができます。（5分毎にデータベースの変更ログのアーカイブが自動で実行されます）</p>
<p>これは、データの損失を最小限に抑えることのできる機能となっており、ポカしやすい人には必需品と言えるほどの機能となっています。</p>
<p>先程申し上げた日次のバックアップだけでは不足しているバックアップ分を補填しているので、個人的にはすごく好きです。</p>
<blockquote><p>DB インスタンスを特定の時点に復元し、新しい DB インスタンスを作成できます。</p>
<p><cite class="blockquote_ref"> <a href="https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_PIT.html" target="_blank" rel="noopener noreferrer">DB インスタンスを特定の時点に復元し、新しい DB インスタンスを作成できます。</a> </cite></p></blockquote>
<h3>死活監視が楽ちん</h3>
<p>RDS はデフォルトでメトリクスデータを1分間隔で CloudWatch に送信してくれます。<br />
（CloudWatch はメトリクスの収集、アラームの設定、ログの収集と監視などを対応してくれるサービスです）</p>
<p>&nbsp;</p>
<p>これも自分ごとではありますが、死活監視をするために以下のようなインフラを構築しました。</p>
<table style="border-collapse: collapse; width: 100%; height: 519px;">
<tbody>
<tr style="height: 45px;">
<td style="width: 50%; text-align: center; height: 45px;">イメージ</td>
<td style="width: 50%; text-align: center; height: 45px;">設定手順</td>
</tr>
<tr style="height: 474px;">
<td style="width: 50%; height: 474px;"><img fetchpriority="high" decoding="async" src="https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー.png" alt="監視構成" width="1000" height="500" class="aligncenter size-full wp-image-1443" srcset="https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー.png 1000w, https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー-300x150.png 300w, https://otonan-syusyoku.work/wp-content/uploads/2023/09/アプリケーションを監視するサーバーを監視するサーバー-768x384.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></td>
<td style="width: 50%; height: 474px;">
<ol>
<li>アプリケーションサーバー構築</li>
<li>アプリケーションサーバーを監視するサーバー（監視サーバー A）を構築
<ol>
<li>Zabbix をインストール</li>
<li>アプリケーションサーバーに 監視サーバーA のエージェントをインストール</li>
</ol>
</li>
<li>監視サーバーA にて監視設定</li>
<li>監視サーバーAを監視する監視サーバーBを構築
<ol>
<li>Zabbix をインストール</li>
<li>監視サーバーAに監視サーバーBのエージェントをインストール</li>
</ol>
</li>
<li>監視サーバーBにて監視設定</li>
</ol>
</td>
</tr>
</tbody>
</table>
<p>[getpost id=&#8221;1243&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;][getpost id=&#8221;1220&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<p>&nbsp;</p>
<p>手順書いてみたんですけど、すっげー面倒くさいですね。。。</p>
<p>その反面、 RDS では上記のような面倒くさい事をしなくても死活監視が簡単にできてしまうんです。</p>
<p>下記のあたりを見てれば DBが生きているかどうかを判別することができるので、すごく楽です。</p>
<ul>
<li>データベースの稼働状況</li>
<li>CPU使用率</li>
<li>メモリ使用率</li>
<li>ディスクストレージ</li>
<li>データベースのクエリおよびスロークエリ</li>
</ul>
<p>これらに対して閾値を設定して異常状態を感知できるようにすれば、僕が構築したよく分からない事はしなくても済むなんて素敵すぎる！！！！</p>
<h3>フェイルオーバーが楽ちん</h3>
<p>フェイルオーバー の構成を取っていると何らかの障害が起きた際に被害を最小限に止めることができます。</p>
<p>実際に手動で組み込んだことはないのですが、天下の Oracle 様の解説記事を読んでみるとごちゃごちゃと設定が必要そうで、適切な冗長構成を取るのが難しそうな印象を受けました。</p>
<p>&nbsp;</p>
<p>対して RDS は以下の条件を満たせば、冗長構成を取ることが可能となっています。</p>
<ul>
<li>マルチアベイラビリティーゾーン</li>
<li>ホットスタンバイオプションの有効化</li>
</ul>
<p>実際の手法を確認したい方はこちらの記事をご確認ください。</p>
<p>[getpost id=&#8221;1448&#8243; cat_name=&#8221;1&#8243; date=&#8221;0&#8243;]</p>
<h2>まとめ</h2>
<p>単純なDBを構築したい場合、<strong>RDS を使うことで楽に安全に構築することができます</strong>。</p>
<p>過去の自分に戒めを込めて、 RDS 使うと幸せになれることを胸張って伝えていきたいです。笑</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1426/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
