0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

単一のAWS CodePipelineで複数リージョンへの自動デプロイを実現する方法

Posted at

概要

単一のCodePipelineから複数リージョンへ自動デプロイする方法を解説します。クロスリージョンアクション機能を使い、各リージョンに対してDeployアクションを追加することで、災害対策や低レイテンシー化を実現できます。ArtifactStoresの設定とIAMロールの構成がポイントです。

目次

  1. はじめに
  2. クロスリージョンデプロイの仕組み
  3. 前提条件と準備
  4. 実装手順
  5. 料金について
  6. ベストプラクティスと注意点
  7. 終わりに

はじめに

アプリケーションを複数のAWSリージョンに展開することで、以下のメリットが得られます。

  • 災害対策(DR): 特定リージョンの障害時でもサービスを継続
  • 低レイテンシー: ユーザーに近いリージョンからサービスを提供
  • コンプライアンス対応: データの地理的配置要件への対応

従来は各リージョンごとに個別のパイプラインを管理する必要がありましたが、CodePipelineのクロスリージョンアクション機能を使用すると、単一のパイプラインから異なるリージョンのリソースへアクションを実行できます。これにより、パイプライン管理の複雑さを大幅に削減できます。

クロスリージョンデプロイの仕組み

基本アーキテクチャ

CodePipelineがクロスリージョンアクションを含む場合、パイプラインリージョンからアクションのリージョンへ、そのアクションの入力アーティファクトのみをレプリケートします。

image.png

重要な概念

ArtifactStores(複数形)

パイプラインを作成または編集する際、パイプラインリージョンにアーティファクトバケットが必要で、さらにアクションを実行する予定のリージョンごとに1つずつアーティファクトバケットが必要です。

単一リージョン構成では artifactStore(単数形)を使用しますが、クロスリージョンアクションを作成する場合は artifactStores(複数形)を使用する必要があります。両方を同時に使用することはできません。

リージョンごとのDeployアクション

各リージョンへのデプロイは、Deployステージ内にリージョンを指定したアクションを追加することで実現します。コンソールでクロスリージョンアクションを作成する際は、アクションプロバイダーとRegionフィールドを選択します。

前提条件と準備

必要な権限

  • 各リージョンでS3バケットを作成する権限
  • IAMロールを作成・編集する権限
  • CodePipelineを作成・編集する権限
  • デプロイ対象サービス(Lambda、ECS等)の操作権限

各リージョンでのS3バケット作成

CodePipelineがクロスリージョンアクションを実行する際、アーティファクトを1つのリージョンから別のリージョンへコピーする処理を自動的に行います。そのため、デプロイ先の各リージョンでアーティファクトストア用のS3バケットを事前に作成する必要があります。

# 東京リージョン(プライマリ)
aws s3 mb s3://my-pipeline-artifacts-ap-northeast-1 --region ap-northeast-1

# オレゴンリージョン
aws s3 mb s3://my-pipeline-artifacts-us-west-2 --region us-west-2

# フランクフルトリージョン
aws s3 mb s3://my-pipeline-artifacts-eu-central-1 --region eu-central-1

各バケットでバージョニングを有効化します。

aws s3api put-bucket-versioning \
  --bucket my-pipeline-artifacts-ap-northeast-1 \
  --versioning-configuration Status=Enabled \
  --region ap-northeast-1

IAMロールの設定

CodePipelineサービスロールに、各リージョンのS3バケットへのアクセス権限を付与します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:GetBucketLocation",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-pipeline-artifacts-ap-northeast-1/*",
        "arn:aws:s3:::my-pipeline-artifacts-us-west-2/*",
        "arn:aws:s3:::my-pipeline-artifacts-eu-central-1/*",
        "arn:aws:s3:::my-pipeline-artifacts-ap-northeast-1",
        "arn:aws:s3:::my-pipeline-artifacts-us-west-2",
        "arn:aws:s3:::my-pipeline-artifacts-eu-central-1"
      ]
    }
  ]
}

実装手順

CloudFormationテンプレートでのパイプライン定義

以下は、Lambda関数を3つのリージョンにデプロイするパイプラインの例です。

AWSTemplateFormatVersion: '2010-09-09'
Description: Multi-Region CodePipeline

