Back to Releases
v2.206.0 2025年7月16日

AWS CDK v2.206.0 リリース解説

ECS Blue/Greenデプロイメントのネイティブサポート追加と、カスタムリソースプロバイダーフレームワークのロギング設定改善

ecscustom-resources

概要

AWS CDK v2.206.0では、ECS ServiceにおけるBlue/Greenデプロイメントのネイティブサポートが追加され、カスタムリソースプロバイダーフレームワークの非同期実行時のロギングがデフォルトでオフになりました。これらの変更により、ECSのデプロイメント戦略の柔軟性が向上し、カスタムリソースの運用コストが削減されます。

新機能

ECS Blue/Greenデプロイメントのネイティブサポート (L1)

ECS Serviceリソースに、AWS CodeDeployを使用しないネイティブBlue/Greenデプロイメントのサポートが追加されました。この機能により、ELBv2ターゲットグループを使用した安全なデプロイメント戦略を実装できます。

新しいプロパティ

LoadBalancer.AdvancedConfiguration

ロードバランサーのBlue/Greenデプロイメント設定を定義します:

import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as iam from 'aws-cdk-lib/aws-iam';

const service = new ecs.FargateService(this, 'Service', {
  cluster,
  taskDefinition,
  // 通常のロードバランサー設定
  loadBalancers: [{
    targetGroupArn: productionTargetGroup.targetGroupArn,
    containerName: 'web',
    containerPort: 80,
    // Blue/Greenデプロイメントの詳細設定
    advancedConfiguration: {
      alternateTargetGroupArn: testTargetGroup.targetGroupArn,  // テスト用ターゲットグループ (必須)
      productionListenerRule: 'arn:aws:elasticloadbalancing:...',  // 本番リスナールールARN
      testListenerRule: 'arn:aws:elasticloadbalancing:...',        // テストリスナールールARN
      roleArn: deploymentRole.roleArn,                              // トラフィックシフト用IAMロール
    },
  }],
});

DeploymentConfiguration の拡張

Blue/Greenデプロイメントの動作を制御する新しいオプション:

const service = new ecs.FargateService(this, 'Service', {
  cluster,
  taskDefinition,
  deploymentConfiguration: {
    strategy: 'BLUE_GREEN',                    // デプロイメント戦略: ROLLING (デフォルト) または BLUE_GREEN
    bakeTimeInMinutes: 15,                     // 新バージョンの安定性確認時間 (0-1440分)
    lifecycleHooks: [                          // デプロイメントライフサイクルフック
      {
        hookTargetArn: hookFunction.functionArn,  // Lambda関数ARN (必須)
        roleArn: hookRole.roleArn,                // Lambda実行用IAMロール (必須)
        lifecycleStages: [                        // フック実行タイミング (必須)
          'PRE_TRAFFIC_ROUTING',                  // トラフィックシフト前
          'POST_TRAFFIC_ROUTING',                 // トラフィックシフト後
        ],
      },
    ],
  },
});

ServiceConnect.TestTrafficRules

Service Connectを使用したBlue/Greenデプロイメント時のテストトラフィックルーティング設定:

const service = new ecs.FargateService(this, 'Service', {
  cluster,
  taskDefinition,
  serviceConnectConfiguration: {
    services: [{
      portMappingName: 'api',
      clientAliases: [{
        port: 8080,
        dnsName: 'api.local',
        // Blue/Greenデプロイメント時のテストトラフィックルーティング
        testTrafficRules: {
          header: {
            name: 'X-Test-Traffic',          // HTTPヘッダー名 (必須)
            value: {
              exact: 'canary',               // 完全一致する値 (必須)
            },
          },
        },
      }],
    }],
  },
});

使用例: 完全なBlue/Greenデプロイメント設定

import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as lambda from 'aws-cdk-lib/aws-lambda';

const vpc = new ec2.Vpc(this, 'Vpc');
const cluster = new ecs.Cluster(this, 'Cluster', { vpc });

// ALBとターゲットグループの作成
const alb = new elbv2.ApplicationLoadBalancer(this, 'ALB', { vpc, internetFacing: true });
const productionTargetGroup = new elbv2.ApplicationTargetGroup(this, 'ProdTG', {
  vpc,
  port: 80,
  protocol: elbv2.ApplicationProtocol.HTTP,
  targetType: elbv2.TargetType.IP,
});
const testTargetGroup = new elbv2.ApplicationTargetGroup(this, 'TestTG', {
  vpc,
  port: 80,
  protocol: elbv2.ApplicationProtocol.HTTP,
  targetType: elbv2.TargetType.IP,
});

// リスナーとリスナールールの作成
const listener = alb.addListener('Listener', { port: 80, defaultAction: elbv2.ListenerAction.fixedResponse(404) });
const prodRule = listener.addTargetGroups('ProdRule', { targetGroups: [productionTargetGroup], priority: 100 });
const testListener = alb.addListener('TestListener', { port: 8080, defaultAction: elbv2.ListenerAction.fixedResponse(404) });
const testRule = testListener.addTargetGroups('TestRule', { targetGroups: [testTargetGroup], priority: 100 });

