前半:https://iret.media/138635
後半:https://iret.media/138658

はじめに

対象者

DOP試験(AWS Certified DevOps Engineer )に向けて、ここ間違いやすいよってところをサービスごとに注記していきます。(2025年1月時点)
結構な量になったので記事を2分割し、
前半はCodeDeployなどCode三兄弟とCloudFormationについて記載しています。
後半はAutoScalingやALBなど上記以外を記載。
また、情報を参考にする上での注意を記事の最後に記載していますので、気になる方はそちらをご確認ください。

それでは早速CodeDeployから

CodeDeploy

単一のタググループとは

  • タググループでは、デプロイ対象のEC2インスタンスを、タグを使って指定することが可能です。
  • タグの場合であれば、タグの”キー名”と”値”を指定するとそれに合致するEC2インスタンスがデプロイ先の対象となります。

デプロイグループ

デプロイグループは、インスタンスIDの登録ではなく、タグによって定義されます。

「aws deploy stop-deployment」コマンド

「aws deploy stop-deployment」コマンドを使用してデプロイを停止する。
ただしこのコマンドはデプロイを停止するだけであり、ロールバックを自動的に行いません。

AppSpec ファイルの中身

version: 0.0
os: operating-system-name
files:
  source-destination-files-mappings
permissions:
  permissions-specifications
hooks:
  deployment-lifecycle-event-mappings

ECRへの公開

「AWS CodeDeploy」はアプリケーションのデプロイを自動化するサービスであり、コンテナイメージを Amazon Elastic Container Registry (Amazon ECR) に公開する機能はない

CodeDeploy OneAtATime

一つずつ

Immutable

Immutableは既存のインスタンスは変更しないでデプロイをするポリシーです。
Auto scalingグループごとにデプロイした後、グループ単位で前のものをkillします。

appspec.yaml

AllowTrafficのライフサイクルに、ユーザーがappspec.yamlで介入できない

必要な IAM ポリシー

jsx
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "codedeploy:PollHost",
                "codedeploy:PutHostCommandComplete",
                "codedeploy:GetDeployment",
                "codedeploy:RegisterApplicationRevision"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::YOUR_DEPLOYMENT_BUCKET",
                "arn:aws:s3:::YOUR_DEPLOYMENT_BUCKET/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

具体的には、AWS CodeDeployは主に仮想マシンやサーバーレス環境でのデプロイメントに適しており、コンテナ化されたアプリケーションに対するデプロイメントでは Amazon ECS や Kubernetes などのコンテナ管理サービスが適しています。

CodeBuild

CodeBuildのbuild specファイル

本番環境と同じ条件での統合テストが可能になる。
buildspec.ymlとは、ビルド実行時に実行するコマンドを記述したYAML形式のファイルのこと。
このファイルをソースコードのルートディレクトリに配置することでCodeBuildbuildspec.ymlを読み込んで実行される。
CodeCommitを使用する場合は、リポジトリのルートディレクトリに配置する。
buildspec.ymlには以下のような項目が記述される。

yaml
phases:
    pre_build:
        commands:
            - <コマンド>

runOrder値

CodeBuildの実行順番、
例えば単体テストを追加したいときは2に入れるなどする

SQS:エラー時にバッチを分割

  • 「エラー時にバッチを分割設定」
    • SQS では “ReportBatchItemFailures” を利用して、失敗したメッセージのみ再処理対象にする ことが可能。

CodeCommit

appspec. yml は CodeDeploy用

CodePipeline

アクションのログに関して、s3に配信するものではないので、cloud trail経由が望ましい。
※CodePipeline の実行履歴は CloudTrail で追跡できるが、詳細なログは CloudWatch Logs に記録可能
EventBridge経由で、CodeCommitと結びつく

テスト時のみリソースを有効

Amazon EventBridge (Amazon CloudWatch Events) を AWS CodePipeline で使用すると、デプロイのテスト時のみリソースを有効にし、それ以外の時間は無効にすることができる

CodeArtifact

CodeArtifactを使うことで自身の利用するパッケージをAWS上に置いておくことができます。
pip installの対象となるライブラリなどを特定の領域で公開できるサービス

CodeArtifact の オリジン制御 (Origin Control) 設定を変更して、直接公開を許可しつつアップストリーム操作をブロック

AWS CodeArtifact の Origin Control を変更して、以下のようなポリシーを実現したい場合の設定について説明します。

  • 直接公開を許可: パッケージの直接公開(npm publish など)を許可
  • アップストリーム操作をブロック: 外部リポジトリ(npm、PyPI など)へのアップストリーム操作を防ぐ

設定方法

1. CodeArtifact のオリジンコントロール(Origin Control)ポリシーを設定

AWS CodeArtifact では、オリジンコントロールポリシーを設定することで、パッケージの取得元や公開方法を制御できます。

