目次

AWS Certified DevOps Engineer – Professional (DOP-C02) 完全学習ガイド

試験概要

項目 内容
試験コード DOP-C02
正式名称 AWS Certified DevOps Engineer – Professional
難易度 ★★★★★ (Professional)
問題数 75問
試験時間 180分
合格スコア 750/1000
有効期限 3年
受験料 $300 USD
前提推奨 DVA-C02またはSOA-C02取得済み + 実務経験2年以上

特徴

DevOpsプラクティスをAWSで実装する能力を問う。
CI/CDパイプライン・IaC・自動化・障害対応・セキュリティ自動化がコアテーマ。


ドメイン別出題割合

ドメイン 出題割合 重要度
Domain 1: SDLC自動化 22% ★★★★★
Domain 2: 構成管理とIaC 17% ★★★★★
Domain 3: 弾力性のあるクラウドソリューション 15% ★★★★
Domain 4: モニタリングとログ 15% ★★★★
Domain 5: インシデントとイベントレスポンス 14% ★★★★
Domain 6: セキュリティとコンプライアンス 17% ★★★★★

Domain 1: SDLC自動化(22%)

1-1. CI/CDパイプラインの高度設計

マルチステージパイプライン(本番相当の設計):

┌─────────────────────────────────────────────────────────────────┐
│                  CodePipeline                                   │
│                                                                 │
│  [Source]      [Build]         [Test]          [Deploy]         │
│  CodeCommit    CodeBuild       CodeBuild       CodeDeploy       │
│  GitHub        ・ビルド         ・ユニットテスト   ・Staging環境     │
│  S3            ・Lint           ・統合テスト      ・承認ゲート       │
│                ・脆弱性スキャン   ・E2Eテスト       ・Blue/Green     │
│                ・イメージプッシュ  ・負荷テスト      ・Prod展開        │
│                                                                 │
│  [Artifacts: S3]   [Test Reports: S3]   [Deploy History]       │
└─────────────────────────────────────────────────────────────────┘

CodeBuild 高度な設定:

# buildspec.yml(本番想定の完全版)
version: 0.2

env:
  variables:
    AWS_DEFAULT_REGION: ap-northeast-1
    ECR_REPO_NAME: my-app
  parameter-store:
    SONAR_TOKEN: /prod/sonar/token
  secrets-manager:
    GITHUB_TOKEN: prod/github-token:token

phases:
  install:
    runtime-versions:
      python: 3.11
    commands:
      - pip install pytest pytest-cov bandit safety

  pre_build:
    commands:
      # セキュリティスキャン
      - bandit -r src/ -f json -o bandit-report.json || true
      - safety check --json > safety-report.json || true
      # Dockerログイン
      - aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_REGISTRY

  build:
    commands:
      # テスト実行
      - pytest tests/ --cov=src --cov-report=xml:coverage.xml -v
      # ビルド
      - docker build -t $ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION .
      - docker push $ECR_REGISTRY/$ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION

  post_build:
    commands:
      # イメージ定義ファイル生成(ECS用)
      - printf '[{"name":"app","imageUri":"%s"}]' $ECR_REGISTRY/$ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION > imagedefinitions.json

reports:
  pytest-reports:
    files:
      - coverage.xml
    file-format: COBERTURAXML

  security-reports:
    files:
      - bandit-report.json

artifacts:
  files:
    - imagedefinitions.json
    - appspec.yml
    - taskdef.json

cache:
  paths:
    - /root/.cache/pip/**/*
    - /root/.docker/cache/**/*

1-2. デプロイ戦略の深掘り

Canary デプロイの詳細:

ECSでのCanary(CodeDeployによる):
  Linear10PercentEvery1Minute:
    → 1分ごとに10%ずつ新バージョンへシフト
    → 10分で100%(計画的な段階移行)
  
  Canary10Percent5Minutes:
    → 最初5分間は10%、問題なければ残り90%を一度に
    → 高速だが5分間だけの監視

  自動ロールバックのトリガー:
    → CloudWatch Alarmが発火
    → デプロイ中のエラー率上昇
    → P99レイテンシが閾値超過

Route 53 加重ルーティングによるCanary:
  Route 53 レコード:
    myapp.example.com
      → v1 ALB (重み: 90)
      → v2 ALB (重み: 10)
  
  段階的に重みを変更:
    週1: v1=90, v2=10
    週2: v1=70, v2=30
    週3: v1=50, v2=50 ← 問題なければ加速
    週4: v1=0, v2=100

Lambda の Canary デプロイ(エイリアス使用):
  lambda:updateAlias --routing-config AdditionalVersionWeights={"version2": 0.1}
  → 10%のリクエストをversion2へルーティング
  → CloudWatch Alarmでエラー率監視 → 自動ロールバック

Domain 2: 構成管理とIaC(17%)

2-1. CloudFormation 高度な機能

CloudFormation StackSets(マルチアカウント展開):

# StackSetの定義(管理アカウントから実行)
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudTrail設定をOrganizations全体に展開'

Resources:
  CloudTrailBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'cloudtrail-${AWS::AccountId}-${AWS::Region}'
      
  CloudTrailConfig:
    Type: AWS::CloudTrail::Trail
    Properties:
      IsLogging: true
      S3BucketName: !Ref CloudTrailBucket
      IncludeGlobalServiceEvents: true
      IsMultiRegionTrail: true
      EnableLogFileValidation: true
# StackSet作成(Organizations全体に展開)
aws cloudformation create-stack-set \
  --stack-set-name cloudtrail-all-accounts \
  --template-body file://cloudtrail.yml \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false \
  --permission-model SERVICE_MANAGED

# 特定OUへの展開
aws cloudformation create-stack-instances \
  --stack-set-name cloudtrail-all-accounts \
  --deployment-targets OrganizationalUnitIds=ou-xxxx \
  --regions ap-northeast-1 us-east-1 eu-west-1 \
  --operation-preferences MaxConcurrentPercentage=25,FailureTolerancePercentage=10

CloudFormation Custom Resources:

# Lambda関数(CFnカスタムリソースのハンドラー)
import json
import urllib3
import boto3

http = urllib3.PoolManager()

def handler(event, context):
    request_type = event['RequestType']
    physical_id = event.get('PhysicalResourceId', 'custom-resource')
    
    try:
        if request_type == 'Create':
            result = create_resource(event)
            physical_id = result['ResourceId']
        elif request_type == 'Update':
            result = update_resource(event)
        elif request_type == 'Delete':
            result = delete_resource(event)
        
        send_response(event, context, 'SUCCESS', 
                      {'Result': 'OK'}, physical_id)
    except Exception as e:
        send_response(event, context, 'FAILED',
                      {'Error': str(e)}, physical_id)

def send_response(event, context, status, data, physical_id):
    response_body = json.dumps({
        'Status': status,
        'Reason': f'See CloudWatch logs: {context.log_stream_name}',
        'PhysicalResourceId': physical_id,
        'StackId': event['StackId'],
        'RequestId': event['RequestId'],
        'LogicalResourceId': event['LogicalResourceId'],
        'Data': data
    })
    http.request('PUT', event['ResponseURL'],
                 body=response_body.encode('utf-8'),
                 headers={'Content-Type': ''})

2-2. AWS CDK 実践

CDK パターンの実装:

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as codedeploy from 'aws-cdk-lib/aws-codedeploy';
import { Construct } from 'constructs';

export class ApiStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    // DynamoDB テーブル
    const table = new dynamodb.Table(this, 'OrdersTable', {
      partitionKey: { name: 'PK', type: dynamodb.AttributeType.STRING },
      sortKey: { name: 'SK', type: dynamodb.AttributeType.STRING },
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      pointInTimeRecovery: true,
      encryption: dynamodb.TableEncryption.AWS_MANAGED,
    });

    // Lambda 関数
    const apiFunction = new lambda.Function(this, 'ApiFunction', {
      runtime: lambda.Runtime.PYTHON_3_11,
      handler: 'app.handler',
      code: lambda.Code.fromAsset('src'),
      environment: { TABLE_NAME: table.tableName },
      tracing: lambda.Tracing.ACTIVE,  // X-Ray
      // Canaryデプロイの設定
      currentVersionOptions: {
        removalPolicy: cdk.RemovalPolicy.RETAIN,
      },
    });

    // Canaryデプロイ
    const alias = new lambda.Alias(this, 'LiveAlias', {
      aliasName: 'live',
      version: apiFunction.currentVersion,
    });

    new codedeploy.LambdaDeploymentGroup(this, 'DeploymentGroup', {
      alias,
      deploymentConfig: codedeploy.LambdaDeploymentConfig.CANARY_10PERCENT_5MINUTES,
      alarms: [/* CloudWatch Alarms */],
    });

    table.grantReadWriteData(apiFunction);
  }
}

Domain 3: 弾力性のあるクラウドソリューション(15%)

3-1. サーキットブレーカーパターン

# Lambda + DynamoDBで実装するサーキットブレーカー
import boto3
import time
from enum import Enum

class CircuitState(Enum):
    CLOSED = "CLOSED"       # 正常(リクエストを通す)
    OPEN = "OPEN"           # 遮断中(エラーを即返す)
    HALF_OPEN = "HALF_OPEN" # 試験中(少量のリクエストを通す)

class CircuitBreaker:
    def __init__(self, service_name, failure_threshold=5, timeout=60):
        self.service_name = service_name
        self.failure_threshold = failure_threshold
        self.timeout = timeout
        self.dynamodb = boto3.resource('dynamodb')
        self.table = self.dynamodb.Table('CircuitBreakerState')
    
    def call(self, func, *args, **kwargs):
        state = self._get_state()
        
        if state['status'] == CircuitState.OPEN.value:
            if time.time() - state['last_failure_time'] > self.timeout:
                self._set_state(CircuitState.HALF_OPEN.value)
            else:
                raise Exception(f"Circuit OPEN for {self.service_name}")
        
        try:
            result = func(*args, **kwargs)
            self._on_success()
            return result
        except Exception as e:
            self._on_failure()
            raise e
    
    def _on_success(self):
        self._set_state(CircuitState.CLOSED.value, failure_count=0)
    
    def _on_failure(self):
        state = self._get_state()
        failure_count = state.get('failure_count', 0) + 1
        
        if failure_count >= self.failure_threshold:
            self._set_state(CircuitState.OPEN.value, failure_count=failure_count)
        else:
            self._set_state(state['status'], failure_count=failure_count)

Domain 4: モニタリングとログ(15%)

4-1. オブザーバビリティの実装

構造化ログの設計:

import json
import logging
import datetime
from aws_xray_sdk.core import xray_recorder

logger = logging.getLogger()
logger.setLevel(logging.INFO)

class StructuredLogger:
    def __init__(self, service_name: str, environment: str):
        self.base_context = {
            "service": service_name,
            "environment": environment,
        }
    
    def info(self, message: str, **kwargs):
        self._log("INFO", message, **kwargs)
    
    def error(self, message: str, **kwargs):
        self._log("ERROR", message, **kwargs)
    
    def _log(self, level: str, message: str, **kwargs):
        log_entry = {
            "timestamp": datetime.datetime.utcnow().isoformat() + "Z",
            "level": level,
            "message": message,
            "trace_id": xray_recorder.current_trace_id() if xray_recorder.current_segment() else None,
            **self.base_context,
            **kwargs
        }
        logger.info(json.dumps(log_entry))

# 使用例
log = StructuredLogger("order-service", "prod")

def handler(event, context):
    log.info("Order processing started", 
              order_id=event.get('orderId'),
              customer_id=event.get('customerId'),
              request_id=context.aws_request_id)

SLO/SLIのアラーム設定:

import boto3

cloudwatch = boto3.client('cloudwatch')

# エラーバジェットアラーム
# 月次のエラーバジェット(43.2分 for 99.9% SLO)の50%を消費したらアラーム
cloudwatch.put_metric_alarm(
    AlarmName='ErrorBudget-50percent-consumed',
    AlarmDescription='エラーバジェットの50%を消費',
    MetricName='5XXError',
    Namespace='AWS/ApiGateway',
    Statistic='Sum',
    Period=300,
    EvaluationPeriods=1,
    Threshold=50,  # 5分間で50エラー
    ComparisonOperator='GreaterThanOrEqualToThreshold',
    AlarmActions=['arn:aws:sns:...'],
    Dimensions=[{'Name': 'ApiName', 'Value': 'MyAPI'}],
    TreatMissingData='notBreaching'
)

Domain 5: インシデントとイベントレスポンス(14%)

5-1. 自動インシデントレスポンス

EventBridge + Step Functionsによる自動対応:

// Step Functions ステートマシン定義(インシデント自動対応)
{
  "Comment": "自動インシデント対応フロー",
  "StartAt": "TriageIncident",
  "States": {
    "TriageIncident": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:::function:triage-incident",
      "Next": "ClassifySeverity"
    },
    "ClassifySeverity": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.severity",
          "StringEquals": "CRITICAL",
          "Next": "ImmediateResponse"
        },
        {
          "Variable": "$.severity",
          "StringEquals": "HIGH",
          "Next": "HighPriorityResponse"
        }
      ],
      "Default": "StandardResponse"
    },
    "ImmediateResponse": {
      "Type": "Parallel",
      "Branches": [
        {
          "StartAt": "NotifyOnCall",
          "States": {
            "NotifyOnCall": {
              "Type": "Task",
              "Resource": "arn:aws:states:::sns:publish",
              "Parameters": {
                "TopicArn": "arn:aws:sns:::oncall-critical",
                "Message.{{CONTENT}}quot;: "$.alert_message"
              },
              "End": true
            }
          }
        },
        {
          "StartAt": "CreateJiraTicket",
          "States": {
            "CreateJiraTicket": {
              "Type": "Task",
              "Resource": "arn:aws:lambda:::function:create-jira",
              "End": true
            }
          }
        },
        {
          "StartAt": "RunAutoRemediation",
          "States": {
            "RunAutoRemediation": {
              "Type": "Task",
              "Resource": "arn:aws:lambda:::function:auto-remediation",
              "End": true
            }
          }
        }
      ],
      "Next": "WaitForResolution"
    },
    "WaitForResolution": {
      "Type": "Wait",
      "Seconds": 3600,
      "Next": "CheckResolved"
    },
    "CheckResolved": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:::function:check-resolved",
      "End": true
    }
  }
}

Domain 6: セキュリティとコンプライアンス(17%)

6-1. DevSecOps の実装

パイプラインへのセキュリティ統合:

# CodePipeline にセキュリティゲートを追加
# Stage: SecurityScan
- Name: SecurityScan
  Actions:
    - Name: SASTScan
      ActionTypeId:
        Category: Build
        Owner: AWS
        Provider: CodeBuild
      Configuration:
        ProjectName: !Ref SastScanProject
      InputArtifacts:
        - Name: SourceOutput
      OutputArtifacts:
        - Name: SastReport

    - Name: DependencyCheck
      ActionTypeId:
        Category: Build
        Owner: AWS
        Provider: CodeBuild
      Configuration:
        ProjectName: !Ref DepCheckProject

    - Name: ContainerScan
      ActionTypeId:
        Category: Build
        Owner: AWS
        Provider: CodeBuild
      Configuration:
        ProjectName: !Ref ContainerScanProject

- Name: SecurityGate
  Actions:
    - Name: ManualApprovalIfHighSeverity
      ActionTypeId:
        Category: Approval
        Owner: AWS
        Provider: Manual
      Configuration:
        NotificationArn: !Ref SecurityTeamSNS
        CustomData: "High severity findings detected. Review required."

Inspector + CodePipeline の統合:

# Lambda: ECRスキャン結果チェック
import boto3
import json

def check_ecr_scan(image_uri, max_severity='HIGH'):
    """
    ECRイメージスキャン結果を確認し、
    max_severity以上の脆弱性があればパイプラインを停止
    """
    ecr = boto3.client('ecr')
    
    repo_name, tag = image_uri.split(':')[-2:]
    
    response = ecr.describe_image_scan_findings(
        repositoryName=repo_name,
        imageId={'imageTag': tag}
    )
    
    findings = response['imageScanFindings']['findingSeverityCounts']
    
    severity_order = ['CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFORMATIONAL']
    max_idx = severity_order.index(max_severity)
    
    for severity in severity_order[:max_idx + 1]:
        if findings.get(severity, 0) > 0:
            raise Exception(
                f"Security scan failed: {severity} vulnerabilities found: "
                f"{json.dumps(findings)}"
            )
    
    return {"status": "passed", "findings": findings}

学習計画(10週間)

Week 1-3: CI/CDとIaC

Week 1: CodePipeline/CodeBuild/CodeDeploy の詳細
  → 実際にマルチステージパイプラインを作成する
  → Blue/Green ECSデプロイを実装する

Week 2: CloudFormation 高度な機能
  → StackSets(複数アカウントへの展開)
  → Custom Resources
  → CloudFormation Guard(ポリシーとしてのコード)

Week 3: CDK実践
  → TypeScriptでスタックを作成
  → CDK Pipelinesで自己変異するパイプラインを実装

Week 4-6: 監視・セキュリティ・自動化

  • Week 4: CloudWatch(高度なアラーム、Logs Insights)
  • Week 5: EventBridge + Step Functions(自動インシデント対応)
  • Week 6: セキュリティ自動化(DevSecOps、Config Rules自動修復)

Week 7-8: 演習

  • Week 7: 模擬試験1回目(75問)+ 復習
  • Week 8: 弱点分野の集中学習

Week 9-10: 仕上げ

  • Week 9: 模擬試験2〜3回
  • Week 10: 最終確認と試験

アーキテクチャ図

Multi-Stage CodePipeline 全体フロー

flowchart LR
    subgraph Source["① Source"]
        GIT["CodeCommit\ngit push main"]
    end

    subgraph Build["② Build & Test"]
        CB1["CodeBuild\n単体テスト\nSAST (Bandit)"]
        CB2["CodeBuild\nDocker Build\nECR Push\nSBOM生成"]
    end

    subgraph Staging["③ Staging Deploy"]
        ECS_S["ECS Fargate\nStaging"]
        IntTest["CodeBuild\n統合テスト\nE2Eテスト"]
    end

    subgraph Gate["④ Quality Gate"]
        Approval["手動承認\nSNS → Slack"]
        SecScan["Inspector\n脆弱性スキャン\n結果確認"]
    end

    subgraph Prod["⑤ Production Deploy"]
        CG["CodeDeploy\nBlue/Green\n10%→100%"]
        Monitor["CloudWatch\nアラーム監視"]
    end

    GIT --> CB1 --> CB2 --> ECS_S --> IntTest --> SecScan --> Approval --> CG --> Monitor
    Monitor -->|"異常検知"| CG

Blue/Green デプロイ フロー

sequenceDiagram
    participant Dev as 開発者
    participant CP as CodePipeline
    participant CD as CodeDeploy
    participant ALB as ALB
    participant Blue as Blue環境(現行)
    participant Green as Green環境(新)
    participant CW as CloudWatch

    Dev->>CP: git push
    CP->>CD: デプロイ開始
    CD->>Green: 新バージョン起動
    CD->>ALB: テストトラフィック(10%)をGreenに向ける
    CW-->>CD: エラーレート確認
    CD->>ALB: 本番トラフィック(100%)をGreenに切り替え
    Note over ALB,Blue: 旧Blue環境は一定期間保持後に削除
    ALB-->>Blue: トラフィック 0%
    CW-->>CD: 異常検知時
    CD->>ALB: 自動ロールバック(Blue 100%)

本試験形式 模擬問題(詳細解説付き)


問題 1