Resources:
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      Name: multi-region-deployment-pipeline
      RoleArn: !GetAtt CodePipelineServiceRole.Arn
      # 複数リージョンの場合はArtifactStores(複数形)を使用
      ArtifactStores:
        - Region: ap-northeast-1
          ArtifactStore:
            Type: S3
            Location: my-pipeline-artifacts-ap-northeast-1
        - Region: us-west-2
          ArtifactStore:
            Type: S3
            Location: my-pipeline-artifacts-us-west-2
        - Region: eu-central-1
          ArtifactStore:
            Type: S3
            Location: my-pipeline-artifacts-eu-central-1
      
      Stages:
        # ソースステージ
        - Name: Source
          Actions:
            - Name: SourceAction
              ActionTypeId:
                Category: Source
                Owner: AWS
                Provider: S3
                Version: '1'
              Configuration:
                S3Bucket: my-source-bucket
                S3ObjectKey: source.zip
              OutputArtifacts:
                - Name: SourceOutput
        
        # ビルドステージ
        - Name: Build
          Actions:
            - Name: BuildAction
              ActionTypeId:
                Category: Build
                Owner: AWS
                Provider: CodeBuild
                Version: '1'
              Configuration:
                ProjectName: !Ref CodeBuildProject
              InputArtifacts:
                - Name: SourceOutput
              OutputArtifacts:
                - Name: BuildOutput
        
        # デプロイステージ(3リージョン並列デプロイ)
        - Name: Deploy
          Actions:
            # 東京リージョンへのデプロイ
            - Name: DeployToTokyo
              Region: ap-northeast-1
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: '1'
              Configuration:
                ActionMode: CREATE_UPDATE
                StackName: my-app-stack
                TemplatePath: BuildOutput::packaged-tokyo.yaml
                RoleArn: !GetAtt CloudFormationRole.Arn
              InputArtifacts:
                - Name: BuildOutput
              RunOrder: 1
            
            # オレゴンリージョンへのデプロイ
            - Name: DeployToOregon
              Region: us-west-2
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: '1'
              Configuration:
                ActionMode: CREATE_UPDATE
                StackName: my-app-stack
                TemplatePath: BuildOutput::packaged-oregon.yaml
                RoleArn: !GetAtt CloudFormationRole.Arn
              InputArtifacts:
                - Name: BuildOutput
              RunOrder: 1
            
            # フランクフルトリージョンへのデプロイ
            - Name: DeployToFrankfurt
              Region: eu-central-1
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Provider: CloudFormation
                Version: '1'
              Configuration:
                ActionMode: CREATE_UPDATE
                StackName: my-app-stack
                TemplatePath: BuildOutput::packaged-frankfurt.yaml
                RoleArn: !GetAtt CloudFormationRole.Arn
              InputArtifacts:
                - Name: BuildOutput
              RunOrder: 1

並列デプロイと順次デプロイ

上記の例では、3つのデプロイアクションの RunOrder を全て 1 に設定しています。これにより並列デプロイが実行されます。

順次デプロイが必要な場合(例:東京→オレゴン→フランクフルトの順)は、RunOrderの値を変更します。

- Name: DeployToTokyo
  RunOrder: 1
- Name: DeployToOregon
  RunOrder: 2
- Name: DeployToFrankfurt
  RunOrder: 3

リージョンごとのパッケージング

CloudFormationやSAMを使用する場合、各リージョン用に個別にパッケージングされたアプリケーションが必要です。ビルドステージで aws cloudformation package コマンドを --region フラグ付きでリージョンごとに実行します。

# buildspec.yaml
version: 0.2
phases:
  build:
    commands:
      # 東京リージョン用パッケージ
      - aws cloudformation package 
          --template-file template.yaml 
          --s3-bucket my-pipeline-artifacts-ap-northeast-1 
          --output-template-file packaged-tokyo.yaml 
          --region ap-northeast-1
      
      # オレゴンリージョン用パッケージ
      - aws cloudformation package 
          --template-file template.yaml 
          --s3-bucket my-pipeline-artifacts-us-west-2 
          --output-template-file packaged-oregon.yaml 
          --region us-west-2
      
      # フランクフルトリージョン用パッケージ
      - aws cloudformation package 
          --template-file template.yaml 
          --s3-bucket my-pipeline-artifacts-eu-central-1 
          --output-template-file packaged-frankfurt.yaml 
          --region eu-central-1

artifacts:
  files:
    - packaged-tokyo.yaml
    - packaged-oregon.yaml
    - packaged-frankfurt.yaml