オリジンコントロール設定のポイント

  • Allow : CodeArtifact に直接パッケージを公開(許可)
  • Block : 外部リポジトリからのパッケージ取得やアップストリーム操作をブロック
{
  "repository": "your-repo-name",
  "domain": "your-domain-name",
  "upstream": {
    "upstreamRepositories": []
  },
  "originControl": {
    "directPublish": "Allow",
    "upstream": "Block"
  }
}

この設定により:

  • npm publishtwine upload で CodeArtifact に直接公開が可能
  • 外部の npm / PyPI などへのパッケージ転送(アップストリーム)がブロックされる

S3のバックエンドを使用している

CloudFormation cfn

CloudFormation lambda カスタムリソース

スタックのイベントに合わせて動作させたい機能をカスタムリソースと定義して、
LambdaかSNSを呼び出して呼び出し先で何とかする機能です。

実行タイミングは以下で設定可能
event.RequestType === 'Create':リソース作成時
event.RequestType === 'Update':リソース更新時
event.RequestType === 'Delete':リソース削除時

CloudFormation Hooks

  • リソースの削除、更新前に特定のカスタムロジックを実行できるもの

cfn-initヘルパースクリプト

具体的には、cfn-initヘルパースクリプトは AWS CloudFormation によって提供され、スタックのメタデータを読み込み、パッケージのインストール、ファイルの書き込みなどのセットアップタスクを実行します。
cfn-initは、CloudFormationリソースのメタデータ AWS::CloudFormation::Init セクションに記述されたコンフィグを取得し その記述のとおりにEC2インスタンス内でパッケージのインストールやファイルの作成、サービスの開始などを実行するヘルパースクリプトです。

cfn-init
リソースメタデータの取得と解釈、パッケージのインストール、ファイルの作成、およびサービスの開始で使用します。
cfn-signal
CreationPolicy または WaitCondition でシグナルを送信するために使用し、前提となるリソースやアプリケーションの準備ができたときに、スタックの他のリソースを同期できるようにします。
cfn-get-metadata
特定のキーへのリソースまたはパスのメタデータを取得するために使用します。

cfn-hup(hang upの略のhup): メタデータへの更新を確認し、変更が検出されたときにカスタムフックを実行するために使用します。
CloudFormation init メタデータを使用することで、アプリケーションの構成ファイルを AWS CloudFormation テンプレート内に直接配置できます。これにより、インスタンス起動時にcfn-init スクリプトを介して自動的に構成ファイルが適用されます。

cfn-initのサンプル

jsx
Resources:
  ServerInstance:
    Type: AWS::EC2::Instance
    Metadata:
      Comment: Install a simple web app
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
          files:
            /var/www/html/index.html:
              content: !Sub |
                <p>Hello!</p>
              mode: '000644'
              owner: root
              group: root
          services:
            sysvinit:
              httpd:
                enabled: 'true'
                ensureRunning: 'true'
    Properties:
      ImageId: !Ref AmiId
      InstanceType: t3.micro
      SecurityGroupIds:
        - !Ref InstanceSecurityGroup
      KeyName: !Ref KeyName
      SubnetId : !Ref SubnetId
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          /opt/aws/bin/cfn-init -v \
          --stack ${AWS::StackName} \
          --resource ServerInstance \
          --region ${AWS::Region}
  InstanceSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'

メタデータサンプル

jsx
AWSTemplateFormatVersion: '2010-09-09'
Resources:
  MyEC2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      InstanceType: t2.micro
      ImageId: ami-0abcdef1234567890  # 適切なAMI IDに置き換えてください
      KeyName: my-key-pair
      Metadata:
        AWS::CloudFormation::Init:
          configSets:
            default:
              - install
              - start
          config:
            install:
              packages:
                yum:
                  httpd: []
            start:
              service:
                sysvinit:
                  httpd:
                    enabled: 'true'
                    ensureRunning: 'true'
            sources:
              '/var/www/html':
                'https://example.com/my-web-content.tar.gz'
            files:
              '/etc/httpd/conf.d/my-site.conf':
                content: |
                  <VirtualHost *:80>
                    DocumentRoot /var/www/html
                    ServerName www.example.com
                  </VirtualHost>
                mode: '000644'
                owner: root
                group: root
    UserData:
      Fn::Base64: |
        #!/bin/bash
        set -xe
        yum update -y
        yum install -y aws-cfn-bootstrap
        /opt/aws/bin/cfn-init --region !Ref 'AWS::Region' --stack !Ref 'AWS::StackName' --resource MyEC2Instance
        /opt/aws/bin/cfn-signal --exit-code $? --stack !Ref 'AWS::StackName' --resource MyEC2Instance

initメタデータと起動テンプレートの違いは?

主な違い