本番環境への新機能デプロイで、最初は全体の 10% のユーザーに新バージョンを提供し、問題がなければ徐々に増やしていきたいと考えています。問題発生時は自動的に旧バージョンに戻したいです。ECS Fargate での最適な実装はどれですか?

  • A. ECS サービスの「ローリング更新」デプロイメント
  • B. CodeDeployECS Blue/Green デプロイ + CloudWatch アラームによる自動ロールバック
  • C. ECS タスク定義を手動で更新して徐々に切り替える
  • D. Route 53 の加重ルーティングで 10:90 に設定する
正解と解説

正解: B

解説:

  • B が正解: CodeDeployECS Blue/Green デプロイで以下が実現できます:
    • canarylinear デプロイメント設定で段階的にトラフィックを移行
    • deploymentReadyOption でトラフィック移行の待機時間設定
    • CloudWatch アラームを autoRollbackConfiguration に設定することで、エラーレート超過時に自動ロールバック
// appspec.yml (ECS)
{
  "Hooks": [{"AfterAllowTestTraffic": "arn:aws:lambda:...:ValidateService"}]
}
// デプロイ設定: ECSCanary10Percent5Minutes
// → 5分間10%のみ、問題なければ100%に切り替え
  • A(ローリング更新): 段階的なトラフィック制御はなく、自動ロールバックも限定的です。
  • C(手動): 自動化されていないため、24時間365日の対応が必要になります。
  • D(Route 53): ECSサービス単位でのバージョン管理ができないため、ブルーグリーンと組み合わせる必要があります。

問題 2

CloudFormation で管理されているリソースが誰かに手動で変更されています(ドリフト)。これを検出し、定期的に自動修正する仕組みを構築したい場合の最適な方法はどれですか?

正解と解説

正解: C

解説:

  • C が正解: CloudFormation のドリフト検出(detect-stack-drift)を EventBridge スケジュール(例: 毎日深夜)で実行し、ドリフト検出(DRIFTED 状態)を SNS で通知、必要に応じて CloudFormation 更新で自動修正するパターンです。
# Lambda でドリフト検出を実行
import boto3

def lambda_handler(event, context):
    cfn = boto3.client('cloudformation')
    sns = boto3.client('sns')
    
    # ドリフト検出開始
    response = cfn.detect_stack_drift(StackName='production-stack')
    detection_id = response['StackDriftDetectionId']
    
    # 結果確認(ポーリングまたは別Lambda)
    result = cfn.describe_stack_drift_detection_status(
        StackDriftDetectionId=detection_id
    )
    
    if result['StackDriftStatus'] == 'DRIFTED':
        sns.publish(
            TopicArn='arn:aws:sns:...:drift-alerts',
            Subject='CloudFormation Drift Detected',
            Message=str(result)
        )
  • B(AWS Config): リソースレベルの変更検知には有効ですが、CloudFormation スタックのドリフト概念とは異なります。
  • D(スタックポリシー): CloudFormation 更新を制限しますが、コンソール・CLI からの直接変更は防げません。

問題 3

マイクロサービスアーキテクチャで、サービスAがサービスBを呼び出しています。サービスBが過負荷になった場合、連鎖障害(カスケード障害)を防ぐためのパターンはどれですか?

  • A. サービスAのリトライ回数を増やす
  • B. サービス間通信にSQSを挟んで非同期化する
  • C. サーキットブレーカーパターンを実装する
  • D. サービスBのオートスケーリングの速度を上げる
正解と解説

正解: C

解説:

  • C(サーキットブレーカー)が正解: サーキットブレーカーはエラー率が閾値を超えると「サーキット(回路)をオープン」し、サービスBへの呼び出しを一時的に遮断します。これによりサービスBの回復時間を確保し、サービスAへの障害伝播(カスケード障害)を防ぎます。
# CircuitBreaker の状態機械
class CircuitState(Enum):
    CLOSED = "closed"     # 正常(リクエスト通過)
    OPEN = "open"         # 障害中(リクエスト遮断、即エラー返却)
    HALF_OPEN = "half_open"  # 回復確認(試験的リクエスト)

# CLOSED → (エラー率>50%) → OPEN → (timeout後) → HALF_OPEN → (成功) → CLOSED
  • A(リトライ増加): 過負荷状態のサービスへのリトライを増やすと、さらに負荷が増大し障害が悪化(Thundering Herd)。
  • B(SQS 非同期化): 非同期通信では有効ですが、同期的なAPIレスポンスが必要な場合は使えません。
  • D(自動スケーリング): 必要ですが、スケールアウトには時間がかかり、即時の連鎖障害防止にはなりません。

問題 4

開発チームが週に複数回の本番デプロイを安全に行えるようにするために、継続的デリバリー(CD)パイプラインにセキュリティゲートを組み込みたいと考えています。最も適切な DevSecOps の実装はどれですか?

  • A. 本番デプロイ前に手動のセキュリティレビューを必須にする
  • B. CodeBuild で SAST(静的解析)→ SCA(依存関係スキャン)→ ECR イメージスキャン(Inspector)→ 自動承認ゲートを実装する
  • C. 月次の外部ペネトレーションテストを実施する
  • D. AWS WAF を本番環境の前に設置する
正解と解説

正解: B

解説:

  • B(自動化されたセキュリティゲート)が正解: 「週複数回」のデプロイには手動レビューは速度のボトルネックになります。自動化されたセキュリティチェックを CI/CD に組み込む(Shift Left)ことで、速度を保ちながらセキュリティを確保できます。

DevSecOps パイプラインの各ゲート:

ステージ ツール 検出内容
SAST Bandit(Python)/ESLint コード内脆弱性
SCA Safety/Snyk 依存ライブラリの既知脆弱性
Secrets Scan git-secrets/Truffhog APIキー・パスワード漏洩
Container Scan ECR Inspector/Trivy コンテナイメージ脆弱性
IaC Scan cfn-nag/Checkov CloudFormation設定ミス
  • A(手動レビュー): 週複数回のデプロイでは人的ボトルネックになります。
  • C(月次ペネトレーションテスト): 必要ですが、デプロイ毎のゲートにはなりません。
  • D(WAF): ランタイムの保護には有効ですが、デプロイパイプラインのセキュリティゲートではありません。

問題 5

Infrastructure as Code(IaC)で CloudFormation テンプレートをモジュール化して再利用可能にしたい場合、最も適切な方法はどれですか?

  • A. CloudFormationInclude 機能で共通テンプレートを読み込む
  • B. CloudFormation Nested Stacks または CloudFormation Modules を使用する
  • C. 全リソースを単一の大きなテンプレートに定義する
  • D. AWS CDK でコードとして共通コンポーネントを NPM パッケージに分割する
正解と解説

正解: B または D(コンテキストによる)

解説: この問題は「CloudFormation で」という限定が重要です。

  • B(Nested Stacks / Modules): CloudFormation のネイティブ機能でモジュール化します。

    • Nested Stacks: 親スタックから子スタックを呼び出す(複雑な構成に有効)
    • CloudFormation Modules: 再利用可能なリソース設定テンプレート(Privateレジストリに登録)
  • D(CDK): CDKはTypeScript/Python等でインフラを定義する高レベルIaCです。NPMパッケージ化によるモジュール再利用は非常に強力ですが、CloudFormation自体のモジュール化ではなく、CDKがCFnテンプレートを生成します。

CloudFormation で」という文脈ではBが正解、「最も効果的なモジュール化」ならDもありです。

  • A(Include): CloudFormationInclude 機能は存在しません(誤りの選択肢)。
  • C(単一大テンプレート): 管理しにくく、変更時の影響範囲が大きい。アンチパターンです。

DOP-C02 追加詳解セクション

DevOps エンジニア試験の特徴

DevOps Engineer Professionalは、SAAまたはDVAの上位資格。「スケールでの自動化・CI/CD・インフラのコード化・セキュリティ統合」が中心テーマ。

CI/CD パイプライン 深掘り

マルチアカウント CI/CD パイプライン

エンタープライズCI/CDパターン:

┌─────────────────────────────────────────────────────────────┐
│  ツールアカウント(Pipeline Account)                        │
│  CodePipeline → CodeBuild → Artifact(S3)                  │
└─────────────────────────────────────────────────────────────┘
         ↓ 承認後デプロイ
┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
│  Dev アカウント   │  │ Staging アカウント│  │  Prod アカウント  │
│  自動デプロイ     │  │  自動デプロイ     │  │  手動承認後デプロイ│
└──────────────────┘  └──────────────────┘  └──────────────────┘

クロスアカウントデプロイの実装:
  → IAMロールのAssumeRoleでツールアカウントから各環境へデプロイ
  → KMSキーはクロスアカウントアクセスを許可
  → S3アーティファクトバケットのバケットポリシーで各アカウントを許可

コードのテスト戦略

テストピラミッド:
         /        /  \   E2Eテスト(少・遅・高コスト)
       /────      / 統合  \  統合テスト(中)
     /テスト       /───────────   /  単体テスト  \  ユニットテスト(多・速・低コスト)
  /_______________
CI/CDでのテスト自動化:
  → CodeBuild で自動テスト(buildspec.yml)
  → 失敗したら次のステージに進まない
  → テストカバレッジレポート(S3に保存)

CloudFormation 高度なトピック

スタックセット(StackSets)

概念:
  → 複数AWSアカウント・複数リージョンに同一スタックを一括デプロイ
  → 組織全体への標準的なリソース(IAMロール・CloudTrail等)の展開

タイプ:
  管理者アカウント(Admin Account): スタックセットを作成・管理
  ターゲットアカウント: スタックインスタンスがデプロイされる先

デプロイオーダー:
  → 最大同時デプロイ数(MaxConcurrentAccounts)
  → 失敗耐性(FailureToleranceCount): 何件失敗したら全体を停止するか

カスタムリソース(Custom Resources)

概念:
  → CloudFormationがネイティブサポートしていないリソースをLambdaで作成・管理

仕組み:
  → CloudFormationがLambda(またはSNS)にリクエスト送信
  → LambdaがAPIを呼び出してリソースを作成
  → LambdaがSend方式でCloudFormationにレスポンス送信

ユースケース:
  → サードパーティAPIの呼び出し
  → Route 53レコードの外部DNS設定
  → DBの初期データ投入
  → AMIの検索(最新AMI IDの動的取得)

Systems Manager 高度な活用

SSM Automation

概念:
  → 複雑な運用タスクをドキュメント(自動化ドキュメント)で定義・実行
  → 例: インスタンスの停止→スナップショット→再起動

組み込みドキュメント例:
  AWS-StopEC2Instance: EC2停止
  AWS-CreateImage: AMI作成
  AWS-PatchInstanceWithRollback: パッチ適用(ロールバック機能付き)

トリガー:
  → 手動実行
  → EventBridgeスケジュール
  → Configルール(非準拠時に自動修復)

AWS Config の自動修復

Config Rules → 非準拠検出 → Remediation Action → SSM Automation

例:
  1. Config Rule: s3-bucket-public-read-prohibited
  2. 非準拠S3バケットを検出
  3. Remediation Action: AWS-DisableS3BucketPublicReadWrite を実行
  4. 自動的にパブリックアクセスを無効化

イベント駆動アーキテクチャ

EventBridge 詳細

EventBridgeの主要概念:
  イベントバス(Event Bus):
    → デフォルトバス: AWSサービスからのイベント
    → カスタムバス: アプリケーションからのカスタムイベント
    → パートナーバス: SaaSパートナー(Salesforce等)からのイベント

  ルール(Rule):
    → イベントパターンマッチング(JSONフィルタ)
    → スケジュール(Cron/Rate式)

  ターゲット:
    → Lambda, SQS, SNS, Kinesis, Step Functions等

イベントパターンの例:
  {
    "source": ["aws.ec2"],
    "detail-type": ["EC2 Instance State-change Notification"],
    "detail": {
      "state": ["stopped", "terminated"]
    }
  }

Step Functions 詳細

概念:
  → ビジュアルワークフローでサーバーレスアプリケーションを調整
  → 各ステップのエラーハンドリング・リトライを宣言的に定義

ワークフロータイプ:
  Standard Workflow:
    → 1年間の実行時間
    → 完全な実行履歴
    → 高耐久性
    → 課金: 状態遷移回数

  Express Workflow:
    → 5分以内
    → 高スループット(秒間10万回以上)
    → ストリーム処理・IoTデータ処理に適合
    → 課金: 実行数 + 実行時間

状態タイプ:
  Task: Lambda/ECS等の処理実行
  Choice: 条件分岐
  Wait: 待機(タイマー)
  Parallel: 並列実行
  Map: 配列の各要素に対して処理
  Pass: データ変換(処理なし)
  Succeed/Fail: 終了状態

DOP-C02 模擬問題


問題 DOP-01

CloudFormation StackSetsの主な用途はどれですか?

  • A. 単一アカウント内の複数スタックを管理する
  • B. 複数のAWSアカウントと複数リージョンに同一スタックを一括デプロイする
  • C. スタック内のリソース変更を検出する
  • D. CloudFormationテンプレートのバージョン管理を行う
正解と解説

正解: B

StackSetsは複数のAWSアカウント・リージョンに同一のCloudFormationスタックを一括管理するサービス。組織全体への標準的なリソース(IAMロール・CloudTrail・Config等)の展開に最適。


問題 DOP-02

EventBridgeで「EC2インスタンスが停止または終了した場合に自動的にLambdaを呼び出してSlack通知する」ルールを設定したい。イベントパターンに含めるべき情報はどれですか?

  • A. EC2インスタンスのIPアドレス
  • B. source: aws.ec2 + detail-type: EC2 Instance State-change Notification + detail.state: [stopped, terminated]
  • C. CloudTrailのAPIイベント名
  • D. CloudWatchメトリクスの閾値
正解と解説

正解: B

EventBridgeのEC2状態変化イベントはsource: aws.ec2、detail-type: EC2 Instance State-change Notificationで識別される。detail.stateフィールドでstoppedやterminatedをフィルタリングする。


問題 DOP-03

Step Functions で「3つのLambda関数を同時に実行し、全て完了したら次のステップに進みたい」場合に使用する状態タイプはどれですか?

  • A. Choice
  • B. Map
  • C. Parallel
  • D. Task
正解と解説

正解: C

Parallel状態は複数のブランチを同時に実行し、全ブランチが完了してから次の状態に遷移する。Map状態は配列の各要素に同じ処理を繰り返す。


問題 DOP-04

AWS Config の自動修復(Auto Remediation)機能の説明として正しいものはどれですか?

  • A. CloudFormationスタックを自動的に更新する
  • B. Config Ruleで非準拠を検出した際にSSM Automationドキュメントを自動実行して修正する
  • C. CloudTrailのアラートに基づいてEC2を停止する
  • D. GuardDutyの脅威検知に基づいてIAMを変更する
正解と解説

正解: B

Config の自動修復はConfig Ruleの非準拠をトリガーにSSM Automationを実行する機能。例: S3バケットの公開設定をルールで検出→SSM Automationで自動的に非公開に設定する。


問題 DOP-05

マルチアカウント環境でCodePipelineからdev/staging/prodアカウントにクロスアカウントデプロイする際に必要なものはどれですか?(2つ選択)

  • A. 各ターゲットアカウントでCodePipelineパイプラインを個別に作成する
  • B. パイプラインアカウントのCodePipelineがターゲットアカウントのIAMロールをAssumeRoleする
  • C. アーティファクトS3バケットに各ターゲットアカウントのアクセスを許可するバケットポリシーを設定する
  • D. VPCピアリングで全アカウントを接続する
  • E. Route 53でアカウント間のDNSを設定する
正解と解説

正解: B, C

クロスアカウントデプロイ:

  • B: パイプラインアカウントがターゲットアカウントのデプロイロールをAssumeRoleしてCloudFormation等を実行
  • C: アーティファクトS3バケットのポリシーでターゲットアカウントの読み取りを許可

DOP-C02 試験直前チェックリスト

  • [ ] CloudFormation StackSets の用途(マルチアカウント展開)
  • [ ] カスタムリソース(Lambda/SNS)の仕組み
  • [ ] SSM Automation の自動修復フロー
  • [ ] EventBridge のイベントパターン構文
  • [ ] Step Functions Standard vs Express Workflow の違い
  • [ ] Step Functions の状態タイプ(Task/Choice/Parallel/Map等)
  • [ ] マルチアカウント CI/CD の IAMロール設定
  • [ ] CodeDeploy の Canary/Linear/AllAtOnce デプロイ設定

付録: DOP-C02 頻出サービス一覧

サービス DOP試験での重点
AWS CodePipeline マルチアカウント・承認ゲート・パイプライン設計
AWS CodeBuild buildspec.yml・テスト自動化・環境変数
AWS CodeDeploy appspec.yml・Lambda/ECSデプロイ設定
AWS CloudFormation StackSets・カスタムリソース・変更セット
AWS Systems Manager Automation・Session Manager・Patch Manager
Amazon EventBridge イベントバス・イベントパターン・スケジュール
AWS Step Functions ワークフロー・エラーハンドリング・Parallel/Map
AWS Config Rules・自動修復・Conformance Packs
AWS CloudTrail 組織証跡・ログファイルの整合性
Amazon CloudWatch カスタムメトリクス・ダッシュボード・Composite Alarm
AWS Organizations SCP・組織全体のポリシー管理
Amazon ECR コンテナイメージの管理・スキャン
Amazon ECS/EKS Blue/Greenデプロイ・ローリングアップデート

Domain 1 追加: 高度なCI/CDパターン

CodePipeline 詳細設定

マルチアカウントパイプライン設計

マルチアカウント CI/CD パターン
┌─────────────────────────────────────────────────────────────────┐
│  Tooling Account(CI/CDパイプライン専用)                         │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  CodePipeline                                           │   │
│  │  Source → Build → Test → [ManualApproval] → Deploy      │   │
│  └──────────────────────────────┬──────────────────────────┘   │
│                                 │                               │
│  ┌────────────────┐  ┌──────────┴──────────┐  ┌─────────────┐  │
│  │  Dev Account   │  │  Staging Account    │  │Prod Account │  │
│  │  自動デプロイ   │  │  統合テスト後        │  │ 承認後      │  │
│  │  CloudFormation│  │  CloudFormation      │  │CloudFormation│  │
│  │  StackSets     │  │  StackSets           │  │StackSets    │  │
│  └────────────────┘  └─────────────────────┘  └─────────────┘  │
│                                                                 │
│  IAMロール設定:                                                  │
│  ・Tooling Account に各ターゲットアカウントへのAssumeRole        │
│  ・ターゲットアカウントに CloudFormationDeploymentRole           │
└─────────────────────────────────────────────────────────────────┘
# CDK でのマルチアカウントパイプライン
from aws_cdk import (
    Stack, Environment,
    aws_codepipeline as codepipeline,
    aws_codepipeline_actions as cpactions,
    pipelines as pipelines
)

class MultiAccountPipeline(Stack):
    def __init__(self, scope, id, **kwargs):
        super().__init__(scope, id, **kwargs)
        
        pipeline = pipelines.CodePipeline(
            self, 'Pipeline',
            pipeline_name='multi-account-deploy',
            synth=pipelines.ShellStep(
                'Synth',
                input=pipelines.CodePipelineSource.code_commit(
                    repo, 'main'
                ),
                commands=[
                    'npm ci',
                    'npm run build',
                    'npx cdk synth'
                ]
            )
        )
        
        # Dev ステージ(自動デプロイ)
        pipeline.add_stage(
            AppStage(self, 'Dev', env=Environment(
                account='111111111111', region='us-east-1'
            ))
        )
        
        # Staging ステージ(統合テスト付き)
        staging_stage = pipeline.add_stage(
            AppStage(self, 'Staging', env=Environment(
                account='222222222222', region='us-east-1'
            )),
            post=[
                pipelines.ShellStep('IntegTest',
                    commands=['python -m pytest tests/integ/']
                )
            ]
        )
        
        # Prod ステージ(手動承認付き)
        pipeline.add_stage(
            AppStage(self, 'Prod', env=Environment(
                account='333333333333', region='us-east-1'
            )),
            pre=[
                pipelines.ManualApprovalStep('ProdApproval',
                    comment='本番デプロイを承認してください'
                )
            ]
        )

