
S3バージョニング自動修復システムから学ぶSOAサービス連携
はじめに
こんにちは。現在、AWS Certified SysOps Administrator – Associate(SOA)資格の学習に取り組んでいる八亀です。SOAの学習を進める中で、AWS Config、EventBridge、Systems Manager など多数のサービスが登場しますが、「どう連携させるのかイメージが湧かない…」という課題に直面しました。
そこで今回は、サービス間連携を理解するため、S3バケットの構成逸脱を自動で検知・修復する小規模なシステムを構築し、SOA試験頻出サービスの実践的な使い方を学んでいきます。
今回作るもの
本記事では、AWS CloudFormationで定義されたS3バケットの構成(バージョニング設定) が手動で変更された場合に、逸脱を検知→自動で修復処理を実行→処理結果をログ記録という一連の流れを自動化した「構成の自己修復システム」を構築します。
以下が本システムのアーキテクチャ図です
このシステムを通して、SOA試験でも頻出の以下のサービスを学ぶことができます:
- AWS CloudFormation
- AWS Config
- Amazon EventBridge
- AWS Systems Manager Automation
- Amazon CloudWatch Logs
やってみた
Step1 CloudFormation
本システムの対象となるリソース、S3バケットをCloudFormationで作成します。学習のため、S3バケット以外のリソース(AWS Config、EventBridge、SSM Automationなど)はマネジメントコンソールから作成していきます。
まず、CloudFormationテンプレートに使用する以下のYAMLファイルを準備します。ファイル名は self-healing-s3 など、わかりやすい名前で保存してください。
self-healing-s3.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: Learning - S3 Bucket for Self-Healing Practice
Parameters:
ForceUpdateTimestamp:
Type: String
Default: "2025-01-01-00:00:00"
Description: Force update parameter
Resources:
MonitoredS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub self-healing-demo-${AWS::AccountId}-${AWS::Region}
VersioningConfiguration:
Status: Enabled
Tags:
- Key: SelfHealingTarget
Value: "true"
- Key: LastUpdate
Value: !Ref ForceUpdateTimestamp
重要なポイント:
- VersioningConfiguration:S3バケットのバージョニングを有効化
- SelfHealingTarget タグ:Config Rule の監視対象を限定し、既存のS3バケットに影響を与えないようスコープを制御
テンプレートの準備ができたら、AWSマネジメントコンソールから「AWS CloudFormation」にアクセスし、スタックの作成→新しいリソースを使用をクリックします。
スタックの作成
「テンプレートの準備」で「テンプレートファイルをアップロード」を選択し、先ほど準備したテンプレートファイルをアップロードします。「次へ」を押します。
スタックの詳細を指定
スタック名を分かりやすい名前で入力します。今回は「yakame-self-healing-s3-stack」と付けています。パラメータはそのままで、「次へ」をクリックします。
スタックオプションの設定
自分のIAMユーザーにS3の作成・管理権限がある場合は、そのまま進めて問題ありません。権限不足の場合のみ適切なIAMロールを指定します。「次へ」をクリックします。
確認して作成
設定に問題がなければ「送信」をクリックし、以下を確認しましょう。
- CloudFormationコンソールでスタックステータスが CREATE_COMPLETE になっていること
- S3コンソールで新しいバケットが作成されていること
- バケットのプロパティでバージョニングが「有効」になっていること
- タグ「SelfHealingTarget=true」が付与されていること
Step2 AWS Config
次に、AWS Configのルールを作成します。
今回の目的は、S3バケットのバージョニング設定が無効化された場合に逸脱を検知することです。そのために、AWSが提供するマネージドルールである「s3-bucket-versioning-enabled」を使います。
AWSマネジメントコンソールから「AWS Config」にアクセスし、「ルール」タブを開きます。「ルールの追加」ボタンをクリックして、ルール名にs3-bucket-versioning-enabledを入力し検索します。該当のルールが表示されたら「追加」をクリックします。
ルールの設定
ルール名をわかりやすい名前に変更します。今回は、「yakame-s3-bucket-versioning-enabled」としています。
また、評価対象のリソースを絞り込むために「タグ」スコープを使用します。
CloudFormationでS3バケットに付与したタグと一致するように、キーを「SelfHealingTarget」、値を「true」に設定します。
この設定により、既存のバケットには影響を与えずに、今回作成したバケットのみを監視対象とすることができます。
「次へ」をクリックします。
確認と作成
確認画面で設定に問題がなければ「保存」をクリックします。
作成が完了したら、以下を確認します。
- ルールが作成されていること
- 評価対象のリソースがCloudFormationで作成した1つのS3バケットのみであり、検出コンプライアンスが「準拠」と表示されていること
Step3 IAMロール作成
AWS EventBridge と SSM Automation を連携させるため、適切な権限を持つIAMロールを事前に作成する必要があります。このロールは、EventBridge がSSM Automation を実行し、SSM が CloudFormation 更新や S3 操作、ログ出力を行うために使用されます。
具体的な操作手順はここでは省略しますが、以下の内容を満たすIAMロールを事前に作成しておきましょう:
IAMポリシー:SSMCloudFormationRemediationPolicy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudformation:UpdateStack",
"cloudformation:DescribeStacks"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutBucketVersioning",
"s3:PutBucketTagging",
"s3:GetBucketTagging",
"s3:GetBucketVersioning"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:StartAutomationExecution",
"ssm:GetAutomationExecution",
"ssm:DescribeAutomationExecutions"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "arn:aws:iam::xxxxxxxxxxxx:role/SSMExecutionRoleForRemediation"
}
]
}
注:iam:PassRoleの"Resource"に記載されているxxxxは自身のアカウントIDを入れてください。
IAMロールの信頼関係:SSMExecutionRoleForRemediation
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ssm.amazonaws.com",
"events.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
権限の説明:
- CloudFormation: スタック更新と状態確認
- CloudWatch Logs: 修復結果の記録とログ管理
- S3: バケットのバージョニング設定操作
- SSM: Automation実行状況の確認
Step4 AWS Systems Manager
次に、EventBridge から呼び出される修復処理を定義するカスタム SSM Automation ドキュメントを作成します。このドキュメントが、実際の修復ロジックを実行する中核部分となります。
理想的には CloudFormation の再適用だけで S3 バージョニングを Suspended
→ Enabled
に修復できるはずですが、実際にテストしてみると、CloudFormation ではバージョニングの状態変更が期待通りに動作しない場合があることが分かりました。
そこで今回は、以下のハイブリッドプロセスで自動修復を実現しています:
- まず CloudFormation 再適用による修復を試行
- 修復後にS3の実際の状態を確認
- まだ修復されていない場合は S3 API で直接修復
AWSマネジメントコンソールから「AWS Systems Manager」にアクセスし、左メニューの「ドキュメント」から、「ドキュメントの作成」→「オートメーション」を選択します。
左上からドキュメント名を任意の名前に変更します。今回は「Custom-UpdateCloudFormationStack」としています。
「コード」に、以下のYAML形式のコードを貼り付けます。
Custom-UpdateCloudFormationStack
schemaVersion: '0.3'
description: S3 Self-Healing with Auto-Created Logs (Minimal)
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
BucketName:
type: String
description: S3 bucket name to heal
StackName:
type: String
description: CloudFormation stack name
AutomationAssumeRole:
type: String
description: IAM role for execution
mainSteps:
- name: UpdateStack
action: aws:executeAwsApi
nextStep: WaitAndFix
isEnd: false
inputs:
Service: cloudformation
Api: UpdateStack
StackName: '{{ StackName }}'
UsePreviousTemplate: true
Parameters:
- ParameterKey: ForceUpdateTimestamp
ParameterValue: '{{ global:DATE_TIME }}'
- name: WaitAndFix
action: aws:sleep
nextStep: FixAndLog
isEnd: false
inputs:
Duration: PT30S
- name: FixAndLog
action: aws:executeScript
isEnd: true
inputs:
Runtime: python3.9
Handler: fix_and_log
Script: |
import boto3
import json
from datetime import datetime
def fix_and_log(events, context):
s3 = boto3.client('s3')
logs = boto3.client('logs')
bucket = events['BucketName']
log_group = '/aws/s3-self-healing/audit'
log_stream = f"fix-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
# ロググループ自動作成
try:
logs.create_log_group(logGroupName=log_group)
print(f"Created log group: {log_group}")
except logs.exceptions.ResourceAlreadyExistsException:
print("Log group already exists")
# ログストリーム作成
try:
logs.create_log_stream(logGroupName=log_group, logStreamName=log_stream)
except:
pass
# バージョニング確認
response = s3.get_bucket_versioning(Bucket=bucket)
status = response.get('Status', 'Unversioned')
# 修復処理
if status != 'Enabled':
s3.put_bucket_versioning(
Bucket=bucket,
VersioningConfiguration={'Status': 'Enabled'}
)
method = 'direct_api'
print("Fixed by direct API")
else:
method = 'cloudformation'
print("Fixed by CloudFormation")
# ログ出力
log_data = {
"timestamp": datetime.now().isoformat(),
"bucket": bucket,
"remediation_method": method,
"initial_status": status,
"final_status": "Enabled"
}
logs.put_log_events(
logGroupName=log_group,
logStreamName=log_stream,
logEvents=[{
'timestamp': int(datetime.now().timestamp() * 1000),
'message': json.dumps(log_data)
}]
)
print(f"Logged to: {log_group}/{log_stream}")
return {"method": method, "status": "success"}
InputPayload:
BucketName: '{{ BucketName }}'
StackName: '{{ StackName }}'
outputs:
- Name: Result
Selector: $.Payload
Type: StringMap
outputs:
- FixAndLog.Result
マネージドサービスのドキュメントとして用意されている「AWS-UpdateCloudFormationStack」ではスタックの更新しかできずS3 APIの適用ができない為、カスタムドキュメントを使用しています。
ドキュメントの作成には Claude Sonnet 4 を活用しています。
SSM Automation の処理概要:
- CloudFormation 更新
- 待機: CloudFormation 処理完了を待つ(30秒)
- ハイブリッド修復: バージョニング状態を確認し、必要に応じて S3 API で直接修復
- ログ記録: 修復結果を CloudWatch Logs に詳細記録
設定が完了したら「ランブックを作成」をクリックします。
Step5 AWS EventBridge
次に、AWS Configから発行される「非準拠イベント」を検知するために、EventBridgeのルールを作成します。このルールにより、構成の逸脱が発生した際に、自動的にSSM Automationが起動し、CloudFormationスタックの再適用を実行することができます。
AWSマネジメントコンソールから「Amazon EventBridge」にアクセスし、左メニューの「ルール」から「ルールの作成」をクリックします。
ルールの詳細を定義
ルール名と説明欄は任意のもので構いません。今回は以下のように設定しました:
- ルール名:yakame-s3-versioning-noncompliant-rule
- 説明:Rule for detecting non-compliance events from AWS Config rules
イベントパターンを構成
イベントパターンはカスタムパターンを使用し、以下の内容を入力します。
カスタムパターン(JSONエディタ)
{
"source": ["aws.config"],
"detail-type": ["Config Rules Compliance Change"],
"detail": {
"configRuleName": ["yakame-s3-bucket-versioning-enabled"],
"newEvaluationResult": {
"complianceType": ["NON_COMPLIANT"]
}
}
}
configRuleNameには自身で作成したConfigRule名を入れてください。
この設定により、作成したConfig Ruleが非準拠と評価した時のみ、イベントが発火します。
ターゲットを選択
ターゲットには、「Systems Managerオートメーション」を選択します。
ドキュメント名は作成したSSMドキュメントを指定します。
今回は「Custom-UpdateCloudFormationStack」を指定します。
入力パラメータは以下の通りです:
- S3バケット名(self-healing-demo-xxxxxxxxxxxx-ap-northeast-1)
- CloudFormation Stack名
- 作成済みのIAMロールのARN
- 実行ロールでは「既存ロールを使用」を選択し、作成したロールを適用しましょう。
タグの設定
タグは任意です。必要でなければ、何も入力せずにスキップして問題ありません。
ルールの作成
最後に「レビューと作成」画面で内容を確認し、「ルールの作成」をクリックします。
作成が完了すると、以下のようにルールが一覧に表示され、有効になっていることが確認できます。
確認してみた
実際にシステムを動作させて、自己修復の一連の流れを確認していきます。
バージョニングの停止
S3バケットのプロパティタブから、手動でバージョニングを「停止」に変更します
Configの確認
AWS Config が構成変更を検知し、コンプライアンス状態が「非準拠」に変わったことを確認します。
EventBridgeの確認
Config の非準拠イベントをトリガーとして、EventBridge ルールが発火したことを確認します。
※表示まで5分程度かかるため飛ばしても可
SSM Automationの確認
EventBridge により起動された SSM Automation の実行状況を確認します。各ステップの成功/失敗や実行時間を詳細に確認できます。
AWSマネジメントコンソールから「AWS Systems Manager」にアクセスし、左メニューの「自動化」から確認できます。
CloudFormationの確認
SSM Automation により CloudFormation スタックが更新されたことを確認します。
ステータスが「UPDATE_COMPLETE」になっていればOKです
CloudWatch logsの確認
修復処理の詳細な実行ログが CloudWatch Logs に記録されていることを確認します。
AWSマネジメントコンソールから「CloudWatch」にアクセスし、左メニューの「ロググループ」から確認できます。
やはり、バージョニングに関してはStackの再適用だけではEnabled状態にならず、direct_apiで修復したことが分かりますね…なぜだろう?
S3バージョンの修復確認
最後に、S3のバージョニング状態を見ていきます。
システムにより自動修復され、S3 バケットのバージョニングが「有効」に戻っていることを確認できました。
LastUpdateタグが更新されており、Stackの再適用も一部できていることも確認できます。
おわりに
本記事では、S3バージョニング自動修復システムの構築を通じて、SOA試験頻出サービスの実践的な連携方法を解説しました。
AWS Config による構成監視から始まり、EventBridge でのイベント駆動、SSM Automation による修復処理、そして CloudWatch Logs での結果記録まで、一連の自動化フローを掴んでいただけたのではないでしょうか。
SOA学習をさらに深めるには、今回使用した各サービスの他の機能も確認してみることをお勧めします。Systems Manager であれば Parameter Store や Session Manager、CloudWatch であればカスタムメトリクスやアラーム機能など、実際のコンソールで様々なメニューを触ってみることで、SOA試験で問われる幅広い知識を身につけることができます。
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。