// トラフィックシフト用IAMロール
const deploymentRole = new iam.Role(this, 'DeploymentRole', {
  assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
  managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('AWSCodeDeployRoleForECS')],
});

// デプロイメントフック用Lambda関数
const hookFunction = new lambda.Function(this, 'HookFunction', {
  runtime: lambda.Runtime.NODEJS_20_X,
  handler: 'index.handler',
  code: lambda.Code.fromInline(`
    exports.handler = async (event) => {
      console.log('Deployment hook triggered:', JSON.stringify(event));
      // カスタム検証ロジックをここに実装
      return { status: 'success' };
    };
  `),
});

const hookRole = new iam.Role(this, 'HookRole', {
  assumedBy: new iam.ServicePrincipal('ecs.amazonaws.com'),
});
hookFunction.grantInvoke(hookRole);

// タスク定義
const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDef');
const container = taskDefinition.addContainer('web', {
  image: ecs.ContainerImage.fromRegistry('nginx:latest'),
  portMappings: [{ containerPort: 80, name: 'http' }],
});

// Blue/Greenデプロイメントを使用するECS Service
const service = new ecs.FargateService(this, 'Service', {
  cluster,
  taskDefinition,
  desiredCount: 2,
  // Blue/Greenデプロイメント設定
  deploymentConfiguration: {
    strategy: 'BLUE_GREEN',                    // Blue/Greenデプロイメント戦略を有効化
    bakeTimeInMinutes: 10,                     // 10分間の安定性確認
    maximumPercent: 200,                       // ローリング更新設定
    minimumHealthyPercent: 100,
    lifecycleHooks: [{
      hookTargetArn: hookFunction.functionArn,
      roleArn: hookRole.roleArn,
      lifecycleStages: ['PRE_TRAFFIC_ROUTING', 'POST_TRAFFIC_ROUTING'],
    }],
  },
  // ロードバランサー設定
  loadBalancers: [{
    targetGroupArn: productionTargetGroup.targetGroupArn,
    containerName: 'web',
    containerPort: 80,
    advancedConfiguration: {
      alternateTargetGroupArn: testTargetGroup.targetGroupArn,
      productionListenerRule: prodRule.listenerRuleArn,
      testListenerRule: testRule.listenerRuleArn,
      roleArn: deploymentRole.roleArn,
    },
  }],
});

この設定により、以下の動作が実現されます:

  • 新しいタスクバージョンがtestTargetGroupにデプロイされる
  • PRE_TRAFFIC_ROUTINGフックで事前検証を実行
  • テストトラフィックで新バージョンを検証
  • 10分間の安定性確認 (bake time)
  • 本番トラフィックを新バージョンにシフト
  • POST_TRAFFIC_ROUTINGフックで事後検証を実行
  • 古いタスクバージョンを削除

カスタムリソースプロバイダーフレームワークのロギング設定改善

非同期カスタムリソースプロバイダーフレームワークのロギングが、デフォルトでオフになりました。これにより、CloudWatch Logsのコストを削減できます。

変更内容

従来は、非同期カスタムリソース (Step Functionsを使用するwaiter) のログがデフォルトで有効でしたが、v2.206.0からはデフォルトで無効になります。

import * as cr from 'aws-cdk-lib/custom-resources';

const provider = new cr.Provider(this, 'Provider', {
  onEventHandler: onEventFunction,
  isCompleteHandler: isCompleteFunction,  // 非同期waiterを使用
  // ロギングの設定 (オプション)
  // logRetention: logs.RetentionDays.ONE_WEEK,  // ログを有効にする場合のみ指定
});

移行ガイド

ロギングを引き続き有効にしたい場合は、明示的にlogRetentionプロパティを指定してください:

import * as cr from 'aws-cdk-lib/custom-resources';
import * as logs from 'aws-cdk-lib/aws-logs';

const provider = new cr.Provider(this, 'Provider', {
  onEventHandler: onEventFunction,
  isCompleteHandler: isCompleteFunction,
  // ロギングを明示的に有効化
  logRetention: logs.RetentionDays.ONE_WEEK,
});

まとめ

AWS CDK v2.206.0では、ECSのBlue/Greenデプロイメント機能が大幅に強化され、より安全で柔軟なデプロイメント戦略を実装できるようになりました。L1レベルでのサポートにより、CloudFormationテンプレートを直接活用する高度な設定が可能です。

また、カスタムリソースプロバイダーフレームワークのロギング設定変更により、運用コストの最適化が図られています。既存のカスタムリソースでロギングが必要な場合は、明示的な設定を追加してください。

これらの機能を活用することで、より堅牢で運用効率の高いインフラストラクチャを構築できます。