CodeBuild 高度なテスト自動化

# buildspec.yml - セキュリティスキャン + テスト完全版
version: 0.2

phases:
  pre_build:
    commands:
      # 依存関係の脆弱性チェック
      - pip install safety bandit
      - safety check --json > safety-report.json || true
      - bandit -r src/ -f json -o bandit-report.json || true
      
      # ECRログイン
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION |
          docker login --username AWS --password-stdin
          $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  
  build:
    commands:
      # コンテナビルド
      - docker build -t $ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION .
      
      # ユニットテスト
      - python -m pytest tests/unit/ --junitxml=test-reports/junit.xml
          --cov=src --cov-report=xml:coverage.xml
      
      # コンテナイメージスキャン(Trivy)
      - trivy image --exit-code 1 --severity HIGH,CRITICAL
          $ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION
  
  post_build:
    commands:
      # イメージプッシュ(テスト通過後のみ)
      - docker push $ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION
      - docker tag $ECR_REPO_NAME:$CODEBUILD_RESOLVED_SOURCE_VERSION
          $ECR_REPO_NAME:latest

reports:
  JUnitReports:
    files: ['test-reports/junit.xml']
    file-format: JUNITXML
  
  CoverageReport:
    files: ['coverage.xml']
    file-format: COBERTURAXML

artifacts:
  files:
    - imageDetail.json
    - appspec.yml
    - taskdef.json

CodeDeploy 詳細設定

Lambda デプロイ設定

# appspec.yml(Lambda)
version: 0.0

Resources:
  - MyLambdaFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: !Ref LambdaFunctionName
        Alias: !Ref LambdaAlias
        CurrentVersion: !Ref LambdaCurrentVersion
        TargetVersion: !Ref LambdaTargetVersion

Hooks:
  - BeforeAllowTraffic: ValidateBeforeDeployment
  - AfterAllowTraffic: ValidateAfterDeployment
# デプロイ前後のバリデーション Lambda
import boto3
import json

def validate_before_deployment(event, context):
    """デプロイ前チェック(現行バージョンで実行)"""
    deployment_id = event['DeploymentId']
    lifecycle_event_hook_execution_id = event['LifecycleEventHookExecutionId']
    
    try:
        # ヘルスチェック実施
        response = invoke_health_check()
        if response['status'] != 'healthy':
            raise Exception('Pre-deployment health check failed')
        
        # CodeDeploy に成功を通知
        codedeploy = boto3.client('codedeploy')
        codedeploy.put_lifecycle_event_hook_execution_status(
            deploymentId=deployment_id,
            lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
            status='Succeeded'
        )
    except Exception as e:
        codedeploy.put_lifecycle_event_hook_execution_status(
            deploymentId=deployment_id,
            lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
            status='Failed'
        )
        raise

def validate_after_deployment(event, context):
    """デプロイ後チェック(新バージョンで実行)"""
    deployment_id = event['DeploymentId']
    lifecycle_event_hook_execution_id = event['LifecycleEventHookExecutionId']
    
    # 新バージョンでのスモークテスト
    try:
        results = run_smoke_tests()
        if not all(r['passed'] for r in results):
            raise Exception('Smoke tests failed after deployment')
        
        codedeploy = boto3.client('codedeploy')
        codedeploy.put_lifecycle_event_hook_execution_status(
            deploymentId=deployment_id,
            lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
            status='Succeeded'
        )
    except Exception as e:
        codedeploy.put_lifecycle_event_hook_execution_status(
            deploymentId=deployment_id,
            lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
            status='Failed'
        )
        raise

ECS Blue/Green デプロイ設定

{
  "version": "0.0",
  "Resources": [
    {
      "TargetService": {
        "Type": "AWS::ECS::Service",
        "Properties": {
          "TaskDefinition": "<TASK_DEFINITION>",
          "LoadBalancerInfo": {
            "ContainerName": "web",
            "ContainerPort": 80
          },
          "PlatformVersion": "LATEST"
        }
      }
    }
  ],
  "Hooks": [
    {
      "BeforeInstall": "LambdaFunctionToValidateBeforeInstall"
    },
    {
      "AfterInstall": "LambdaFunctionToValidateAfterInstall"
    },
    {
      "AfterAllowTestTraffic": "LambdaFunctionToValidateAfterTestTrafficShifts"
    },
    {
      "BeforeAllowTraffic": "LambdaFunctionToValidateBeforeAllowTraffic"
    },
    {
      "AfterAllowTraffic": "LambdaFunctionToValidateAfterTrafficShifts"
    }
  ]
}

Domain 2 追加: 高度なInfrastructure as Code

CloudFormation 高度な機能

ネストされたスタック vs StackSets

CloudFormation スタック戦略
┌────────────────────────────────────────────────────────────┐
│  ネストされたスタック(Nested Stacks)                        │
│  用途: 単一アカウント内でのテンプレート分割・再利用          │
│                                                            │
│  ├── Root Stack                                           │
│  │    ├── Network Stack(VPC/Subnet)                     │
│  │    ├── Security Stack(SG/IAM)                        │
│  │    └── Application Stack(ECS/RDS)                   │
│                                                            │
├────────────────────────────────────────────────────────────┤
│  StackSets                                                  │
│  用途: 複数アカウント・リージョンへの同一テンプレート展開   │
│                                                            │
│  ├── 管理者アカウント(StackSet定義)                       │
│  │    ├── ターゲット: OU全体 or 特定アカウント             │
│  │    ├── ターゲットリージョン: us-east-1, ap-northeast-1 │
│  │    └── 展開オプション: MaxConcurrent/FailureTolerance  │
└────────────────────────────────────────────────────────────┘
# StackSets CLI 設定
AWSTemplateFormatVersion: '2010-09-09'
Description: '組織全体にデプロイするセキュリティ基準テンプレート'

Resources:
  # CloudTrail を全アカウントで強制有効化
  CloudTrailLogBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'cloudtrail-logs-${AWS::AccountId}-${AWS::Region}'
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: aws:kms
  
  CloudTrail:
    Type: AWS::CloudTrail::Trail
    Properties:
      TrailName: org-security-trail
      IsLogging: true
      IsMultiRegionTrail: true
      IncludeGlobalServiceEvents: true
      S3BucketName: !Ref CloudTrailLogBucket
      EnableLogFileValidation: true
      EventSelectors:
        - ReadWriteType: All
          IncludeManagementEvents: true
          DataResources:
            - Type: AWS::S3::Object
              Values: ['arn:aws:s3:::*']

CloudFormation カスタムリソース

# カスタムリソース Lambda 関数
import boto3
import cfnresponse
import json

def handler(event, context):
    print(f"Request type: {event['RequestType']}")
    
    try:
        if event['RequestType'] in ['Create', 'Update']:
            # リソース作成/更新ロジック
            result = create_or_update_resource(
                event['ResourceProperties']
            )
            cfnresponse.send(event, context, cfnresponse.SUCCESS, {
                'ResourceId': result['id'],
                'Endpoint': result['endpoint']
            })
        
        elif event['RequestType'] == 'Delete':
            # リソース削除ロジック
            resource_id = event.get('PhysicalResourceId')
            delete_resource(resource_id)
            cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
    
    except Exception as e:
        print(f"Error: {e}")
        cfnresponse.send(event, context, cfnresponse.FAILED, {
            'Error': str(e)
        })
# テンプレートでのカスタムリソース使用例
CustomDBUser:
  Type: Custom::DatabaseUser
  Properties:
    ServiceToken: !GetAtt CustomResourceFunction.Arn
    DBClusterArn: !Ref DBCluster
    Username: 'app_user'
    DatabaseName: 'production'
    SecretsManagerArn: !Ref DBSecret

# カスタムリソースの出力値参照
AppConnectionString:
  Value: !GetAtt CustomDBUser.Endpoint

AWS CDK(Cloud Development Kit)

# CDK スタック例(TypeScript同等のPython)
from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_ecs_patterns as ecs_patterns,
    aws_rds as rds,
    aws_elasticloadbalancingv2 as elbv2,
    RemovalPolicy, Duration
)
from constructs import Construct

class ProductionAppStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs):
        super().__init__(scope, construct_id, **kwargs)
        
        # VPC(マルチAZ、NATゲートウェイ付き)
        vpc = ec2.Vpc(
            self, 'ProductionVPC',
            max_azs=3,
            nat_gateways=2,
            subnet_configuration=[
                ec2.SubnetConfiguration(
                    name='Public',
                    subnet_type=ec2.SubnetType.PUBLIC,
                    cidr_mask=24
                ),
                ec2.SubnetConfiguration(
                    name='Private',
                    subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
                    cidr_mask=24
                ),
                ec2.SubnetConfiguration(
                    name='Isolated',
                    subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
                    cidr_mask=28
                )
            ]
        )
        
        # Aurora クラスター
        db_cluster = rds.DatabaseCluster(
            self, 'Database',
            engine=rds.DatabaseClusterEngine.aurora_postgres(
                version=rds.AuroraPostgresEngineVersion.VER_15_3
            ),
            instances=2,
            instance_props=rds.InstanceProps(
                instance_type=ec2.InstanceType.of(
                    ec2.InstanceClass.R6G,
                    ec2.InstanceSize.LARGE
                ),
                vpc=vpc,
                vpc_subnets=ec2.SubnetSelection(
                    subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
                )
            ),
            removal_policy=RemovalPolicy.SNAPSHOT
        )
        
        # ECS Fargate サービス
        cluster = ecs.Cluster(self, 'Cluster', vpc=vpc)
        
        fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(
            self, 'FargateService',
            cluster=cluster,
            cpu=512,
            memory_limit_mib=1024,
            desired_count=3,
            task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
                image=ecs.ContainerImage.from_ecr_repository(ecr_repo),
                container_port=8080,
                environment={
                    'DB_HOST': db_cluster.cluster_endpoint.hostname
                },
                secrets={
                    'DB_PASSWORD': ecs.Secret.from_secrets_manager(db_secret)
                }
            ),
            public_load_balancer=True
        )
        
        # Auto Scaling
        scaling = fargate_service.service.auto_scale_task_count(
            min_capacity=2, max_capacity=10
        )
        scaling.scale_on_cpu_utilization(
            'CpuScaling',
            target_utilization_percent=70,
            scale_in_cooldown=Duration.seconds(60),
            scale_out_cooldown=Duration.seconds(60)
        )

Domain 3 追加: 高可用性アーキテクチャ

マルチリージョン DR 戦略

DR 戦略比較
┌────────────────────────────────────────────────────────────────┐
│  RTO/RPO vs コスト                                              │
│                                                                │
│  Backup & Restore    Cold Standby   Warm Standby  Active/Active│
│  RTO: 数時間          RTO: 数十分     RTO: 数分      RTO: 数秒   │
│  RPO: 数時間          RPO: 数分      RPO: 数秒       RPO: ゼロ   │
│  コスト: 低            コスト: 低中     コスト: 中高    コスト: 高  │
│                                                                │
│  実装:                                                         │
│  バックアップ          最小リソース    スタンバイ起動    両リージョン │
│  S3/RDSスナップショット 起動時スケール  自動フェイルオーバー アクティブ│
└────────────────────────────────────────────────────────────────┘

Route 53 フェイルオーバー設定

import boto3

route53 = boto3.client('route53')

# プライマリ→セカンダリのフェイルオーバー設定
response = route53.change_resource_record_sets(
    HostedZoneId='Z1234567890',
    ChangeBatch={
        'Changes': [
            {
                'Action': 'CREATE',
                'ResourceRecordSet': {
                    'Name': 'api.example.com',
                    'Type': 'A',
                    'SetIdentifier': 'primary',
                    'Failover': 'PRIMARY',
                    'TTL': 60,
                    'ResourceRecords': [{'Value': '1.2.3.4'}],
                    'HealthCheckId': 'primary-health-check-id'
                }
            },
            {
                'Action': 'CREATE',
                'ResourceRecordSet': {
                    'Name': 'api.example.com',
                    'Type': 'A',
                    'SetIdentifier': 'secondary',
                    'Failover': 'SECONDARY',
                    'TTL': 60,
                    'AliasTarget': {
                        'HostedZoneId': 'Z35SXDOTRQ7X7K',
                        'DNSName': 'dr-alb.us-west-2.elb.amazonaws.com',
                        'EvaluateTargetHealth': True
                    }
                }
            }
        ]
    }
)

Auto Scaling 高度な設定

# 予測スケーリング(Predictive Scaling)
import boto3

autoscaling = boto3.client('autoscaling')

response = autoscaling.put_scaling_policy(
    AutoScalingGroupName='my-asg',
    PolicyName='predictive-scaling-policy',
    PolicyType='PredictiveScaling',
    PredictiveScalingConfiguration={
        'MetricSpecifications': [
            {
                'TargetValue': 40,
                'PredefinedMetricPairSpecification': {
                    'PredefinedMetricType': 'ASGCPUUtilization'
                }
            }
        ],
        'Mode': 'ForecastAndScale',  # 予測 + 実際のスケーリング
        'SchedulingBufferTime': 300,  # 5分前にスケールアウト
        'MaxCapacityBreachBehavior': 'IncreaseMaxCapacity',
        'MaxCapacityBuffer': 10  # 最大キャパシティを10%超過許容
    }
)

# スケジュールスケーリング(ビジネス時間対応)
response = autoscaling.put_scheduled_update_group_action(
    AutoScalingGroupName='my-asg',
    ScheduledActionName='business-hours-scale-out',
    Recurrence='0 9 * * MON-FRI',  # 月〜金 午前9時
    MinSize=10,
    DesiredCapacity=15
)

response = autoscaling.put_scheduled_update_group_action(
    AutoScalingGroupName='my-asg',
    ScheduledActionName='after-hours-scale-in',
    Recurrence='0 18 * * MON-FRI',  # 月〜金 午後6時
    MinSize=2,
    DesiredCapacity=3
)

Domain 4 追加: 高度なモニタリングとログ管理

CloudWatch 完全活用ガイド

カスタムメトリクスとダッシュボード

import boto3
import json
from datetime import datetime

cloudwatch = boto3.client('cloudwatch')

# カスタムメトリクスの送信
cloudwatch.put_metric_data(
    Namespace='MyApp/BusinessMetrics',
    MetricData=[
        {
            'MetricName': 'OrdersPerMinute',
            'Value': 47.5,
            'Unit': 'Count/Minute',
            'Timestamp': datetime.utcnow(),
            'Dimensions': [
                {'Name': 'Region', 'Value': 'ap-northeast-1'},
                {'Name': 'Environment', 'Value': 'Production'}
            ]
        },
        {
            'MetricName': 'PaymentSuccessRate',
            'Value': 99.2,
            'Unit': 'Percent',
            'Timestamp': datetime.utcnow(),
            'Dimensions': [
                {'Name': 'PaymentProvider', 'Value': 'Stripe'}
            ]
        }
    ]
)

# Composite Alarm(複合アラーム)設定
cloudwatch.put_composite_alarm(
    AlarmName='ProductionSystemAlert',
    AlarmDescription='CPU高騰 AND エラー率増加の複合検知',
    AlarmRule='(ALARM("HighCPUAlarm") AND ALARM("HighErrorRateAlarm"))',
    AlarmActions=['arn:aws:sns:us-east-1:123:prod-alert-topic'],
    OKActions=['arn:aws:sns:us-east-1:123:prod-ok-topic']
)

CloudWatch Logs Insights クエリ

-- エラーログの分析
fields @timestamp, @message, errorCode, requestId
| filter @message like /ERROR/
| stats count(*) as errorCount by errorCode
| sort errorCount desc
| limit 20

-- APIレイテンシ分析
fields @timestamp, apiName, latency, statusCode
| filter latency > 1000  -- 1秒以上のAPI
| stats avg(latency) as avgLatency, 
        p90(latency) as p90Latency,
        p99(latency) as p99Latency,
        count(*) as requestCount
  by apiName
| sort avgLatency desc

-- Lambda コールドスタート分析  
fields @timestamp, @requestId, @duration, @billedDuration, @initDuration
| filter @type = 'REPORT'
| stats count(@initDuration) as coldStarts,
        count(*) as totalInvocations,
        avg(@initDuration) as avgInitDuration
  by bin(1h)

CloudWatch Container Insights

# EKS/ECS Container Insights 有効化
import boto3

eks = boto3.client('eks')

# EKS クラスターのContainer Insights設定
response = eks.update_cluster_config(
    name='my-eks-cluster',
    logging={
        'clusterLogging': [
            {
                'types': ['api', 'audit', 'authenticator', 'controllerManager', 'scheduler'],
                'enabled': True
            }
        ]
    }
)

# アドオンとしてContainer Insightsエージェントをデプロイ
# kubectl apply -f https://raw.githubusercontent.com/aws-samples/
#   amazon-cloudwatch-agent-operator/main/config/

# カスタムダッシュボード作成(Infrastructure metrics)
cloudwatch = boto3.client('cloudwatch')

dashboard_body = {
    "widgets": [
        {
            "type": "metric",
            "properties": {
                "title": "Container CPU Utilization",
                "metrics": [
                    ["ContainerInsights", "pod_cpu_utilization", 
                     "ClusterName", "my-eks-cluster",
                     {"stat": "Average"}]
                ],
                "period": 60,
                "view": "timeSeries"
            }
        },
        {
            "type": "metric",
            "properties": {
                "title": "Container Memory Usage",
                "metrics": [
                    ["ContainerInsights", "pod_memory_utilization",
                     "ClusterName", "my-eks-cluster",
                     {"stat": "Average"}]
                ],
                "period": 60,
                "view": "timeSeries"
            }
        }
    ]
}

cloudwatch.put_dashboard(
    DashboardName='EKS-Production-Dashboard',
    DashboardBody=json.dumps(dashboard_body)
)

AWS X-Ray 分散トレーシング

# X-Ray を使った Lambda 関数のトレーシング
import boto3
from aws_xray_sdk.core import xray_recorder, patch_all
from aws_xray_sdk.core import patch

# AWS SDK の全呼び出しをトレース
patch_all()

@xray_recorder.capture('process_order')
def process_order(order_data):
    """注文処理(セグメント追跡)"""
    
    # サブセグメントでDB操作を追跡
    with xray_recorder.in_subsegment('validate_order'):
        validated = validate(order_data)
    
    with xray_recorder.in_subsegment('save_to_database'):
        # DynamoDB操作(自動でトレース)
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table('Orders')
        table.put_item(Item=order_data)
    
    with xray_recorder.in_subsegment('send_confirmation'):
        sns = boto3.client('sns')
        sns.publish(
            TopicArn='arn:aws:sns:us-east-1:123:OrderConfirmations',
            Message=json.dumps(order_data)
        )
    
    # カスタムアノテーション(インデックス化されフィルタリング可能)
    xray_recorder.current_segment().put_annotation('OrderId', order_data['id'])
    xray_recorder.current_segment().put_annotation('CustomerId', order_data['customer_id'])
    
    # カスタムメタデータ(非インデックス、詳細情報)
    xray_recorder.current_segment().put_metadata('OrderDetails', order_data)