料金について

CodePipeline料金(2025年10月時点)

CodePipelineには2つのパイプラインタイプがあり、V1タイプとV2タイプで料金体系が異なります。

項目 V1タイプ V2タイプ
基本料金 アクティブなパイプライン1つあたり月額$1.00 アクション実行時間に応じた従量課金
無料枠 月1つのアクティブパイプライン 月100分のアクション実行時間
課金単位 パイプライン数 アクション実行分数 × $0.002/分

アクティブなパイプラインとは、30日以上存在し、当月中に少なくとも1回のコード変更が実行されたパイプラインを指します。

料金例

例1:V1タイプで3リージョンにデプロイするパイプライン1つ

月額料金 = (1 - 1(無料枠)) × $1.00 = $0.00

パイプラインが1つだけなら無料枠内で運用可能です。

例2:V2タイプで月20回実行、各実行で4アクション×平均2分

総アクション実行時間 = 20回 × 4アクション × 2分 = 160分
課金対象 = 160分 - 100分(無料枠) = 60分
月額料金 = 60分 × $0.002 = $0.12

その他の関連料金

  • S3ストレージ料金: アーティファクト保存のため各リージョンでS3料金が発生
  • データ転送料金: リージョン間のアーティファクト転送に対する料金
  • CodeBuild料金: ビルドステージ実行時の料金(インスタンスタイプと実行時間に応じた従量課金)

注意: 料金は変動する可能性があります。最新情報は「AWS CodePipeline の料金」 ( https://aws.amazon.com/jp/codepipeline/pricing/ ) をご確認ください。

ベストプラクティスと注意点

リージョン選定の考慮事項

観点 推奨事項
レイテンシー 主要ユーザーの所在地に近いリージョンを選択
コンプライアンス データ保護規制に準拠したリージョンを選択
可用性 地理的に離れたリージョンの組み合わせ(例:東京+オレゴン)
コスト リージョンごとの料金差を考慮(東京は他リージョンより約1.3倍高い傾向)

セキュリティ設定

S3バケットの暗号化

各リージョンのアーティファクトバケットでサーバーサイド暗号化を有効化します。

aws s3api put-bucket-encryption \
  --bucket my-pipeline-artifacts-ap-northeast-1 \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "AES256"
      }
    }]
  }'

最小権限の原則

IAMロールには必要最小限の権限のみを付与します。特に本番環境へのデプロイアクションには、承認ステップの追加を検討してください。

モニタリング

CloudWatch Eventsの活用

パイプラインの実行状態をモニタリングし、失敗時には通知を受け取る設定を行います。

PipelineEventRule:
  Type: AWS::Events::Rule
  Properties:
    EventPattern:
      source:
        - aws.codepipeline
      detail-type:
        - CodePipeline Pipeline Execution State Change
      detail:
        state:
          - FAILED
        pipeline:
          - !Ref Pipeline
    Targets:
      - Arn: !Ref AlertTopic
        Id: PipelineFailureAlert

トラブルシューティング

アーティファクト転送の失敗

各リージョンのS3バケット名が正しいか、IAMロールに適切な権限があるかを確認してください。

Lambda実行時のリージョン設定

クロスリージョンLambda invokeアクションを使用する場合、PutJobSuccessResultとPutJobFailureResultによるLambda実行のステータスは、CodePipelineが存在するリージョンではなく、Lambda関数が存在するリージョンに送信する必要があります。

終わりに

単一のCodePipelineで複数リージョンへのデプロイを実現する方法を解説しました。重要なポイントは以下の通りです。

  • ArtifactStores(複数形) を使用して各リージョンのS3バケットを定義
  • Deployステージ内にリージョンごとのアクションを追加
  • 各リージョン用にCloudFormationテンプレートを個別にパッケージング
  • 並列・順次デプロイは RunOrder で制御

次のステップ

  • 承認ステージの追加: 本番デプロイ前に手動承認を挟む
  • ロールバック機能の実装: デプロイ失敗時の自動ロールバック
  • カナリアデプロイの導入: 段階的なトラフィック移行
  • クロスアカウントデプロイ: 複数のAWSアカウント間でのデプロイ

多リージョン展開により、グローバルなユーザー体験の向上と高可用性を実現できます。

参考文献・参考サイト

AWS公式ドキュメント

ブログ・技術記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?