特徴 AWS::CloudFormation::Init AWS::EC2::LaunchTemplate
目的 インスタンスの起動後に必要な設定やカスタマイズ(ソフトウェアインストール、設定ファイル配置、サービス起動など) インスタンスの起動に必要な基本的な設定(AMI、インスタンスタイプ、セキュリティグループ、ユーザーデータなど)
実行タイミング インスタンスの起動後、UserData セクション内で cfn-init コマンドを実行して設定を適用 インスタンスの起動時にテンプレートから直接設定を適用
設定項目 ソフトウェアのインストール、サービスの起動、設定ファイルの配置、外部リソースのダウンロードなど インスタンスタイプ、AMI、セキュリティグループ、ユーザーデータなどの基本設定
主な使用方法 インスタンスのカスタマイズや構成管理 インスタンスを起動するための設定テンプレート
  • AWS::CloudFormation::Init は、EC2 インスタンスが起動した後の設定やカスタマイズを行うために使用されます。
  • AWS::EC2::LaunchTemplate は、EC2 インスタンスを起動するための設定テンプレートとして、インスタンスの起動時に必要な基本的な情報を定義します。

CloudFormation hooks

リソースの作成時に暗号化の実施を強制できる
設定内容が基準に従っているかどうかをCloudFormation Hooksで確認し、定めたルールに準拠していない場合は警告を発生させたり、プロビジョニングを中止させたりすることが可能です。

例:

  • AWSSamples::EFSEncrypt::Hook
    • EFSが暗号化されているか

CloudFormationはさまざまなアカウントにデプロイできる仕組みはstackset?

CloudFormation は CloudFormation StackSet を使用することで、複数の AWS アカウントやリージョンにデプロイできる?
はい、CloudFormation StackSet が複数のアカウントやリージョンに対してスタックをデプロイおよび管理するための仕組みです。これにより、複数のAWSアカウントやリージョンで統一されたインフラストラクチャを効率的にデプロイできます。

CAPABILITY_IAM 及び CAPABILITY_NAMED_IAM

cfnがIAMリソースを作る権利問題

cfn、かつInsufficientCapabilitiesエラー、ときたらこれをまず疑うと良い

ドリフト検出とは?

ドリフト検知は現在の状態とCloudFormationで定義されているあるべき状態の差分を検知することができる機能

ドリフト検出オペレーションステータス 説明
DETECTION_COMPLETE ドリフト検出をサポートするスタック内のすべてのリソースについて、スタックドリフト検出オペレーションが正常に完了した。
DETECTION_FAILED スタックドリフト検出オペレーションは、スタック内の少なくとも1つのリソースで失敗した。結果はCloudFormationがドリフト検出を正常に完了したリソースで利用できる。
DETECTION_IN_PROGRESS スタックドリフト検出オペレーションは現在進行中です。

CloudFormation Stack Set

特定のリソースを複数アカウントに跨いでデプロイできるサービス

Service CatalogとStack setの違い

項目 AWS Service Catalog AWS CloudFormation StackSets
主な目的 承認済みのリソース提供 複数アカウント・リージョンへのデプロイ
主な目的 承認済みのリソース提供 複数アカウント・リージョンへのデプロイ
使い方 ユーザーがリソースを選んでデプロイ 管理者が一括デプロイ
利用者 エンドユーザー (開発者, エンジニア) 管理者 (AWS管理チーム)
アクセス管理 IAM 制約や起動制約あり AWS Organizations との統合可能
リソース管理 製品 (Product) をカタログ化 StackSet を組織内に展開
変更適用 個々のユーザーが適用 全リージョン・アカウントに適用

Service Catalog:起動制約

エンドユーザーの権限に許可を与えたくないが、製品を起動させたいケースで活躍する制約

AWS Lambda-backed カスタムリソース

カスタムリソースは実行のステータスを更新するために署名付き URL に応答を送信する必要がある、
AWS CloudFormation カスタムリソースを使用する際、AWS Lambda 関数はカスタムリソースの作成、更新、削除の結果を CloudFormation に返す必要があります。
これを実現するために、Lambda 関数のコードは、署名付き URL に応答を返すことが必要です。署名付き URLは、CloudFormation から Lambda 関数に渡されます。

InsufficientCapabilitiesException

IAMリソースの作成時に権限が不足しているエラー

CDK

CDK アサーションモジュール

AWS CDK アサーションモジュール を使用することで、template.hasResourceProperties を使い、生成されたテンプレートに期待されるリソースのプロパティが正しく設定されているかどうかをテストできます。

これにより、デプロイ前にインフラの構成が正確かどうかを確認し、エラーを防ぐことが可能です。

注意

この記事はAWSのサービスの関係や全体像を簡略に理解するため、
少しサービス名を省略表記しているものもあるかもしれませんがご了承ください。
また、AWS自体常にアップデートするものため、2025/02月時点での情報を書いているつもりですが、
最新の情報はあくまで自己責任でお調べいただければと思います。