def lambda_handler(event, context):
    for record in event['Records']:
        order = json.loads(record['body'])
        process_order(order)

Domain 5 追加: インシデントとイベントレスポンス

AWS Systems Manager インシデント管理

SSM Incident Manager 設定

import boto3

ssm_incidents = boto3.client('ssm-incidents')

# インシデント対応計画の作成
response = ssm_incidents.create_response_plan(
    name='production-outage-response',
    title='本番環境障害対応計画',
    
    incident_template={
        'title': '本番環境障害: {incident_id}',
        'impact': 1,  # 1=Critical, 2=High, 3=Medium, 4=Low
        'dedupeString': 'production-outage',
        'notificationTargets': [
            {'snsTopicArn': 'arn:aws:sns:us-east-1:123:oncall-alerts'}
        ]
    },
    
    # Runbookの設定(自動修復手順)
    actions=[
        {
            'ssmAutomation': {
                'documentName': 'AWSIncidents-DiagnoseECSIssues',
                'documentVersion': '$DEFAULT',
                'roleArn': 'arn:aws:iam::123456789:role/IncidentRole',
                'targetAccount': 'IMPACTED_ACCOUNT'
            }
        }
    ],
    
    # 関係者への通知
    engagements=[
        'arn:aws:ssm-contacts:us-east-1:123:contact/oncall-engineer'
    ],
    
    # チャットチャンネル(Slack/Chime)
    chatChannel={
        'chatbotSns': [
            'arn:aws:sns:us-east-1:123:incident-channel'
        ]
    }
)

EventBridge とLambdaによる自動修復

# EventBridge ルールでEC2の自動修復を実装
import boto3
import json

events = boto3.client('events')
ec2 = boto3.client('ec2')

# 1. Config のコンプライアンス違反をトリガーとする EventBridge ルール
events.put_rule(
    Name='auto-remediate-noncompliant-sg',
    EventPattern=json.dumps({
        'source': ['aws.config'],
        'detail-type': ['Config Rules Compliance Change'],
        'detail': {
            'configRuleArn': ['arn:aws:config:us-east-1:123:config-rule/restricted-ssh'],
            'newEvaluationResult': {
                'complianceType': ['NON_COMPLIANT']
            }
        }
    }),
    State='ENABLED'
)

# 2. 自動修復Lambda
def auto_remediate_handler(event, context):
    """SSH (22番ポート) が全開放されたセキュリティグループを自動修復"""
    
    # 違反したリソースIDを取得
    sg_id = event['detail']['resourceId']
    
    ec2 = boto3.client('ec2')
    
    # セキュリティグループのルールを取得
    sg_response = ec2.describe_security_groups(GroupIds=[sg_id])
    sg = sg_response['SecurityGroups'][0]
    
    # SSH(22番)の全開放ルールを削除
    for rule in sg['IpPermissions']:
        if rule.get('FromPort') == 22 and rule.get('ToPort') == 22:
            for ip_range in rule.get('IpRanges', []):
                if ip_range.get('CidrIp') == '0.0.0.0/0':
                    ec2.revoke_security_group_ingress(
                        GroupId=sg_id,
                        IpPermissions=[{
                            'IpProtocol': 'tcp',
                            'FromPort': 22,
                            'ToPort': 22,
                            'IpRanges': [{'CidrIp': '0.0.0.0/0'}]
                        }]
                    )
                    print(f'Revoked SSH from 0.0.0.0/0 in {sg_id}')
    
    # 修復完了をSNSで通知
    sns = boto3.client('sns')
    sns.publish(
        TopicArn='arn:aws:sns:us-east-1:123:security-alerts',
        Subject='Security Group Auto-Remediated',
        Message=f'Security Group {sg_id} was automatically remediated: SSH from 0.0.0.0/0 was removed.'
    )

Chaos Engineering(障害注入テスト)

# AWS FIS(Fault Injection Simulator)でカオスエンジニアリング
import boto3

fis = boto3.client('fis')

# 障害注入実験テンプレート作成
response = fis.create_experiment_template(
    description='EC2インスタンス障害シミュレーション',
    
    targets={
        'productionInstances': {
            'resourceType': 'aws:ec2:instance',
            'resourceTags': {
                'Environment': 'Production',
                'CanSimulateFault': 'true'  # 対象インスタンスにタグ付け
            },
            'selectionMode': 'PERCENT(20)'  # 20%のインスタンスに適用
        }
    },
    
    actions={
        'terminateInstances': {
            'actionId': 'aws:ec2:terminate-instances',
            'targets': {'Instances': 'productionInstances'},
            'startAfter': ['startDelay']
        },
        'startDelay': {
            'actionId': 'aws:fis:wait',
            'parameters': {'duration': 'PT30S'}  # 30秒待機
        }
    },
    
    # 安全装置(実験中断条件)
    stopConditions=[
        {
            'source': 'aws:cloudwatch:alarm',
            'value': 'arn:aws:cloudwatch:us-east-1:123:alarm/AvailabilityAlarm'
        }
    ],
    
    roleArn='arn:aws:iam::123456789:role/FISExperimentRole',
    
    # 実験ログ
    logConfiguration={
        'cloudWatchLogsConfiguration': {
            'logGroupArn': 'arn:aws:logs:us-east-1:123:log-group:/aws/fis/experiments'
        },
        'logSchemaVersion': 2
    }
)

Domain 6 追加: セキュリティとコンプライアンス自動化

AWS Security Hub 統合

import boto3
import json

securityhub = boto3.client('securityhub')

# Security Hub のカスタムアクション(Jira連携)
response = securityhub.create_action_target(
    Name='CreateJiraTicket',
    Description='セキュリティ検出事項からJiraチケットを自動作成',
    Id='CreateJiraTicket'
)

# カスタムインサイトでダッシュボード作成
response = securityhub.create_insight(
    Name='High-Severity-Findings-By-Resource',
    Filters={
        'SeverityLabel': [
            {'Value': 'HIGH', 'Comparison': 'EQUALS'},
            {'Value': 'CRITICAL', 'Comparison': 'EQUALS'}
        ],
        'WorkflowStatus': [
            {'Value': 'NEW', 'Comparison': 'EQUALS'}
        ]
    },
    GroupByAttribute='ResourceId'
)

AWS Config Conformance Packs

# conformance-pack.yaml - CIS Benchmark に基づくルールセット
Parameters:
  AccessKeysRotatedParamMaxAccessKeyAge:
    Default: '90'
    Type: String

Resources:
  # IAM アクセスキーのローテーション確認
  AccessKeysRotated:
    Type: AWS::Config::ConfigRule
    Properties:
      ConfigRuleName: access-keys-rotated
      Source:
        Owner: AWS
        SourceIdentifier: ACCESS_KEYS_ROTATED
      InputParameters:
        maxAccessKeyAge: !Ref AccessKeysRotatedParamMaxAccessKeyAge
  
  # MFA 必須確認
  MFAEnabledForIAMConsoleAccess:
    Type: AWS::Config::ConfigRule
    Properties:
      ConfigRuleName: mfa-enabled-for-iam-console-access
      Source:
        Owner: AWS
        SourceIdentifier: MFA_ENABLED_FOR_IAM_CONSOLE_ACCESS
  
  # S3 パブリックアクセスブロック確認
  S3BucketPublicReadProhibited:
    Type: AWS::Config::ConfigRule
    Properties:
      ConfigRuleName: s3-bucket-public-read-prohibited
      Source:
        Owner: AWS
        SourceIdentifier: S3_BUCKET_PUBLIC_READ_PROHIBITED
  
  # 自動修復アクション(S3パブリックアクセスを自動ブロック)
  S3BucketPublicReadRemediationConfiguration:
    Type: AWS::Config::RemediationConfiguration
    Properties:
      ConfigRuleName: !Ref S3BucketPublicReadProhibited
      TargetType: SSM_DOCUMENT
      TargetId: AWS-DisableS3BucketPublicReadWrite
      Automatic: true  # 自動修復有効
      MaximumAutomaticAttempts: 3
      RetryAttemptSeconds: 60
      Parameters:
        S3BucketName:
          ResourceValue:
            Value: RESOURCE_ID
        AutomationAssumeRole:
          StaticValue:
            Values:
              - arn:aws:iam::123456789:role/ConfigRemediationRole

IAM Access Analyzer 設定

import boto3

accessanalyzer = boto3.client('accessanalyzer')

# 組織全体のアナライザー作成
response = accessanalyzer.create_analyzer(
    analyzerName='org-wide-analyzer',
    type='ORGANIZATION',  # 組織全体スコープ
    tags={
        'Project': 'SecurityBaseline',
        'Environment': 'Production'
    }
)

# 特定のリソースを自動検証するルール設定
response = accessanalyzer.create_archive_rule(
    analyzerName='org-wide-analyzer',
    ruleName='allow-cross-account-for-partner',
    filter={
        # パートナーアカウントからのアクセスは許可済みとして無視
        'principal.AWS': {
            'contains': ['arn:aws:iam::999999999999:root']
        },
        'resourceType': {
            'eq': ['AWS::S3::Bucket']
        }
    }
)

# 未解決の検出事項を一覧表示
findings = accessanalyzer.list_findings(
    analyzerArn=response['arn'],
    filter={
        'status': {'eq': ['ACTIVE']},
        'resourceType': {'eq': ['AWS::IAM::Role']}
    },
    sort={'attributeName': 'UpdatedAt', 'orderBy': 'DESC'}
)

DOP-C02 模擬試験(65問)

問題1-20: SDLC自動化

Q1. CodeDeploy で ECS Blue/Green デプロイ中に新しいコンテナが起動した後、本番トラフィックを切り替える前に実行されるフックは?

  • A) AfterInstall
  • B) AfterAllowTestTraffic
  • C) BeforeAllowTraffic
  • D) AfterAllowTraffic

正解: C - BeforeAllowTraffic フックは新しいコンテナが起動し、テストリスナーへのトラフィックが完了した後、本番トラフィックを切り替える前に実行されます。ここでスモークテストやヘルスチェックを実行します。


Q2. CodePipeline でマルチアカウントデプロイを実現するための必要な設定は?

  • A) VPCピアリング設定のみ
  • B) Tooling アカウントのパイプライン実行ロールが各ターゲットアカウントのデプロイロールをAssumeRoleできる設定
  • C) Organizations SCP の設定のみ
  • D) リソースベースポリシーは不要

正解: B - マルチアカウントパイプラインには、①Toolingアカウントのパイプライン実行ロール ②ターゲットアカウントのCloudFormation/CodeDeployデプロイロール ③パイプラインロールから各アカウントロールへのsts:AssumeRole許可、が必要です。


Q3. CodeBuild でテストレポートを保存するための設定は?

  • A) CloudWatch Logs のみに出力
  • B) buildspec.yml の reports セクションに JUnit/Cobertura 形式で設定
  • C) S3 に手動アップロード
  • D) CodeCommit に保存

正解: B - buildspec.yml の reports セクションで JUnit(テスト結果)や Cobertura(カバレッジ)フォーマットを指定します。CodeBuild がレポートを解析し、コンソールでグラフィカルに表示してくれます。


Q4. CodePipeline のステージ間でアーティファクトを受け渡す際のストレージは?

  • A) EFS
  • B) S3(デフォルトでKMS暗号化)
  • C) DynamoDB
  • D) CodeCommit

正解: B - CodePipeline はステージ間のアーティファクトをS3バケットに保存します。デフォルトでSSE-KMS暗号化が適用されます。パイプライン作成時に自動生成されるS3バケットが使用されます。


Q5. CodeDeploy のデプロイ設定で「AllAtOnce」「HalfAtATime」「OneAtATime」以外に使用できるのは?

  • A) QuarterAtATime
  • B) カスタムデプロイ設定(最小健全ホスト数を指定)
  • C) TwoAtATime のみ
  • D) カスタム設定は不可能

正解: B - CodeDeploy ではカスタムデプロイ設定を作成でき、「最小健全ホスト数」をパーセンテージまたは絶対数で指定できます。例えば「常に70%以上のインスタンスを健全状態に保つ」といった設定が可能です。


Q6. CDK で「CDK Pipelines」を使う主な利点は?

  • A) 速度が速い
  • B) インフラのコードもCI/CDパイプラインで自動デプロイ・自己更新(Self-mutating)できる
  • C) コストが安い
  • D) CloudFormation不要

正解: B - CDK Pipelinesのself-mutating機能により、パイプライン自体のコードを変更しても、パイプラインが次回実行時に自動的に自身を更新します。インフラのCI/CDを完全自動化できます。


Q7. CodeCommit でプルリクエストのマージを特定のブランチ保護ルールを設定するには?

  • A) 直接設定できない。Lambda + EventBridge で実装
  • B) ブランチポリシーの承認ルールテンプレートで設定
  • C) IAMポリシーのみで制御
  • D) CloudFormationのみで設定可能

正解: B - CodeCommit の「承認ルールテンプレート」を使用して、特定のブランチへのマージに必要な承認者数や承認グループを設定できます。例:「mainブランチへのPRは最低2名の承認が必要」。


Q8. GitHub Actions から AWS にデプロイする際のベストプラクティスは?

  • A) AWSアクセスキーをGitHub Secretsに保存
  • B) GitHub OIDC プロバイダーと IAMロールを使ってアクセスキー不要で認証
  • C) EC2上でActionsを実行
  • D) キーのローテーションを毎月実施

正解: B - GitHub OIDC(OpenID Connect)との連携により、GitHub Actionsがトークンを使ってIAMロールをAssumeRoleできます。長期的なアクセスキーを管理するリスクがなくなります。


Q9. CodePipeline に手動承認ゲートを追加した際、承認の通知先として使えるのは?

  • A) メールのみ
  • B) SNS トピック(→ Eメール/Lambda/Slack等)
  • C) SQS のみ
  • D) CloudWatch Alarmのみ

正解: B - 手動承認アクションにSNSトピックを設定すると、承認リクエスト発生時に通知が送信されます。SNSからEmailSubscription(承認URLメール)やLambda(Slack通知)など様々な連携が可能です。


Q10. ECR のコンテナイメージスキャンの2種類は?

  • A) Quick Scan と Deep Scan
  • B) Basic Scan(プッシュ時スキャン)と Enhanced Scan(Amazon Inspectorによる継続的スキャン)
  • C) Layer Scan と Full Scan
  • D) Manual と Automatic のみの違い

正解: B - ECR Basic Scan はプッシュ時にOS パッケージの脆弱性を検査。Enhanced Scan は Amazon Inspector を使ってOS + アプリケーション依存関係を継続的にスキャンし、新しいCVEが公開されると自動再スキャンされます。


問題11-30: IaC、モニタリング、セキュリティ

Q11. CloudFormation StackSets でデプロイに失敗した場合のデフォルト動作は?

  • A) 全スタックをロールバック
  • B) FailureTolerance の設定に従い、許容範囲内の失敗は継続、超えると停止
  • C) 即座に全デプロイを停止
  • D) 失敗を無視して続行

正解: B - StackSets の FailureToleranceCount(失敗許容数)や FailureTolerancePercentage(失敗許容割合)の設定に従い動作します。許容範囲内であれば他のアカウントへのデプロイを継続します。


Q12. CloudFormation の「変更セット(Change Sets)」の主な用途は?

  • A) テンプレートの文法確認のみ
  • B) スタック更新前に追加/変更/削除されるリソースをプレビューし、意図しない変更を防ぐ
  • C) バックアップの作成
  • D) コスト見積もりのみ

正解: B - 変更セットは実際にスタックを更新する前に「何が変わるか」をプレビューします。特に削除(Removal)や置換(Replacement)が発生するリソースを事前確認することで、意図しないダウンタイムを防ぎます。


Q13. AWS CDK の cdk diff コマンドの役割は?

  • A) コードのテスト実行
  • B) 現在デプロイ済みのスタックとコードの差分をCloudFormation変更セット形式で表示
  • C) 依存関係の更新確認
  • D) コストの比較

正解: B - cdk diff は現在のスタックと新しいコードの変更点を CloudFormation の変更セット形式で出力します。デプロイ前の確認に不可欠で、意図しない変更の検出に役立ちます。


Q14. CloudWatch Synthetics の主な用途は?

  • A) Lambda のパフォーマンス最適化
  • B) Canary テストで定期的にAPIやWebサイトのエンドポイントを自動監視
  • C) コード品質チェック
  • D) コスト最適化

正解: B - CloudWatch Synthetics Canary は Node.js/Pythonスクリプトをスケジュール実行して、APIエンドポイントのレイテンシ・可用性・機能を24時間365日自動テストします。ユーザー影響前に問題を検出できます。


Q15. AWS X-Ray でのサービスマップの主な利点は?

  • A) コストの可視化
  • B) マイクロサービス間の依存関係とレイテンシをグラフィカルに可視化し、ボトルネック特定
  • C) IAMポリシーの可視化
  • D) CloudFormationスタックの可視化

正解: B - X-Ray サービスマップはマイクロサービスアーキテクチャ内の各サービスとその依存関係、レイテンシ、エラー率を視覚的に表示します。分散システムのパフォーマンス問題やエラーの根本原因特定に役立ちます。


Q16. CloudTrail の「ログファイルの整合性の検証」機能は何に使うか?

  • A) ログのパフォーマンス向上
  • B) ログが改ざんされていないことを暗号的(SHA-256ハッシュ+デジタル署名)に証明
  • C) ログの自動圧縮
  • D) ログの検索高速化

正解: B - CloudTrail のログファイル整合性検証はDigest File(SHA-256ハッシュとデジタル署名)を使ってログの改ざん検知を可能にします。コンプライアンス監査やフォレンジック調査での証拠性確保に重要です。


Q17. AWS Config の「Conformance Pack」とは?

  • A) 設定ファイルのパッケージ
  • B) 複数のConfig Rulesと修復アクションをパッケージ化したコンプライアンスフレームワーク(CIS Benchmarkなど)
  • C) CloudFormationテンプレートの集合
  • D) IAMポリシーのセット

正解: B - Conformance Pack は複数のConfig RulesとSSM修復ドキュメントをまとめてデプロイできます。CIS AWS Foundations Benchmark、NIST 800-53、PCI DSSなどの業界標準の事前定義済みパックが用意されています。


Q18. Security Hub の「統合(Integrations)」で連携できるサードパーティ製品は?

  • A) AWSサービスのみ
  • B) Splunk、Palo Alto Networks、CrowdStrike などのサードパーティセキュリティ製品
  • C) Microsoftのみ
  • D) 統合は不可能

正解: B - Security Hub は AWS セキュリティサービス(GuardDuty/Inspector/Macie等)だけでなく、Splunk、Palo Alto Networks、CrowdStrike、Trend Micro、Snyk などのサードパーティ製品からの検出事項もASFF(Amazon Security Finding Format)で集約できます。


Q19. AWS Organizations の Service Control Policy(SCP)について正しいのは?

  • A) IAM権限を追加できる
  • B) SCPはAWS管理者も含む全てのIAMエンティティの最大権限を制限(Denyのみ)
  • C) ルートアカウントには適用されない
  • D) リソースベースポリシーを上書きできる

正解: B - SCPはアカウントのIAMエンティティが実行できるアクションの「最大権限」を設定します。SCPで拒否されているアクションはrootユーザー含む全ユーザーが実行不可になります。SCPは追加ではなく制限のみです(Explicit Allow必要)。


Q20. AWS Macie でS3のデータ検出をカスタマイズするには?

  • A) カスタム検出ルールは設定不可
  • B) カスタムデータ識別子(正規表現パターン)を作成してドメイン固有の機密データを検出
  • C) Config Rulesを使用
  • D) Lambda関数のみで対応

正解: B - Macie のカスタムデータ識別子は、正規表現とキーワードを使って組織固有の機密情報パターン(社員ID、顧客番号、特定フォーマットの番号等)を定義できます。組み込みの検出(クレジットカード/SSN等)に加えて独自パターンを追加できます。


問題21-40: 高度な運用

Q21. SSM Session Manager が従来のSSH/RDPより優れている点は?

  • A) 速度が速い
  • B) 踏み台サーバー不要、ポート開放不要、全セッションがCloudTrail/S3に記録
  • C) より多くのプロトコルをサポート
  • D) 低コスト

正解: B - Session Manager はSSHポート(22)やRDPポート(3389)を開放せずにEC2に接続できます。踏み台サーバーも不要で、全操作ログがCloudTrail/S3/CloudWatch Logsに自動記録されるため監査要件を満たします。


Q22. SSM Patch Manager で定期的なパッチ適用を自動化するには?

  • A) Lambda で手動実装
  • B) パッチベースラインとメンテナンスウィンドウを組み合わせて設定
  • C) EventBridge のみで実装
  • D) Config Rulesで管理

正解: B - SSM Patch Manager は①パッチベースライン(適用するパッチの基準:重要度/OS/製品)を定義し②メンテナンスウィンドウ(パッチ適用の時間窓)にPatch Manager タスクを設定することで自動パッチ適用を実現します。


Q23. Step Functions の「Error Handling」でリトライと例外キャッチを実装するには?

  • A) Lambda 内でのみ実装
  • B) TaskステートのRetryフィールド(指数バックオフ付き)とCatchフィールド
  • C) SQS のデッドレターキューのみで対応
  • D) CloudWatch Alarmと連動

正解: B - StepFunctions の Task ステートには Retry(指数バックオフ設定可能なリトライ)と Catch(特定エラータイプをキャッチして別ステートに遷移)を設定できます。これにより詳細なエラーハンドリングが可能です。


Q24. EventBridge の「イベントバス(Event Bus)」の種類は?

  • A) Default のみ
  • B) Default(AWSサービス)、Partner(SaaS連携)、Custom(カスタムイベント)の3種類
  • C) PublicとPrivateの2種類
  • D) AWSとカスタムの2種類

正解: B - Default Bus: AWSサービスのイベント(EC2状態変化等)、Partner Bus: Zendesk/Datadog等のSaaSイベント、Custom Bus: 独自アプリケーションのビジネスイベント。クロスアカウントイベント共有もサポートします。


Q25. CloudFormation のドリフト検出(Drift Detection)とは?

  • A) テンプレートの文法エラー検出
  • B) CloudFormation管理外での変更(コンソール直接操作等)とテンプレートの差異を検出
  • C) スタックの削除確認
  • D) コスト変動の検出

正解: B - Drift Detection はスタックのリソースが CloudFormation の期待する設定から外れた変更(「ドリフト」)を検出します。誰かがコンソールで直接設定を変更した場合などに、テンプレートとの差異を特定できます。


Q26. AWS Backup でバックアップポリシーをOrganizations全体に適用するには?

  • A) 各アカウントで個別設定のみ
  • B) Organizations のバックアップポリシー(Backup Policy)を使ってOU全体にバックアップ計画を適用
  • C) StackSetsで各アカウントにデプロイ
  • D) Lambda 関数で管理

正解: B - Organizations のバックアップポリシー(Management Policy Type: BACKUP)を使用すると、組織全体またはOUのアカウントに対してAWS Backupの計画(頻度/保持期間/ストレージ)を一括適用できます。


Q27. Lambda 関数のデプロイで「エイリアス(Alias)」を使う主な理由は?

  • A) パフォーマンス向上
  • B) バージョン管理と安定したエンドポイント提供(v1→v2への段階的移行も可能)
  • C) コスト削減
  • D) ログの集約

正解: B - エイリアスは特定のバージョンへのポインターです。"production"エイリアスをv1に向け、デプロイ後にv2を10%→50%→100%と段階的に移行できます(Canary/Linear/AllAtOnce)。呼び出し元のARNを変えずにバージョン管理できます。


Q28. ECR のライフサイクルポリシーの主な用途は?

  • A) セキュリティスキャンの自動化
  • B) 古いコンテナイメージを自動削除してストレージコストを削減
  • C) イメージの暗号化設定
  • D) プッシュ権限の管理

正解: B - ECRライフサイクルポリシーは条件(タグ有無/プッシュ日付/イメージ数)を設定して古いイメージを自動削除します。例:「untaggedイメージは7日後に削除」「10個を超えるイメージは古い順に削除」。


Q29. CloudWatch Anomaly Detection の仕組みは?

  • A) 固定閾値との比較
  • B) 機械学習でメトリクスの通常パターンを学習し、統計的な異常を検出
  • C) 人手によるルール設定
  • D) 他サービスとのメトリクス比較

正解: B - Anomaly Detection はメトリクスの過去データを機械学習で分析し、時間帯・曜日・季節性を考慮した「正常範囲」を自動学習します。範囲を外れた場合にアラームを発生させるため、固定閾値では検出できない異常を捉えられます。


Q30. AWS Systems Manager Parameter Store と Secrets Manager の使い分けは?

  • A) 機能は同じ
  • B) Parameter Storeは設定値・非機密データ向け(無料/低コスト)、Secrets Managerはシークレット自動ローテーション機能付き(有料)
  • C) Secrets Managerの方がパフォーマンスが高い
  • D) Parameter Storeはキャッシュ不可

正解: B - Parameter Store(Standard無料/Advanced0.05/月)は設定値や非機密情報に最適。Secrets Manager(0.40/月/シークレット)は自動ローテーション(RDS/Redshift/DocumentDB対応)と多様な統合機能が必要な場合に使用します。


問題31-50: 高度なシナリオ問題

Q31. マルチリージョンの DR 設定で「最低コストで RPO 1時間」を達成するアーキテクチャは?

  • A) Active/Active(両リージョンで本番稼働)
  • B) Pilot Light(コアシステムのみスタンバイ) + 1時間ごとのRDSスナップショット・S3クロスリージョンレプリケーション
  • C) Warm Standby(フル稼働規模の半分でスタンバイ)
  • D) バックアップ&リストアのみ(毎時スナップショット)

正解: B - Pilot Lightは最小限のインフラ(データベースのレプリカとAMI)をDRリージョンで待機させ、災害時にスケールアップします。RDSクロスリージョンリードレプリカまたは1時間間隔のスナップショットでRPO 1時間を達成できます。コストは比較的低いです。


Q32. CloudFormation でRDSパスワードを安全に管理する方法は?

  • A) テンプレートに直接記述
  • B) Secrets Manager でシークレットを作成し、{{resolve:secretsmanager:...}} 動的参照を使用
  • C) S3から読み込む
  • D) CodePipeline の環境変数で渡す

正解: B - CloudFormation の動的参照 {{resolve:secretsmanager:MySecret:SecretString:password}} を使うと、テンプレートにパスワードを記述せずに Secrets Manager からリアルタイムで値を取得できます。


Q33. ECS サービスで新しいタスク定義をデプロイする際のロールバック自動化は?

  • A) 手動のみ
  • B) CodeDeploy Blue/Green + CloudWatch Alarm(エラー率/CPU閾値)+ AppSpec のアラームベースロールバック
  • C) Auto Scalingグループのヘルスチェックのみ
  • D) Route 53 フェイルオーバーのみ

正解: B - CodeDeploy の Blue/Green デプロイで alarm 設定を追加すると、デプロイ後のCloudWatch Alarmがアラーム状態になった場合に自動ロールバックされます。エラー率や5xxエラー数などのメトリクスベースの自動ロールバックを実現できます。


Q34. Organizations でメンバーアカウントの EC2 購入を特定リージョンに制限する SCP は?

  • A) IAM境界(Permission Boundary)を使用
  • B) SCP で ec2:* アクションに対して Condition: StringNotEquals: aws:RequestedRegion で拒否
  • C) Service Catalogで制限
  • D) CloudFormation Stackで管理

正解: B - SCP の Deny 文に StringNotEquals aws:RequestedRegion 条件を使用します。例:ap-northeast-1us-east-1 以外でのEC2リソース作成を拒否。これにより全メンバーアカウントで指定リージョン外でのEC2操作を禁止できます。


Q35. Kinesis Data Streams への書き込みを CodePipeline でテストするには?

  • A) Lambda を使って手動テスト
  • B) CodeBuild の buildspec.yml に統合テストフェーズを追加し、ストリームに書き込んで Lambda 処理をE2Eテスト
  • C) CloudWatch Logsのみで確認
  • D) テスト不可能

正解: B - CodeBuild に統合テストフェーズを追加し、実際のKinesisストリームにテストデータを書き込み、Lambda処理が期待通りの出力をS3/DynamoDBに書いているかを検証します。テスト用の専用ストリームを使うことが推奨されます。


Q36. CloudFormation で「依存関係の問題」(循環依存)を解決する方法は?

  • A) 手動で順番を管理
  • B) Export/ImportValue で別スタックに分割するか、カスタムリソースで順序を制御
  • C) 循環依存は必ず解消できない
  • D) DependsOn のみで解決

正解: B - CloudFormation は循環依存(A→B→A)をエラーにします。解決策:①スタックを分割してOutputs/ImportValue で参照(スタック間の疎結合)②Lambdaカスタムリソースで実行順序を制御③設計を見直して循環を排除、などです。


Q37. SSM Run Command でコマンドを実行した際の出力を確認する方法は?

  • A) EC2コンソールのみ
  • B) S3バケット、CloudWatch Logs、または GetCommandInvocation API
  • C) コンソールのみで確認可能
  • D) SQS キューに自動送信

正解: B - Run Commandの出力は:①S3バケット(出力をファイル保存)②CloudWatch Logs(ストリーミング記録)③aws ssm get-command-invocation API(プログラム的に取得)の3つの方法で確認できます。


Q38. CodePipeline で「変更なしのフォースリリース」を実行するには?

  • A) 不可能
  • B) コンソールまたは aws codepipeline start-pipeline-execution CLIで強制実行
  • C) CodeBuild を直接実行
  • D) CloudFormation を再デプロイ

正解: B - aws codepipeline start-pipeline-execution --name MyPipeline コマンドでパイプラインを強制実行できます。コンソールからは「変更のリリース」ボタンで実行可能です。ホットフィックスが必要なときなどに使います。


Q39. EKS でのローリングアップデートをゼロダウンタイムで実施するための設定は?

  • A) Deployment のreplicasを増やすのみ
  • B) PodDisruptionBudget(PDB)で最小稼働Pod数を保証し、maxSurge/maxUnavailableを適切に設定
  • C) LoadBalancerの設定のみ
  • D) HorizontalPodAutoscalerのみ

正解: B - maxUnavailable: 0(更新中も全Podを維持)maxSurge: 1(余分に1 Pod起動)に設定し、PodDisruptionBudget で「最低でも必要数のPodを稼働状態に保つ」を設定します。ReadinessProbeを適切に設定することも重要です。


Q40. CloudWatch での「コンポジットアラーム(Composite Alarm)」のユースケースは?

  • A) 複数メトリクスの平均
  • B) 複数のアラーム状態をAND/ORロジックで組み合わせ、アラーム疲れを軽減
  • C) 異なるリージョンのアラームの統合
  • D) コスト管理のみ

正解: B - Composite AlarmはAND/ORロジックで複数のアラームを組み合わせます。例:「CPU > 80% AND ErrorRate > 5%」の時のみアラートを発生させることで、CPU高騰だけやエラー急増だけでは通知せず、組み合わさった深刻な状況のみ通知できます(アラーム疲れ防止)。


問題41-65: 模擬問題総合

Q41. AWS CDK のデプロイ時に「スタックのアップデート前に確認する」ためのコマンドは?

  • A) cdk check
  • B) cdk diff(差分確認)→ cdk deploy(実際にデプロイ)
  • C) cdk validate のみ
  • D) cdk synth のみで確認

正解: B - cdk diff で現在のスタックとの変更差分を確認し、問題なければ cdk deploy でデプロイします。CI/CDパイプラインでも cdk diff を実行して変更内容をプルリクエストに出力するワークフローが一般的です。


Q42. Elastic Beanstalk のデプロイポリシー比較で「最も安全(ダウンタイムなし + 問題時に旧バージョンが即座に復元)」なのは?

  • A) Rolling
  • B) Rolling with additional batch
  • C) Immutable
  • D) Blue/Green

正解: D - Elastic Beanstalk のBlue/Greenは全く別の環境を作成し、CNAMEスワップでトラフィックを切り替えます。問題時はCNAMEを旧環境に戻すだけで即座にロールバック可能。Immutableも安全ですが、同じ環境内のため旧バージョンへの戻しにやや時間がかかります。


Q43. OpsWorks Stacks が廃止になるにあたり、移行先として推奨されるのは?

  • A) OpsWorks for Chef Automate
  • B) AWS Systems Manager(State Manager + Run Command)または AWS CloudFormation + CodeDeploy
  • C) Elastic Beanstalk のみ
  • D) EC2 Auto Scalingのみ

正解: B - OpsWorks Stacks の機能の代替:設定管理はSSM State Manager、コマンド実行はSSM Run Command、インフラプロビジョニングはCloudFormation/CDK、デプロイ自動化はCodeDeploy が各機能を代替します。


Q44. GitOps を AWS で実装する際の推奨アーキテクチャは?

  • A) 手動デプロイのみ
  • B) CodeCommit/GitHub + Flux/ArgoCD で Kubernetes 宣言的設定を自動同期
  • C) CloudFormation のみ
  • D) SSM Automation のみ

正解: B - GitOps はGitリポジトリを「Single Source of Truth」とし、リポジトリの状態とデプロイ環境を常に同期させます。EKSの場合はFlux v2またはArgoCDを使い、GitにマージされたKubernetes マニフェストを自動適用します。


Q45. AWS Config Rules で「リアルタイム(変更検知)」評価と「定期(スケジュール)」評価の使い分けは?

  • A) 違いはない
  • B) リアルタイム(Change Triggered)はリソース変更時即座評価、定期はConfig Rulesで固定時間に評価(IAMパスワードポリシー等)
  • C) 定期評価の方が常に推奨
  • D) リアルタイムのみサポート

正解: B - Change Triggered: リソース設定変更時に即座評価(EC2セキュリティグループ変更検知等)。Periodic: 定期実行が必要なルール(IAMパスワードポリシー確認/アクセスキー年齢確認等)。どちらかまたは両方をルールに設定できます。


Q46. CloudWatch Logs のサブスクリプションフィルター(Subscription Filter)の主な用途は?

  • A) ログの圧縮
  • B) 特定パターンのログをリアルタイムでLambda/Kinesis/OpenSearchに転送
  • C) ログのアーカイブのみ
  • D) アクセス制御の設定

正解: B - サブスクリプションフィルターは正規表現パターンでログをフィルタリングし、マッチしたログをリアルタイムでLambda(アラート処理)、Kinesis Firehose(OpenSearchへの転送)、Kinesis Data Streams(分析)に転送できます。


Q47. CodePipeline にSlack通知を統合する最も簡単な方法は?

  • A) Lambda で API 呼び出しを実装
  • B) AWS Chatbot を Slack ワークスペースと連携し、CodePipeline イベントを通知
  • C) SNS + EmailSubscription のみ
  • D) EventBridge + Webhook のみ

正解: B - AWS Chatbot は Slack や Amazon Chime と連携し、SNS トピックを通じて CodePipeline のイベント(失敗/成功/承認待ち)をSlackチャンネルに通知できます。Chatbotコンソールから設定するだけで実装できます。


Q48. Amazon Inspector v2 の主な機能拡張(v1と比較)は?

  • A) 機能は同じ
  • B) コンテナイメージのスキャン(ECR)、Lambda関数のコードスキャン、継続的自動スキャン、Organizations統合
  • C) v2はEC2専用
  • D) v2は高コスト以外の改善なし

正解: B - Inspector v2 は:①ECR プッシュ時の自動コンテナスキャン②Lambda関数のパッケージ脆弱性スキャン③組織全体の統合管理④Security Hubとの深い統合⑤継続的スキャン(新しいCVE公開時に自動再評価)、などv1から大幅に機能強化されています。


Q49. CloudFormation の実行ロール(Execution Role)の用途は?

  • A) テンプレートの検証のみ
  • B) CloudFormationがリソースを作成/更新/削除する際に使用するIAMロール(最小権限でリソース操作権限を付与)
  • C) パイプラインの実行権限
  • D) コンソールアクセスのみ

正解: B - 実行ロール(Service Role)はCloudFormationがスタック操作時に使用するロールです。デプロイ担当者のIAM権限とは分離でき、「CloudFormationにはEC2/RDSを作成できるが、人間のオペレータには削除権限なし」のような権限分離が実現できます。


Q50. AWS Service Catalog でITサービスカタログを管理する主な利点は?

  • A) コスト削減のみ
  • B) 承認済みCloudFormationテンプレートのセルフサービスデプロイ、ガバナンス確保、コンプライアンス維持
  • C) セキュリティ強化のみ
  • D) 開発速度の向上のみ

正解: B - Service Catalogにより:①CloudFormationテンプレートを「製品」として管理②エンドユーザーが承認済み製品をセルフサービスでデプロイ③IT部門が承認済みの標準構成のみ展開可能にガバナンス確保④タグ付けルールの強制でコスト管理、が実現できます。


Q51〜Q65: 追加問題(短答形式)

Q# 問題 正解
Q51 CodeDeployのデプロイグループでtermination_wait_timeの役割は? 旧インスタンスをデプロイ成功後X分待ってから終了(ロールバック時間の確保)
Q52 SSM Automation のドキュメントタイプ Automation vs Command の違いは? Automation: 複雑なワークフロー(複数ステップ/条件分岐)、Command: EC2上でのスクリプト実行
Q53 CloudFormation スタックを削除しても残るリソースを指定するには? DeletionPolicy: Retain または Snapshot(RDS/EBS)を設定
Q54 Lambda の「プロビジョニングされた同時実行」vs「予約済み同時実行」の違いは? Provisioned: コールドスタートなし(常時ウォーム)、Reserved: 最大同時実行数の上限設定
Q55 CodeBuild でプライベートSubnetのRDSへの接続を可能にするには? CodeBuild VPC設定でプライベートSubnetとSGを指定し、RDSのSGにCodeBuildのSGからの接続許可
Q56 EventBridge の「イベントアーカイブ」の用途は? 過去のイベントを保存し、後でリプレイ(再生)可能にする(例: バグ修正後に過去イベントを再処理)
Q57 AWS CodeArtifact の主な用途は? プライベートnpm/Maven/PyPIリポジトリ。外部パッケージをキャッシュし、内部パッケージを管理
Q58 Systems Manager の「OpsCenter」の用途は? 運用上の問題(OpsItem)の集中管理。GuardDuty/Config/CloudWatch Alarmと統合
Q59 CloudFormation Guard(cfn-guard)の用途は? ポリシーとしてのコード。テンプレートが組織のルールに準拠しているかCI/CDで自動チェック
Q60 CodePipeline のクロスリージョンアクションで必要な設定は? リージョンごとのアーティファクトストアS3バケットとKMSキー。パイプラインへのregionパラメータ指定
Q61 ECS タスク定義の機密情報管理のベストプラクティスは? secrets フィールドでParameter Store/Secrets Managerを参照。環境変数への直接記述は避ける
Q62 CloudTrail で「特定のIAMユーザーの全API呼び出し」を分析するには? CloudTrail + Athena(S3上のログをSQLクエリ)またはCloudWatch Logs Insightsでフィルタリング
Q63 CDK の synth 段階でのセキュリティチェックツールは? CDK Nag(Aspect ベースのルールチェック。NIST/CIS等のコンプライアンスルールをCDKレベルで検証)
Q64 CodeBuild で Docker ビルドを実行する際に必要な設定は? privileged: true モードを有効化(Docker-in-Dockerに必要)
Q65 Organizations の委任管理者(Delegated Administrator)の用途は? 管理アカウント以外のメンバーアカウントに特定サービス(Security Hub/GuardDuty等)の組織管理を委任

DOP-C02 学習戦略と30日プラン

学習ロードマップ

Week 1: CI/CDとIaC基礎
  Day 1-2:  CodePipeline/CodeBuild/CodeDeploy の構成と設定
  Day 3-4:  CloudFormation(StackSets/カスタムリソース/変更セット)
  Day 5-6:  AWS CDK 基礎と高度な使い方
  Day 7:    ハンズオン: マルチアカウントパイプライン構築

Week 2: 自動化とモニタリング  
  Day 8-9:  SSM(Automation/Patch Manager/Session Manager)
  Day 10-11: CloudWatch(カスタムメトリクス/Composite Alarm/Container Insights)
  Day 12-13: EventBridge + Step Functions
  Day 14:   ハンズオン: 自動修復パイプライン

Week 3: セキュリティとコンプライアンス
  Day 15-16: AWS Config(Conformance Pack/自動修復)
  Day 17-18: Security Hub + GuardDuty + Macie + Inspector
  Day 19-20: Organizations(SCP/OU設計)
  Day 21:   ハンズオン: セキュリティベースライン自動化

Week 4: 高可用性と仕上げ
  Day 22-24: 模擬試験(65問×2回)
  Day 25-27: 弱点分野の補強
  Day 28-30: 直前チェックリストの確認

DOP-C02 最終チェックリスト

CI/CD

  • [ ] CodePipeline のクロスアカウントデプロイ設定(IAMロール連携)
  • [ ] CodeBuild buildspec.yml の全セクション(phases/artifacts/reports)
  • [ ] CodeDeploy の全デプロイ設定(In-Place/Blue-Green/Canary/Linear/AllAtOnce)
  • [ ] Lambda/ECS/EC2 それぞれのデプロイ方法の違い
  • [ ] appspec.yml のライフサイクルフック(BeforeInstall〜AfterAllowTraffic)

IaC

  • [ ] CloudFormation StackSets でのマルチアカウントデプロイ設定
  • [ ] CloudFormation カスタムリソース(Lambda/SNS)の実装
  • [ ] CDK の construct レベル(L1/L2/L3)の違い
  • [ ] cdk diff と変更セットの関係
  • [ ] Terraform AWS Provider との CloudFormation の使い分け

自動化

  • [ ] SSM の全サービス(Automation/Session Manager/Patch Manager/Distributor/OpsCenter)
  • [ ] EventBridge のイベントバス、ルール、スケジューラーの設定
  • [ ] Step Functions の全ステートタイプとエラーハンドリング
  • [ ] 自動修復パターン(Config Rule → SSM Automation)

モニタリング

  • [ ] CloudWatch Composite Alarm の設計
  • [ ] X-Ray のサービスマップとトレース設定
  • [ ] CloudWatch Logs Insights クエリ構文
  • [ ] Container Insights(ECS/EKS)の設定

セキュリティ

  • [ ] SCP の設計(条件キーによる制限)
  • [ ] Security Hub の統合(GuardDuty/Inspector/Macie等)
  • [ ] Config Conformance Pack の設定と自動修復
  • [ ] IAM Access Analyzer の検出と対処

DOP-C02 AWS Certified DevOps Engineer Professional 完全ガイド完了


Terraform と AWS の統合

Terraform を使ったAWSインフラ管理

# main.tf - ECS Fargateサービスの完全定義
terraform {
  required_version = ">= 1.5.0"
  
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  
  # Terraform State の S3 バックエンド
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "production/ecs/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    kms_key_id     = "arn:aws:kms:ap-northeast-1:123456789:key/key-id"
    dynamodb_table = "terraform-state-lock"  # State ロック
  }
}

provider "aws" {
  region = var.aws_region
  
  default_tags {
    tags = {
      Environment = var.environment
      Project     = var.project_name
      ManagedBy   = "Terraform"
    }
  }
}

# ECS タスク定義
resource "aws_ecs_task_definition" "app" {
  family                   = "${var.app_name}-task"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = var.task_cpu
  memory                   = var.task_memory
  execution_role_arn       = aws_iam_role.ecs_task_execution.arn
  task_role_arn            = aws_iam_role.ecs_task.arn
  
  container_definitions = jsonencode([
    {
      name  = var.app_name
      image = "${aws_ecr_repository.app.repository_url}:${var.image_tag}"
      
      portMappings = [
        {
          containerPort = 8080
          protocol      = "tcp"
        }
      ]
      
      environment = [
        { name = "ENVIRONMENT", value = var.environment },
        { name = "DB_HOST",     value = aws_rds_cluster.main.endpoint }
      ]
      
      secrets = [
        {
          name      = "DB_PASSWORD"
          valueFrom = aws_secretsmanager_secret.db_password.arn
        }
      ]
      
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          "awslogs-group"         = "/ecs/${var.app_name}"
          "awslogs-region"        = var.aws_region
          "awslogs-stream-prefix" = "ecs"
        }
      }
      
      healthCheck = {
        command     = ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
        interval    = 30
        timeout     = 5
        retries     = 3
        startPeriod = 60
      }
    }
  ])
}

# ECS サービス
resource "aws_ecs_service" "app" {
  name            = "${var.app_name}-service"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = var.desired_count
  launch_type     = "FARGATE"
  
  network_configuration {
    subnets         = var.private_subnet_ids
    security_groups = [aws_security_group.ecs_tasks.id]
  }
  
  load_balancer {
    target_group_arn = aws_lb_target_group.app.arn
    container_name   = var.app_name
    container_port   = 8080
  }
  
  # Blue/Green デプロイ設定(CodeDeploy)
  deployment_controller {
    type = "CODE_DEPLOY"
  }
  
  lifecycle {
    ignore_changes = [task_definition, desired_count]  # CodeDeployが管理
  }
  
  depends_on = [aws_lb_listener.app]
}

Terraform CI/CD パイプライン

# .github/workflows/terraform.yml
name: Terraform CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  id-token: write  # OIDC 認証に必要
  contents: read
  pull-requests: write

jobs:
  terraform-plan:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789:role/TerraformDeployRole
          aws-region: ap-northeast-1
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.6.0
      
      - name: Terraform Init
        run: terraform init
      
      - name: Terraform Format Check
        run: terraform fmt -check -recursive
      
      - name: Terraform Validate
        run: terraform validate
      
      - name: Terraform Plan
        id: plan
        run: terraform plan -out=tfplan -no-color
        continue-on-error: true
      
      - name: Comment Plan on PR
        uses: actions/github-script@v7
        if: github.event_name == 'pull_request'
        with:
          script: |
            const output = `
            #### Terraform Plan 結果
            \`\`\`
            ${{ steps.plan.outputs.stdout }}
            \`\`\`
            `;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            });
  
  terraform-apply:
    runs-on: ubuntu-latest
    needs: terraform-plan
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    environment: production  # 手動承認環境
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789:role/TerraformDeployRole
          aws-region: ap-northeast-1
      
      - name: Terraform Apply
        run: terraform apply -auto-approve tfplan

AWS Control Tower とランディングゾーン

Control Tower の概要

Control Tower アーキテクチャ
┌────────────────────────────────────────────────────────────────┐
│  Management Account                                            │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  AWS Control Tower                                        │  │
│  │  ・ランディングゾーンのセットアップ                         │  │
│  │  ・ガードレール(予防的/探偵的)の管理                      │  │
│  │  ・Account Vending Machine                               │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                │
│  ┌────────────────────┐  ┌────────────────────┐               │
│  │  Log Archive Account│  │  Audit Account      │               │
│  │  (全CloudTrail ログ)│  │  (セキュリティ監査用)│               │
│  └────────────────────┘  └────────────────────┘               │
│                                                                │
│  Organizational Units (OU)                                    │
│  ├── Security OU                                              │
│  │    └── Log Archive, Audit                                  │
│  ├── Workloads OU                                             │
│  │    ├── Production Account                                  │
│  │    └── Staging Account                                     │
│  └── Sandbox OU                                               │
│       └── Dev/Test Accounts                                   │
└────────────────────────────────────────────────────────────────┘

Control Tower ガードレール

ガードレールタイプ 仕組み
予防的(Preventive) SCP で即座にブロック S3 バケットへの公開アクセスを禁止
探偵的(Detective) Config Rule で違反を検出・通知 ルートアカウントMFA未設定を検出
Mandatory 常に有効(無効化不可) CloudTrail 有効化必須
Strongly Recommended 強く推奨(任意) S3 MFA Delete 有効化推奨
Elective オプション(任意) EC2インスタンスのIMDSv2強制
# Account Factory (Service Catalog経由でのアカウント作成自動化)
import boto3

service_catalog = boto3.client('servicecatalog')

# Control Tower Account Vending Machine 経由で新規アカウント作成
response = service_catalog.provision_product(
    ProductId='prod-xxxxxxxxxxxx',  # Account Factory 製品ID
    ProvisioningArtifactId='pa-xxxxxxxxxxxx',
    ProvisionedProductName='new-workload-account-001',
    ProvisioningParameters=[
        {'Key': 'AccountName', 'Value': 'my-new-workload-account'},
        {'Key': 'AccountEmail', 'Value': 'aws-account-001@company.com'},
        {'Key': 'ManagedOrganizationalUnit', 'Value': 'Workloads'},
        {'Key': 'SSOUserEmail', 'Value': 'admin@company.com'},
        {'Key': 'SSOUserFirstName', 'Value': 'Admin'},
        {'Key': 'SSOUserLastName', 'Value': 'User'},
    ]
)

Amazon EKS 高度な運用

EKS でのCI/CD最適化

# Kubernetes Deployment(Blue/Green対応)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
  labels:
    app: api-server
    version: v2.0.0
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-server
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1         # 最大で1つ余分に起動
      maxUnavailable: 0   # 常に全 replicas を維持
  template:
    metadata:
      labels:
        app: api-server
        version: v2.0.0
    spec:
      containers:
        - name: api-server
          image: 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/api-server:v2.0.0
          
          # リソース制限
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          
          # ヘルスチェック
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          
          # 環境変数(Secrets Manager連携)
          env:
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
      
      # Graceful Shutdown
      terminationGracePeriodSeconds: 30
      
      # トポロジー分散(AZ間分散)
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: api-server

---
# Pod Disruption Budget(PDB)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-server-pdb
spec:
  minAvailable: 2  # 常に最低2Podを維持
  selector:
    matchLabels:
      app: api-server

---
# Horizontal Pod Autoscaler (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-server-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-server
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

EKS Fargate プロファイル

import boto3

eks = boto3.client('eks')

# Fargate プロファイル作成(特定namespaceのPodsをFargateで実行)
response = eks.create_fargate_profile(
    clusterName='production-cluster',
    fargateProfileName='app-fargate-profile',
    podExecutionRoleArn='arn:aws:iam::123456789:role/EKSFargatePodExecutionRole',
    subnets=['subnet-private-1a', 'subnet-private-1c'],
    selectors=[
        {
            'namespace': 'production',
            'labels': {'compute-type': 'fargate'}
        },
        {
            'namespace': 'monitoring'
        }
    ],
    tags={
        'Environment': 'Production',
        'ManagedBy': 'Terraform'
    }
)

AWS Proton によるサービステンプレート管理

Proton の概要

AWS Proton はマイクロサービスの標準インフラテンプレートを管理するサービスです。

Proton アーキテクチャ
┌────────────────────────────────────────────────────────────────┐
│  Platform Team(インフラエンジニア)                              │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  AWS Proton                                               │  │
│  │  ├── 環境テンプレート(VPC/ECS Cluster/RDS)              │  │
│  │  └── サービステンプレート(ECS Service/Lambda Function)  │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                │
│  App Team(アプリ開発者)                                        │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  承認済みテンプレートからセルフサービスでデプロイ            │  │
│  │  ・ECSサービステンプレートv2を選択 → パラメータ入力 → デプロイ│  │
│  │  ・インフラの詳細知識不要                                   │  │
│  └──────────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────────┘

試験対策 重要サービス比較

デプロイ方法比較マトリクス

デプロイ方法 サービス ダウンタイム ロールバック速度 コスト
In-Place(Rolling) CodeDeploy EC2 短時間あり 遅い(再デプロイ)
Blue/Green CodeDeploy EC2/ECS/Lambda ゼロ 高速(切り戻し) 高(2環境)
Canary CodeDeploy Lambda/ECS ゼロ 高速 中(一時的)
Linear CodeDeploy Lambda/ECS ゼロ 高速 中(一時的)
Rolling with extra batch Elastic Beanstalk ゼロ 中(+1バッチ)
Immutable Elastic Beanstalk ゼロ 高速 高(2倍)

CloudFormation vs Terraform vs CDK 比較

項目 CloudFormation Terraform CDK
言語 YAML/JSON HCL TypeScript/Python/Java等
マルチクラウド AWSのみ マルチクラウド対応 AWSのみ
State管理 AWS管理(無料) S3+DynamoDB(手動) CloudFormation経由
抽象化 低(リソースレベル) 中(モジュール) 高(L3 Construct)
ドリフト検出 あり terraform plan CloudFormation経由
Import importブロック terraform import cdk import
試験での重要度 最重要 参考程度 重要

付録: DOP-C02 頻出CLIコマンド

# CodePipeline
aws codepipeline get-pipeline --name MyPipeline
aws codepipeline start-pipeline-execution --name MyPipeline
aws codepipeline list-pipeline-executions --pipeline-name MyPipeline
aws codepipeline get-pipeline-execution --pipeline-name MyPipeline --pipeline-execution-id <id>

# CloudFormation
aws cloudformation create-stack \
  --stack-name my-stack \
  --template-file template.yaml \
  --parameters ParameterKey=Env,ParameterValue=prod \
  --capabilities CAPABILITY_NAMED_IAM

aws cloudformation create-change-set \
  --stack-name my-stack \
  --template-file new-template.yaml \
  --change-set-name my-change-set

aws cloudformation describe-change-set \
  --stack-name my-stack \
  --change-set-name my-change-set

aws cloudformation execute-change-set \
  --stack-name my-stack \
  --change-set-name my-change-set

# CloudFormation StackSets
aws cloudformation create-stack-set \
  --stack-set-name security-baseline \
  --template-body file://security.yaml

aws cloudformation create-stack-instances \
  --stack-set-name security-baseline \
  --deployment-targets OrganizationalUnitIds=ou-xxxx-xxxxxxxx \
  --regions us-east-1 ap-northeast-1

# SSM
aws ssm start-session --target i-0123456789abcdef0
aws ssm send-command \
  --document-name AWS-RunShellScript \
  --targets "Key=tag:Environment,Values=Production" \
  --parameters commands='["df -h", "free -m"]'

aws ssm describe-instance-information \
  --filters "Key=PingStatus,Values=Online"

# CDK
cdk ls                      # スタック一覧
cdk synth                   # CloudFormationテンプレート生成
cdk diff                    # 差分確認
cdk deploy --all            # 全スタックデプロイ
cdk destroy --all           # 全スタック削除
cdk bootstrap               # CDKツールキット初期化

DOP-C02 AWS Certified DevOps Engineer Professional 完全学習ガイド(最終版)


追加模擬問題セット(DOP-C02)

高度なシナリオ問題 20問

Q1. ある企業がCodePipelineを使っているが、CodeBuildのビルドジョブが毎回最初から依存関係をインストールするため時間がかかっている。最も効果的な改善策は?

  • A) より大きいインスタンスタイプを使用する
  • B) CodeBuildのキャッシュ(S3またはローカル)を設定してnpm/pip依存関係をキャッシュ
  • C) CodeBuildを並列実行する
  • D) Lambdaでビルドする

正解: B - CodeBuildのキャッシュ設定でS3またはローカルキャッシュを使用し、node_modules.pipなどを再利用することでビルド時間を大幅に短縮できます。S3キャッシュはビルドファームをまたいで共有可能です。


Q2. ECSサービスのBlue/Greenデプロイで、デプロイ後のメトリクスが悪化した場合に自動ロールバックするには?

  • A) Lambda関数で手動監視
  • B) CodeDeployのアラーム設定(CloudWatch Alarm)でデプロイ失敗条件を定義し自動ロールバック
  • C) Auto Scalingグループのヘルスチェックのみ
  • D) Route 53 ヘルスチェック

正解: B - CodeDeployのDeploymentGroupにautoRollbackConfigurationalarmsを設定します。指定したCloudWatch Alarmが発火した場合(5xx増加、レイテンシ悪化等)、自動的に旧バージョンにロールバックされます。


Q3. 組織全体の全アカウントで「S3バケットへのパブリックACL付与を禁止」を強制するSCPは?

  • A) IAMポリシーで設定
  • B) S3ブロックパブリックアクセス設定を全アカウントで手動設定
  • C) SCP で s3:PutBucketAcls3:PutObjectAcl に Condition: StringLike: s3:x-amz-acl: public で Deny
  • D) Config Ruleのみで対応

正解: C - SCPのDeny文でs3:PutBucketAcls3:PutObjectAclに対してpublicを含むACLの設定を禁止します。これにより全メンバーアカウントでパブリックACLの設定が不可能になります。


Q4. マルチリージョンでActive/Activeアーキテクチャを実現する際のDynamoDBの設定は?

  • A) 各リージョンで独立したテーブルを作成
  • B) DynamoDB Global Tables で複数リージョンにアクティブ-アクティブのレプリケーション
  • C) DynamoDB Streams でカスタムレプリケーション
  • D) S3でバックアップして手動復元

正解: B - DynamoDB Global Tables は指定したリージョン間で双方向の自動レプリケーションを提供します。各リージョンのアプリが最寄りのレプリカに書き込み・読み込みができるActive/Activeパターンを実現します。競合は「Last Write Wins」で解決されます。


Q5. CodePipelineの失敗をチームのSlackチャンネルに通知する最もシンプルな構成は?

  • A) Lambda関数でSlack Webhookを呼び出す
  • B) CodePipeline → EventBridge → AWS Chatbot → Slack
  • C) CloudWatch Alarm → SNS → Eメール
  • D) CodeBuildの出力をSlackに送る

正解: B - EventBridgeでCodePipelineのFAILEDイベントをキャッチし、AWS ChatbotのSlack統合に送ることで、コードなしでSlack通知が実現できます。Lambda実装より管理が簡単です。


Q6. CloudFormationスタックの更新で特定のリソースを「更新をスキップ」させるには?

  • A) 不可能
  • B) UpdateReplacePolicy を Retain に設定するか、スタックポリシー(Stack Policy)でUPDATEを拒否
  • C) DeletionPolicy のみで制御
  • D) リソースをテンプレートから削除する

正解: B - スタックポリシーでリソースのUpdateアクションを拒否(Deny)することで、誤った更新を防止できます。また特定リソースを別スタックに移動することも選択肢です。


Q7. ECS タスクからS3バケットにアクセスする際のベストプラクティスは?

  • A) タスク定義にAWSアクセスキーを埋め込む
  • B) ECSタスクロール(Task Role)にS3アクセス権限を付与し、SDK の自動認証を活用
  • C) EC2インスタンスロールのみを使用
  • D) 環境変数でアクセスキーを渡す

正解: B - ECSタスクロールはタスクレベルのIAM権限を提供します。アプリケーションはIMDSv2を通じてタスクロールの認証情報を自動取得します。アクセスキーのハードコードより安全で、ローテーション不要です。


Q8. CloudWatch Logs の「メトリクスフィルター」の用途は?

  • A) ログの削除フィルタリング
  • B) ログのテキストパターンをCloudWatchメトリクスに変換(例: ERRORログ数をメトリクス化してアラーム設定)
  • C) ログの暗号化
  • D) ログのアーカイブ設定

正解: B - メトリクスフィルターはロググループのテキストパターンを監視し、マッチしたログ数をCloudWatchメトリクスとして記録します。例:ERRORが含まれるログ数をAppErrorsメトリクスとして集計し、閾値超過でアラームを発生させます。


Q9. AWS CloudShell の主な用途は?

  • A) 重い計算処理
  • B) ブラウザからCLI操作。認証設定不要、AWS CLIが事前インストール済み
  • C) Lambdaのデバッグ
  • D) EC2インスタンスへのSSH接続のみ

正解: B - CloudShellはコンソールにログイン済みのユーザーの権限でそのまま使えるブラウザベースのシェルです。一時的なCLI操作やスクリプト実行に便利。ホームディレクトリ(1GB)は永続化されます。


Q10. Lambda 関数の「デッドレターキュー(DLQ)」の用途は?

  • A) Lambda関数の高速化
  • B) 非同期呼び出しで処理失敗したイベントをSQS/SNSに保存して後で再処理・分析
  • C) 同期呼び出しのエラーハンドリング
  • D) Lambda関数のバックアップ

正解: B - 非同期呼び出し(S3イベント、SNS等)で Lambda が2回リトライしても失敗した場合、イベントをDLQ(SQSキューまたはSNSトピック)に送信します。失敗したイベントの分析・再処理に使用します。


Q11. CodeDeploy でEC2インスタンスにエージェントを自動インストールする方法は?

  • A) 手動インストールのみ
  • B) EC2のUser Data スクリプトまたはSSM Distributorを使用して自動インストール
  • C) AMIに含める方法のみ
  • D) CloudFormation Init のみ

正解: B - EC2起動時のUserDataでaws codedeploy-installコマンドを実行するか、SSM Distributor でAWSCodeDeployAgentパッケージを自動インストールできます。Auto Scaling Groupと組み合わせた自動登録が一般的です。


Q12. AWS CloudFormation での「待機条件(Wait Condition)」の用途は?

  • A) タイムアウト設定のみ
  • B) EC2/ECS等のリソースが初期化完了したことをシグナルするまでスタック作成を一時停止
  • C) ループ処理の実装
  • D) 並列デプロイの制御

正解: B - WaitConditionはEC2インスタンスのブートストラップスクリプト完了等を待つために使います。インスタンスがスクリプト完了後にcfn-signalコマンドでシグナルを送ると、スタックの次のステップが進みます。


Q13. SSM Parameter Store の「SecureString」タイプで使用される暗号化方式は?

  • A) SSL/TLSのみ
  • B) AWS KMS(デフォルトはaws/ssm マネージドキー、またはカスタムKMSキー)
  • C) AES-128
  • D) S3 Server-Side Encryption

正解: B - SecureStringタイプのパラメータはAWS KMSで暗号化されます。デフォルトではaws/ssmマスターキーを使用しますが、カスタムKMSキーを指定することで特定のIAMポリシーやCloudTrail追跡が可能になります。


Q14. AWS Organizations の「Service Control Policy(SCP)」でよく使われるセキュリティパターンは?

  • A) ポリシーは1種類のみ
  • B) 特定リージョン以外でのリソース作成禁止、特定サービスの完全禁止、ルートユーザーのアクション禁止
  • C) IAMユーザー作成の禁止のみ
  • D) S3操作の制限のみ

正解: B - SCPの主要パターン:①aws:RequestedRegion条件でリージョン制限②Deny: ec2:で特定OU全体でEC2禁止③Deny: *: Condition: StringLike: aws:PrincipalArn: arn:aws:iam::*:rootでルートユーザー操作禁止④Deny: organizations:Leaveで組織からの脱退禁止。


Q15. CodePipeline で特定の変更(特定ファイル/ディレクトリのみ)でパイプライン起動をトリガーする方法は?

  • A) 不可能(全変更でトリガー)
  • B) EventBridge のCodeCommitイベントフィルターで変更されたファイルパスを条件に設定
  • C) CodeBuildのみで判定
  • D) Lambda関数のみで実装可能

正解: B - EventBridge ルールの detail.referenceName(ブランチ名)と detail.changes.changeType/fileName でフィルタリングできます。ただし CodeCommit 側のEventBridgeの完全なファイルパスフィルタリングはLambdaで詳細判断が必要な場合もあります。


Q16. EKS クラスターのアップグレードのベストプラクティスは?

  • A) 一度に最新バージョンにジャンプ
  • B) コントロールプレーン → ノードグループ の順序で、1マイナーバージョンずつアップグレード
  • C) ノードグループを先にアップグレード
  • D) 同時アップグレード

正解: B - EKSアップグレードの手順:①コントロールプレーンを1マイナーバージョン上げる②マネージドノードグループを順次ローリングアップデート③Add-on(kube-proxy/CoreDNS/VPC CNI)をアップデート。Kubernetesは2バージョン以上の差分はサポート外のため1つずつが必須です。


Q17. AWS Fargate タスクで外部シークレット(Secrets Manager)を安全に注入する方法は?

  • A) 環境変数に直接記述
  • B) タスク定義のsecretsフィールドでSecretsManagerのARNを参照し、タスク起動時に自動注入
  • C) Lambda関数で注入
  • D) S3から読み込む

正解: B - タスク定義のsecretsフィールドに{"name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:..."}を設定します。タスク起動時にECSがSecretsManagerから値を取得して環境変数に注入します。タスク実行ロールにSecretsManagerのアクセス権限が必要です。


Q18. CloudFormation カスタムリソースで cfnresponse モジュールが必要な理由は?

  • A) Lambda関数の実行を高速化する
  • B) CloudFormationへの処理完了シグナル(SUCCESS/FAILED)をPreSigned URLに送信するため
  • C) エラーログの収集
  • D) S3へのアーティファクト保存

正解: B - CloudFormationカスタムリソースはLambda関数の戻り値でなく、PreSignedURL(ResponseURL)への HTTP PUT で完了を通知します。cfnresponse.send()がこのPUT処理を担います。通知されないと CloudFormation はタイムアウト待機します。


Q19. AWS Config でリソースの変更履歴を確認できる期間は?

  • A) 7日間
  • B) デフォルトで7年(2,557日)まで保存(設定により変更可能)
  • C) 1年
  • D) 30日間のみ

正解: B - AWS Config はデフォルトで変更履歴を7年保持します(サービス上限)。コンプライアンス要件に応じてS3へのエクスポートとLife Cycle Policyで長期保存も可能です。


Q20. Elastic Beanstalk でカスタム設定(.ebextensions)の用途は?

  • A) アプリケーションコードのデプロイのみ
  • B) EC2インスタンスのOS設定、パッケージインストール、環境変数設定、Nginx/Apacheカスタマイズ
  • C) ロードバランサーの設定のみ
  • D) データベースの設定のみ

正解: B - .ebextensions/ディレクトリに*.configファイルを置くことで、EC2インスタンスの設定をコードで管理できます。packages(yum/apt)、files(ファイル作成)、commands(コマンド実行)、services(サービス管理)、option_settings(環境変数)が設定可能です。


重要サービス活用パターン集

パターン1: GitOps with ArgoCD on EKS

# ArgoCD Application リソース
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-app
  namespace: argocd
spec:
  project: default
  
  source:
    repoURL: https://github.com/myorg/k8s-manifests
    targetRevision: main
    path: production/api-server
  
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  
  syncPolicy:
    automated:
      prune: true    # Git削除に追従
      selfHeal: true # 手動変更を検知してGitに戻す
    syncOptions:
      - CreateNamespace=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

パターン2: Canary デプロイ with Feature Flags

# AWS AppConfig を使ったFeature Flags
import boto3
import json

appconfig = boto3.client('appconfig')

# フィーチャーフラグの取得
response = appconfig.get_configuration(
    Application='MyApp',
    Environment='Production',
    Configuration='FeatureFlags',
    ClientId='my-service-instance'
)

config = json.loads(response['Content'].read())
enable_new_checkout = config.get('enableNewCheckout', False)

if enable_new_checkout:
    # 新しいチェックアウトフロー
    result = new_checkout_service.process(order)
else:
    # 既存のチェックアウトフロー
    result = legacy_checkout_service.process(order)

パターン3: インフラのコンプライアンス自動化

コンプライアンス自動修復フロー
┌─────────────────────────────────────────────────────────────┐
│  1. Config Rule 評価                                         │
│     「S3バケットにパブリックアクセスが設定されている」を検知     │
│                          ↓                                  │
│  2. EventBridge ルール                                        │
│     Config ルールのNON_COMPLIANTイベントを検知               │
│                          ↓                                  │
│  3. SSM Automation ドキュメント自動起動                        │
│     AWS-DisableS3BucketPublicReadWrite を実行               │
│                          ↓                                  │
│  4. Lambda 通知                                              │
│     Slack/PagerDuty に修復完了を通知                          │
│                          ↓                                  │
│  5. Config Rule 再評価                                        │
│     COMPLIANT に変更されたことを確認                           │
└─────────────────────────────────────────────────────────────┘

DOP-C02 最終まとめ

試験で必ず出る重要概念トップ25

  1. CodeDeploy Blue/Green: Hookの順序(BeforeInstall→AfterInstall→AfterAllowTestTraffic→BeforeAllowTraffic→AfterAllowTraffic)
  2. CodePipeline マルチアカウント: CrossAccount IAMロールのchainパターン
  3. CloudFormation カスタムリソース: cfnresponse + PreSignedURL
  4. CloudFormation StackSets: Organizational/Self-managed、FailureTolerance設定
  5. CDK Pipelines: Self-mutating pipeline
  6. SSM Session Manager: ポート開放不要、全ログをCloudTrail/S3に記録
  7. EventBridge: イベントバス3種(Default/Partner/Custom)、クロスアカウント
  8. Step Functions: Standard vs Express、全ステートタイプ
  9. CloudWatch Composite Alarm: AND/ORロジックでアラーム疲れ防止
  10. X-Ray: サービスマップ、アノテーション(インデックス化)vsメタデータ
  11. AWS Config: Change Triggered vs Periodic、Conformance Pack
  12. Security Hub: ASFF形式、自動アクション設定
  13. Organizations SCP: 最大権限の制限、条件キー活用
  14. Control Tower: ランディングゾーン、予防的/探偵的ガードレール
  15. CodeBuild キャッシュ: S3キャッシュ vs ローカルキャッシュ
  16. ECS Blue/Green: ALBの本番リスナー/テストリスナーの切り替え
  17. Lambda エイリアス: Canary/Linearトラフィックシフト
  18. ECR Enhanced Scan: Amazon Inspector v2による継続的スキャン
  19. Auto Scaling 予測スケーリング: MLで事前スケールアウト
  20. Route 53 フェイルオーバー: Primary/SecondaryとヘルスチェックIDの設定
  21. DynamoDB Global Tables: Active-Active、Last Write Wins
  22. ElastiCache Redis Cluster Mode: スケールアウト(シャーディング)
  23. Kinesis Data Streams: シャードのスケーリング(Re-sharding)
  24. CloudFront + Lambda@Edge: レスポンスヘッダー操作/認証
  25. AWS Backup: Organizations全体へのバックアップポリシー適用

DOP-C02 AWS Certified DevOps Engineer Professional 完全学習ガイド 完了


第7章: インフラコード・GitOps実践

7.1 AWS CDK 高度な設計

import aws_cdk as cdk
from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_ecs_patterns as ecs_patterns,
    aws_rds as rds,
    aws_secretsmanager as secretsmanager,
    aws_codepipeline as codepipeline,
    aws_codepipeline_actions as cp_actions,
    aws_codebuild as codebuild,
    aws_s3 as s3,
    Stack, App, Environment, RemovalPolicy, Duration
)
from constructs import Construct

class MicroserviceStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, 
                 environment: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
        # VPC
        vpc = ec2.Vpc(
            self, 'AppVpc',
            max_azs=3,
            nat_gateways=2 if environment == 'production' else 1,
            subnet_configuration=[
                ec2.SubnetConfiguration(
                    name='Public',
                    subnet_type=ec2.SubnetType.PUBLIC,
                    cidr_mask=24
                ),
                ec2.SubnetConfiguration(
                    name='Private',
                    subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
                    cidr_mask=24
                ),
                ec2.SubnetConfiguration(
                    name='Isolated',
                    subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
                    cidr_mask=24
                )
            ]
        )
        
        # RDS Aurora クラスター
        db_secret = secretsmanager.Secret(
            self, 'DBSecret',
            generate_secret_string=secretsmanager.SecretStringGenerator(
                secret_string_template='{"username": "admin"}',
                generate_string_key='password',
                exclude_characters='"@/\\'
            )
        )
        
        db_cluster = rds.DatabaseCluster(
            self, 'Database',
            engine=rds.DatabaseClusterEngine.aurora_mysql(
                version=rds.AuroraMysqlEngineVersion.VER_3_04_0
            ),
            credentials=rds.Credentials.from_secret(db_secret),
            instances=2 if environment == 'production' else 1,
            instance_props=rds.InstanceProps(
                vpc=vpc,
                vpc_subnets=ec2.SubnetSelection(
                    subnet_type=ec2.SubnetType.PRIVATE_ISOLATED
                ),
                instance_type=ec2.InstanceType.of(
                    ec2.InstanceClass.R7G,
                    ec2.InstanceSize.LARGE if environment == 'production' else ec2.InstanceSize.MEDIUM
                )
            ),
            deletion_protection=environment == 'production',
            removal_policy=RemovalPolicy.SNAPSHOT if environment == 'production' else RemovalPolicy.DESTROY,
            backup=rds.BackupProps(retention=Duration.days(7))
        )
        
        # ECS Fargate サービス
        cluster = ecs.Cluster(
            self, 'EcsCluster',
            vpc=vpc,
            container_insights=True
        )
        
        fargate_service = ecs_patterns.ApplicationLoadBalancedFargateService(
            self, 'AppService',
            cluster=cluster,
            cpu=512,
            memory_limit_mib=1024,
            task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
                image=ecs.ContainerImage.from_registry('nginx:latest'),
                container_port=80,
                secrets={
                    'DB_PASSWORD': ecs.Secret.from_secrets_manager(db_secret, 'password')
                }
            ),
            desired_count=2 if environment == 'production' else 1,
            public_load_balancer=True
        )
        
        # DBへのアクセス許可
        db_cluster.connections.allow_default_port_from(
            fargate_service.service.connections
        )
        
        # Auto Scaling
        scaling = fargate_service.service.auto_scale_task_count(
            min_capacity=2 if environment == 'production' else 1,
            max_capacity=10
        )
        scaling.scale_on_cpu_utilization(
            'CpuScaling',
            target_utilization_percent=70
        )

# CDK Pipeline (自動デプロイパイプライン)
class InfraPipelineStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
        # アーティファクトバケット
        artifact_bucket = s3.Bucket(
            self, 'ArtifactBucket',
            removal_policy=RemovalPolicy.DESTROY,
            encryption=s3.BucketEncryption.S3_MANAGED
        )
        
        pipeline = codepipeline.Pipeline(
            self, 'InfraPipeline',
            artifact_bucket=artifact_bucket,
            cross_account_keys=False
        )
        
        # ソースステージ
        source_output = codepipeline.Artifact()
        pipeline.add_stage(
            stage_name='Source',
            actions=[
                cp_actions.CodeStarConnectionsSourceAction(
                    action_name='GitHubSource',
                    owner='myorg',
                    repo='infrastructure',
                    branch='main',
                    connection_arn='arn:aws:codestar-connections:...',
                    output=source_output
                )
            ]
        )
        
        # CDK Synthステージ
        synth_output = codepipeline.Artifact()
        pipeline.add_stage(
            stage_name='Synth',
            actions=[
                cp_actions.CodeBuildAction(
                    action_name='CDKSynth',
                    project=codebuild.PipelineProject(
                        self, 'SynthProject',
                        build_spec=codebuild.BuildSpec.from_object({
                            'version': '0.2',
                            'phases': {
                                'install': {'commands': ['npm ci']},
                                'build': {'commands': ['npx cdk synth']}
                            },
                            'artifacts': {
                                'base-directory': 'cdk.out',
                                'files': ['**/*']
                            }
                        })
                    ),
                    input=source_output,
                    outputs=[synth_output]
                )
            ]
        )
        
        # Staging デプロイ
        pipeline.add_stage(
            stage_name='DeployStaging',
            actions=[
                cp_actions.CloudFormationCreateUpdateStackAction(
                    action_name='DeployStaging',
                    stack_name='MicroserviceStack-Staging',
                    template_path=synth_output.at_path('MicroserviceStack-Staging.template.json'),
                    admin_permissions=True
                )
            ]
        )
        
        # 手動承認
        pipeline.add_stage(
            stage_name='ApproveProduction',
            actions=[
                cp_actions.ManualApprovalAction(
                    action_name='ApproveProductionDeploy',
                    notification_topic=None
                )
            ]
        )

# CDKアプリエントリーポイント
app = App()

InfraPipelineStack(app, 'InfraPipeline',
    env=Environment(account='123456789012', region='ap-northeast-1')
)

MicroserviceStack(app, 'MicroserviceStack-Staging',
    environment='staging',
    env=Environment(account='111122223333', region='ap-northeast-1')
)

MicroserviceStack(app, 'MicroserviceStack-Production',
    environment='production',
    env=Environment(account='444455556666', region='ap-northeast-1')
)

app.synth()

7.2 AWS CodeArtifact

import boto3
import subprocess

# CodeArtifactドメイン・リポジトリ設定
codeartifact_client = boto3.client('codeartifact', region_name='ap-northeast-1')

def setup_codeartifact():
    # ドメイン作成
    domain = codeartifact_client.create_domain(
        domain='mycompany',
        encryptionKey='arn:aws:kms:ap-northeast-1:123456789012:key/key-id'
    )
    
    # プライベートリポジトリ作成
    private_repo = codeartifact_client.create_repository(
        domain='mycompany',
        repository='private-packages',
        description='Company internal packages'
    )
    
    # パブリックアップストリーム設定(pypi/npm/maven等)
    pypi_upstream = codeartifact_client.create_repository(
        domain='mycompany',
        repository='pypi-store',
        externalConnections=['public:pypi'],
        description='PyPI proxy'
    )
    
    # プライベートリポジトリにアップストリームを追加
    codeartifact_client.update_repository(
        domain='mycompany',
        repository='private-packages',
        upstreams=[{'repositoryName': 'pypi-store'}]
    )
    
    return domain, private_repo

def get_auth_token_for_pip():
    """CI/CDパイプラインでPyPIとして使用するための認証トークン取得"""
    
    response = codeartifact_client.get_authorization_token(
        domain='mycompany',
        domainOwner='123456789012',
        durationSeconds=3600
    )
    
    endpoint = codeartifact_client.get_repository_endpoint(
        domain='mycompany',
        domainOwner='123456789012',
        repository='private-packages',
        format='pypi'
    )
    
    return {
        'token': response['authorizationToken'],
        'endpoint': endpoint['repositoryEndpoint']
    }

# CodeBuildでCodeArtifactを使用するbuildspec
BUILDSPEC_WITH_CODEARTIFACT = """
version: 0.2
phases:
  pre_build:
    commands:
      - pip install codeartifact-login
      - aws codeartifact login --tool pip --domain mycompany --repository private-packages
  build:
    commands:
      - pip install -r requirements.txt  # CodeArtifactからインストール
      - python setup.py build
  post_build:
    commands:
      - twine upload --repository codeartifact dist/*  # CodeArtifactに公開
"""

第8章: 高度なモニタリング・可観測性

8.1 OpenTelemetry と AWS Distro

# AWS Distro for OpenTelemetry (ADOT) 設定
# ECSタスク定義でサイドカーコンテナとして追加

OTEL_COLLECTOR_CONFIG = """
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
  prometheus:
    config:
      scrape_configs:
        - job_name: 'myapp'
          scrape_interval: 15s
          static_configs:
            - targets: ['localhost:8080']

processors:
  batch:
    timeout: 1s
    send_batch_size: 50
  resource:
    attributes:
      - key: service.name
        value: "my-service"
        action: insert
      - key: deployment.environment
        value: "production"
        action: insert

exporters:
  awsxray:
    region: ap-northeast-1
    local_mode: false
  awsemf:
    region: ap-northeast-1
    log_group_name: '/metrics/myapp'
    log_stream_name: 'otel-{TaskId}'
    namespace: 'MyApp'
    dimension_rollup_option: 'ZeroAndSingleDimensionRollup'
  prometheusremotewrite:
    endpoint: "https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-xxx/api/v1/remote_write"
    auth:
      authenticator: sigv4auth
  logging:
    loglevel: warn

extensions:
  health_check: {}
  pprof: {}
  zpages: {}
  sigv4auth:
    region: ap-northeast-1
    service: aps

service:
  extensions: [health_check, pprof, zpages, sigv4auth]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [resource, batch]
      exporters: [awsxray]
    metrics:
      receivers: [otlp, prometheus]
      processors: [resource, batch]
      exporters: [awsemf, prometheusremotewrite]
"""

# Python アプリでのOTel計装
from opentelemetry import trace, metrics
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.flask import FlaskInstrumentor

def setup_observability():
    # トレース設定
    provider = TracerProvider()
    otlp_exporter = OTLPSpanExporter(endpoint="http://localhost:4317")
    provider.add_span_processor(BatchSpanProcessor(otlp_exporter))
    trace.set_tracer_provider(provider)
    
    # 自動計装
    BotocoreInstrumentor().instrument()  # boto3の全APIコールをトレース
    RequestsInstrumentor().instrument()  # HTTPリクエストをトレース
    FlaskInstrumentor().instrument()     # Flaskエンドポイントをトレース
    
    return trace.get_tracer(__name__)

8.2 Amazon Managed Grafana + Prometheus

import boto3

# Amazon Managed Service for Prometheus (AMP) 設定
amp_client = boto3.client('amp', region_name='ap-northeast-1')

def create_prometheus_workspace():
    response = amp_client.create_workspace(
        alias='production-metrics',
        tags={'Environment': 'production'}
    )
    workspace_id = response['workspaceId']
    
    # アラートマネージャー設定
    alert_manager_config = """
alertmanager_config: |
  route:
    group_by: ['alertname', 'job']
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 3h
    receiver: 'pagerduty'
  receivers:
  - name: 'pagerduty'
    pagerduty_configs:
    - routing_key: 'your-pagerduty-key'
      description: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'
"""
    
    amp_client.put_alert_manager_definition(
        workspaceId=workspace_id,
        data=alert_manager_config.encode()
    )
    
    return workspace_id

# Amazon Managed Grafana ワークスペース
def create_grafana_workspace():
    grafana_client = boto3.client('grafana', region_name='ap-northeast-1')
    
    response = grafana_client.create_workspace(
        accountAccessType='CURRENT_ACCOUNT',
        authenticationProviders=['AWS_SSO'],
        permissionType='SERVICE_MANAGED',
        workspaceName='ProductionMetrics',
        workspaceDataSources=['PROMETHEUS', 'CLOUDWATCH', 'XRAY'],
        workspaceNotificationDestinations=['SNS']
    )
    
    return response['workspace']['id']

模擬試験 セット2(15問)

問題1 CodePipelineのパイプラインでサードパーティのコードレビューツール(SonarQube等)を統合する最適な方法は?

A) CodeBuildステップでコードレビューツールのCLIを実行する B) Lambda関数でSonarQubeのAPIを呼び出し、品質ゲートの合否に基づいてパイプラインを続行/停止 C) CodePipelineではサードパーティツールの統合は不可能 D) SonarQubeをEC2に常時稼働させる必要がある

正解: A/B(複合) 解説: SonarQube統合のパターン: ①CodeBuildフェーズでSonarScanner CLIを実行→SonarQube APIで品質ゲート結果確認→基準未達でビルド失敗②Invoke Action(Lambda)でSonarQube APIを呼び出して品質ゲート評価→失敗時はCodePipelineに失敗ステータスを返す。AWS CodeGuru Reviewerとの統合ならネイティブに対応(Pull Request時に自動レビュー)。


問題2 AWS OpsWorks for Chef AutomateのEOL後、Chef/Puppetの設定管理をAWS上で継続する推奨の代替は?

A) OpsWorks for Chef Automateはまだサポートされている B) AWS Systems Manager State Manager + SSM Document(または既存ツールをEC2に移行してセルフマネージド) C) AWS CodeDeploy D) AWS Elastic Beanstalk

正解: B 解説: OpsWorks EOL(2024年)後の移行先: ①SSM State Manager: デシレッドステート管理(指定された状態を継続的に維持)。SSMドキュメントでChefレシピに相当する設定を定義②セルフマネージドChef/Puppet: EC2やEKS上で独自運用③Ansible: SSM Run Commandと組み合わせてAnisblePlaybookを実行④Terraform/CDKへの移行。


問題3 CloudFormationスタックで発生した「Drift(ドリフト)」をどのように処理すべきですか?

A) ドリフトを無視してスタックを引き続き使用する B) ドリフト検出でCloudFormationテンプレートとの差異を特定し、手動修正するか次のCloudFormationデプロイで上書きする C) スタックを削除して再作成する D) ドリフトはCloudFormationが自動修正する

正解: B 解説: CloudFormation ドリフト対応: detect-stack-driftでドリフト状態の特定→describe-stack-resource-driftsで詳細確認→対応オプション: ①手動でコンソール/CLIから修正(CloudFormationの外で変更された設定を元に戻す)②次回デプロイでCloudFormation定義を優先して上書き③CloudFormationテンプレートを現在のリアル状態に合わせて更新。予防策: SCP/IAMで直接変更を禁止。


問題4 Amazon CloudWatch Syntheticsとサービスのヘルスチェックの違いは?

A) CloudWatch Syntheticsはよりコストが高い B) Syntheticsはユーザー視点でエンドツーエンドのWebフロー(ログイン→商品検索→カート追加等)をシミュレートしてモニタリング。ヘルスチェックは単純なHTTPエンドポイント確認のみ C) ヘルスチェックはリアルタイム、SyntheticsはDaily D) SyntheticsはALBのみ対応

正解: B 解説: CloudWatch Synthetics Canary: Puppeteerベースのヘッドレスブラウザ(NodeJS)でWebフロー全体をE2Eテスト。スクリーンショット、HTTPアーカイブ(HAR)の記録。API Canaryテンプレート(HTTP呼び出し)もサポート。ALBヘルスチェックやRoute 53ヘルスチェックは単純なHTTPステータスのみ確認。Syntheticsは複雑な業務フローの監視に適する。


問題5 Blue/GreenデプロイとCanaryデプロイの主な違いは?

A) Canaryデプロイの方が常に安全 B) Blue/Green: 全トラフィックを一斉に新環境に切り替え(瞬時)。Canary: トラフィックの一部(1-10%)を新バージョンに段階的に移行して問題検出後にロールバックまたは全移行 C) Blue/GreenはEC2のみ対応 D) Canaryデプロイには複数のLoadBalancerが必要

正解: B 解説: デプロイ戦略比較: Blue/Green: 新環境(Green)に全切り替え→問題時はBlueに瞬時ロールバック→コスト2倍。Canary: 段階的移行(例: 1%→10%→100%)→各段階でCloudWatchメトリクスを監視→問題検出で自動ロールバック→本番への影響最小化。Rolling: ずつ置き換え(中間状態あり)。In-Place: 既存インスタンスを直接アップデート(最もリスク高)。


問題6 Elastic Beanstalkの「Immutable」デプロイポリシーの仕組みは?

A) 既存インスタンスを直接更新する B) 新しいオートスケーリンググループに新バージョンのインスタンスを起動し、正常確認後に既存グループと置き換える(元のインスタンスは削除) C) Blue/Greenデプロイと同一の仕組み D) インスタンスのAMIを変更する

正解: B 解説: Elastic Beanstalk デプロイポリシー: All at once(全同時更新→ダウンタイムあり)、Rolling(ずつ更新→部分的ダウン)、Rolling with additional batch(追加バッチ→ダウンタイムなし)、Immutable(新ASGで完全新規→本番影響ゼロ)、Traffic splitting(カナリア)。Immutableは本番に最も安全だがコストが一時的に2倍。


問題7 AWS CloudFormation のAWS::CloudFormation::InitUserDataの違いは?

A) 両方とも同じ機能を提供する B) UserData: EC2起動時に1回だけ実行されるシェルスクリプト。cfn-init(CloudFormation::Init): cfn-hupで設定変更時に再実行可能、成功/失敗をCloudFormationに通知(cfn-signal) C) CloudFormation::InitはWindowsのみ対応 D) UserDataはAWS CDKでのみ使用可能

正解: B 解説: cfn-init vs UserData: UserData: EC2起動時の1回限りのスクリプト実行。結果をCloudFormationに通知しない。cfn-init: CloudFormation::Init セクションに定義した設定(パッケージ、ファイル、サービス)をcfn-initで適用。cfn-signal: 設定完了/失敗をCloudFormationに通知(WaitCondition/CreationPolicy)。cfn-hup: メタデータ変更を検知して自動再実行(設定の継続的適用)。


問題8 AWS Proton の主な目的は?

A) CloudFormationテンプレートのバージョン管理 B) プラットフォームエンジニアリングチームが定義したインフラテンプレートと設定をアプリ開発チームにセルフサービスで提供し、一貫性を確保 C) EKSクラスターの自動管理 D) コンテナレジストリの管理

正解: B 解説: AWS Proton: プラットフォームエンジニアリング向けサービス。「環境テンプレート」(VPC、EKSクラスター等のインフラ)と「サービステンプレート」(ECSサービス、Lambda等のアプリ)を定義。開発者はテンプレートから選択してセルフサービスでデプロイ。CloudFormation/Terraformテンプレートとの統合。プラットフォームチームのスケールに有用。


問題9 GitHub ActionsをAWSに安全に統合するための推奨認証方法は?

A) IAMユーザーのアクセスキーをGitHub Secretsに保存する B) GitHub OIDC Provider + IAM RoleでフェデレーションによるAssumeRoleWithWebIdentityを使用 C) Cognitoを使用してGitHubアクターを認証する D) IAMユーザーを作成してCodeStarの権限を付与する

正解: B 解説: GitHub OIDC + AWS IAM: GitHubをIDプロバイダーとしてIAMに登録→IAMロールの信頼ポリシーにGitHub OIDCを指定(リポジトリ・ブランチで条件絞り込み)→GitHub Actionsワークフローでactions/configure-aws-credentialsアクションを使用してAssumeRoleWithWebIdentity→一時的な認証情報を取得。IAMアクセスキーの長期保存が不要でセキュアな統合が実現。


問題10 SRE(Site Reliability Engineering)の「Error Budget」とは何ですか?

A) サービスの年間障害コスト B) SLO(サービスレベル目標)から許容される誤差。99.9%のSLOなら月0.1%(約44分)のエラーが許容範囲(Error Budget) C) ソフトウェアのバグ修正にかけられる予算 D) CloudWatchアラームの閾値

正解: B 解説: SRE Error Budget: SLO(例: 月次99.9%可用性)の達成に対して「消費できる障害時間の許容量」。計算: 1ヶ月×(1-0.999)=約44分。Error Budgetが枯渇したら新機能デプロイを停止し信頼性改善に注力。Error Budgetに余裕があれば積極的な新機能デプロイが許容される。CloudWatch SLO dashboardやAWS Application Signalsで追跡可能。


問題11 AWS CodeGuru Reviewer の主な機能は?

A) コードの実行パフォーマンスのプロファイリング B) AIを使用してPull Request時にコードの問題(セキュリティ脆弱性、非効率なAPIの使用等)を自動検出してレビューコメントを提供 C) コードスタイルのフォーマット修正 D) テストカバレッジの計測

正解: B 解説: CodeGuru Reviewer: ML(Amazon独自)を使用したコードレビューツール。機能: ①セキュリティ脆弱性の検出(硬直化した認証情報、SQLインジェクション等)②非効率なAPIの使用(例: ループ内でS3を呼ぶ非効率なパターン)③デッドコードや潜在的バグ。GitHub/CodeCommit PRに自動コメント。検出カテゴリ: Security、AWS Best Practices、Code Correctness等。


問題12 アプリケーションのMLPredictモデルのパフォーマンス低下を検知するCloudWatchのメトリクス戦略は?

A) CPUとメモリのみ監視する B) カスタムメトリクス(推論レイテンシー、モデル精度、エラー率)+ SageMaker Model Monitor(データドリフト)+ CloudWatchアラームで自動検知 C) ログのみで手動確認する D) X-Rayトレースのみで監視する

正解: B 解説: MLモデル監視ベストプラクティス: ①インフラメトリクス: Lambdaレイテンシー、エラー率(CloudWatch)②モデル品質: カスタムメトリクスで推論結果をPutMetricData→アノマリー検出③データドリフト: SageMaker Model Monitor(入力データ分布変化をCWアラームで通知)④ビジネスメトリクス: 予測による業務指標(例: 推薦クリック率)の変化→CloudWatchダッシュボードで可視化。


問題13 ChatOps(例: Slack + AWS)を実現するための推奨アーキテクチャは?

A) SlackをEC2に常時稼働させる B) API Gateway + Lambda + Slack Webhook(インバウンド)/ Chatbot(アウトバウンド)でCloudWatch/CodePipeline通知をSlackに送信しSlackコマンドでAWS操作 C) SlackのEnterpriseプランのみが可能 D) CloudWatch Logsのみで実現可能

正解: B 解説: ChatOps アーキテクチャ: アウトバウンド(AWS→Slack): AWS Chatbot + SNS→CodePipeline/CodeDeploy/CloudWatchの通知をSlackに転送。インバウンド(Slack→AWS): Slack Slash Command→API Gateway→Lambda→AWSサービス実行(デプロイ承認、SSM Automation実行等)。AWS Chatbotは組み込みでSlack/Teams統合対応。インタラクティブなCloudWatchアラームのアクション対応も可能。


問題14 CI/CDパイプラインのセキュリティとして、シークレットのスキャンを行う統合方法は?

A) CodeBuild環境変数に直接保存する B) AWS CodeGuru Security(ハードコードされた認証情報の検出)+ truffleHog/gitleaks等のシークレットスキャンツールをCodeBuildステップに追加 C) シークレットのスキャンはCodePipelineでは不可能 D) CloudTrailで検出する

正解: B 解説: パイプラインでのシークレットスキャン: ①AWS CodeGuru Security: IAMパターン等のセキュリティ問題を自動検出②pre-commitフック: gitleaks/detect-secretsをローカル開発時に実行③CodeBuildステップ: truffleHogをビルドに追加してGit履歴をスキャン④GitHub Advanced Securityのシークレットスキャニング機能(GitHub使用時)。発見したシークレットは即座にローテーション。


問題15 DevOpsチームのOKR(Objectives and Key Results)として最も適切なDORAメトリクスの組み合わせは?

A) CPU使用率、ストレージ消費量、ネットワーク帯域 B) デプロイ頻度、変更のリードタイム、変更失敗率、サービス復旧時間(MTTR) C) テストカバレッジ率、バグ数、スプリントベロシティ D) 開発者の稼働時間、コミット数、PRのレビュー時間

正解: B 解説: DORAメトリクス(DevOps Research and Assessment): ①デプロイ頻度(Deployment Frequency): 高パフォーマンス=1日複数回②変更のリードタイム(Lead Time for Changes): コードコミット→本番デプロイまでの時間③変更失敗率(Change Failure Rate): デプロイ後に障害が発生する割合④サービス復旧時間(MTTR: Mean Time to Recovery)。AWS Application Signals + CodePipeline で自動追跡可能。


DOP試験 最終チェックリスト

ドメイン1: SDLC自動化 (22%)

  • [ ] CodePipeline(全アクションタイプ、クロスアカウント)
  • [ ] CodeBuild(buildspec.yml、キャッシュ、テストレポート)
  • [ ] CodeDeploy(EC2/ECS/Lambda、AppSpec、ライフサイクルフック)
  • [ ] CodeArtifact(ドメイン、リポジトリ、アップストリーム)
  • [ ] CodeGuru(Reviewer vs Profiler)
  • [ ] GitHub Actions + AWS OIDC統合
  • [ ] CDK(Pipeline Stack、セルフミューテーション)

ドメイン2: 設定管理とIaC (17%)

  • [ ] CloudFormation(ChangeSet、カスタムリソース、cfn-init/cfn-signal)
  • [ ] CloudFormation StackSets
  • [ ] AWS CDK(Constructs、Testing、Aspects)
  • [ ] AWS Service Catalog(製品、ポートフォリオ)
  • [ ] AWS Proton(環境テンプレート、サービステンプレート)
  • [ ] Systems Manager State Manager(デシレッドステート)

ドメイン3: 弾力性のあるクラウドソリューション (15%)

  • [ ] Auto Scaling(スケーリングポリシー、Warm Pool)
  • [ ] ELB(Connection Draining/Deregistration Delay)
  • [ ] Blue/Green vs Canary vs Rolling デプロイ
  • [ ] Lambda Weighted Alias(カナリアデプロイ)
  • [ ] AWS Fault Injection Simulator

ドメイン4: モニタリングとロギング (15%)

  • [ ] CloudWatch(Logs Insights、メトリクスフィルター、Synthetics)
  • [ ] X-Ray(サービスマップ、アノテーション、サンプリングルール)
  • [ ] CloudTrail(データイベント、Insights)
  • [ ] AWS Distro for OpenTelemetry(ADOT)
  • [ ] Amazon Managed Grafana + Prometheus

ドメイン5: インシデントとイベント対応 (18%)

  • [ ] CloudWatch Alarm + SNS + Lambda(自動修復)
  • [ ] Systems Manager OpsCenter(インシデント管理)
  • [ ] Systems Manager Incident Manager
  • [ ] AWS Health API(サービス障害通知)
  • [ ] EventBridge(自動インシデント対応ワークフロー)

ドメイン6: セキュリティとコンプライアンス (13%)

  • [ ] Security Hub + GuardDuty自動修復
  • [ ] AWS Config(準拠状態の自動修復)
  • [ ] Secrets Manager ローテーション
  • [ ] CodePipeline セキュリティ統合(SAST、SCA、シークレットスキャン)
  • [ ] IAM権限境界(Permission Boundaries)