Configure AWS CodeDeploy Deployment Groups

The aws:codedeploy/deploymentGroup:DeploymentGroup resource, part of the Pulumi AWS provider, defines a CodeDeploy deployment group that specifies target instances or services, deployment strategy, and rollback behavior. This guide focuses on three capabilities: EC2 tag-based targeting, ECS blue/green deployments, and Classic ELB traffic control.

Deployment groups require a CodeDeploy application, IAM service role, and target infrastructure such as EC2 instances, ECS services, or load balancers. The examples are intentionally small. Combine them with your own application definitions, IAM policies, and infrastructure.

Deploy to EC2 instances with tag-based targeting

Most CodeDeploy workflows target EC2 instances using tags, allowing you to deploy application revisions to fleets without hardcoding instance IDs.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const assumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: ["codedeploy.amazonaws.com"],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const example = new aws.iam.Role("example", {
    name: "example-role",
    assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const aWSCodeDeployRole = new aws.iam.RolePolicyAttachment("AWSCodeDeployRole", {
    policyArn: "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole",
    role: example.name,
});
const exampleApplication = new aws.codedeploy.Application("example", {name: "example-app"});
const exampleTopic = new aws.sns.Topic("example", {name: "example-topic"});
const exampleDeploymentGroup = new aws.codedeploy.DeploymentGroup("example", {
    appName: exampleApplication.name,
    deploymentGroupName: "example-group",
    serviceRoleArn: example.arn,
    ec2TagSets: [{
        ec2TagFilters: [
            {
                key: "filterkey1",
                type: "KEY_AND_VALUE",
                value: "filtervalue",
            },
            {
                key: "filterkey2",
                type: "KEY_AND_VALUE",
                value: "filtervalue",
            },
        ],
    }],
    triggerConfigurations: [{
        triggerEvents: ["DeploymentFailure"],
        triggerName: "example-trigger",
        triggerTargetArn: exampleTopic.arn,
    }],
    autoRollbackConfiguration: {
        enabled: true,
        events: ["DEPLOYMENT_FAILURE"],
    },
    alarmConfiguration: {
        alarms: ["my-alarm-name"],
        enabled: true,
    },
    outdatedInstancesStrategy: "UPDATE",
});
import pulumi
import pulumi_aws as aws

assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": ["codedeploy.amazonaws.com"],
    }],
    "actions": ["sts:AssumeRole"],
}])
example = aws.iam.Role("example",
    name="example-role",
    assume_role_policy=assume_role.json)
a_ws_code_deploy_role = aws.iam.RolePolicyAttachment("AWSCodeDeployRole",
    policy_arn="arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole",
    role=example.name)
example_application = aws.codedeploy.Application("example", name="example-app")
example_topic = aws.sns.Topic("example", name="example-topic")
example_deployment_group = aws.codedeploy.DeploymentGroup("example",
    app_name=example_application.name,
    deployment_group_name="example-group",
    service_role_arn=example.arn,
    ec2_tag_sets=[{
        "ec2_tag_filters": [
            {
                "key": "filterkey1",
                "type": "KEY_AND_VALUE",
                "value": "filtervalue",
            },
            {
                "key": "filterkey2",
                "type": "KEY_AND_VALUE",
                "value": "filtervalue",
            },
        ],
    }],
    trigger_configurations=[{
        "trigger_events": ["DeploymentFailure"],
        "trigger_name": "example-trigger",
        "trigger_target_arn": example_topic.arn,
    }],
    auto_rollback_configuration={
        "enabled": True,
        "events": ["DEPLOYMENT_FAILURE"],
    },
    alarm_configuration={
        "alarms": ["my-alarm-name"],
        "enabled": True,
    },
    outdated_instances_strategy="UPDATE")
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codedeploy"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/sns"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"codedeploy.amazonaws.com",
							},
						},
					},
					Actions: []string{
						"sts:AssumeRole",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		example, err := iam.NewRole(ctx, "example", &iam.RoleArgs{
			Name:             pulumi.String("example-role"),
			AssumeRolePolicy: pulumi.String(assumeRole.Json),
		})
		if err != nil {
			return err
		}
		_, err = iam.NewRolePolicyAttachment(ctx, "AWSCodeDeployRole", &iam.RolePolicyAttachmentArgs{
			PolicyArn: pulumi.String("arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole"),
			Role:      example.Name,
		})
		if err != nil {
			return err
		}
		exampleApplication, err := codedeploy.NewApplication(ctx, "example", &codedeploy.ApplicationArgs{
			Name: pulumi.String("example-app"),
		})
		if err != nil {
			return err
		}
		exampleTopic, err := sns.NewTopic(ctx, "example", &sns.TopicArgs{
			Name: pulumi.String("example-topic"),
		})
		if err != nil {
			return err
		}
		_, err = codedeploy.NewDeploymentGroup(ctx, "example", &codedeploy.DeploymentGroupArgs{
			AppName:             exampleApplication.Name,
			DeploymentGroupName: pulumi.String("example-group"),
			ServiceRoleArn:      example.Arn,
			Ec2TagSets: codedeploy.DeploymentGroupEc2TagSetArray{
				&codedeploy.DeploymentGroupEc2TagSetArgs{
					Ec2TagFilters: codedeploy.DeploymentGroupEc2TagSetEc2TagFilterArray{
						&codedeploy.DeploymentGroupEc2TagSetEc2TagFilterArgs{
							Key:   pulumi.String("filterkey1"),
							Type:  pulumi.String("KEY_AND_VALUE"),
							Value: pulumi.String("filtervalue"),
						},
						&codedeploy.DeploymentGroupEc2TagSetEc2TagFilterArgs{
							Key:   pulumi.String("filterkey2"),
							Type:  pulumi.String("KEY_AND_VALUE"),
							Value: pulumi.String("filtervalue"),
						},
					},
				},
			},
			TriggerConfigurations: codedeploy.DeploymentGroupTriggerConfigurationArray{
				&codedeploy.DeploymentGroupTriggerConfigurationArgs{
					TriggerEvents: pulumi.StringArray{
						pulumi.String("DeploymentFailure"),
					},
					TriggerName:      pulumi.String("example-trigger"),
					TriggerTargetArn: exampleTopic.Arn,
				},
			},
			AutoRollbackConfiguration: &codedeploy.DeploymentGroupAutoRollbackConfigurationArgs{
				Enabled: pulumi.Bool(true),
				Events: pulumi.StringArray{
					pulumi.String("DEPLOYMENT_FAILURE"),
				},
			},
			AlarmConfiguration: &codedeploy.DeploymentGroupAlarmConfigurationArgs{
				Alarms: pulumi.StringArray{
					pulumi.String("my-alarm-name"),
				},
				Enabled: pulumi.Bool(true),
			},
			OutdatedInstancesStrategy: pulumi.String("UPDATE"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var assumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "codedeploy.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var example = new Aws.Iam.Role("example", new()
    {
        Name = "example-role",
        AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var aWSCodeDeployRole = new Aws.Iam.RolePolicyAttachment("AWSCodeDeployRole", new()
    {
        PolicyArn = "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole",
        Role = example.Name,
    });

    var exampleApplication = new Aws.CodeDeploy.Application("example", new()
    {
        Name = "example-app",
    });

    var exampleTopic = new Aws.Sns.Topic("example", new()
    {
        Name = "example-topic",
    });

    var exampleDeploymentGroup = new Aws.CodeDeploy.DeploymentGroup("example", new()
    {
        AppName = exampleApplication.Name,
        DeploymentGroupName = "example-group",
        ServiceRoleArn = example.Arn,
        Ec2TagSets = new[]
        {
            new Aws.CodeDeploy.Inputs.DeploymentGroupEc2TagSetArgs
            {
                Ec2TagFilters = new[]
                {
                    new Aws.CodeDeploy.Inputs.DeploymentGroupEc2TagSetEc2TagFilterArgs
                    {
                        Key = "filterkey1",
                        Type = "KEY_AND_VALUE",
                        Value = "filtervalue",
                    },
                    new Aws.CodeDeploy.Inputs.DeploymentGroupEc2TagSetEc2TagFilterArgs
                    {
                        Key = "filterkey2",
                        Type = "KEY_AND_VALUE",
                        Value = "filtervalue",
                    },
                },
            },
        },
        TriggerConfigurations = new[]
        {
            new Aws.CodeDeploy.Inputs.DeploymentGroupTriggerConfigurationArgs
            {
                TriggerEvents = new[]
                {
                    "DeploymentFailure",
                },
                TriggerName = "example-trigger",
                TriggerTargetArn = exampleTopic.Arn,
            },
        },
        AutoRollbackConfiguration = new Aws.CodeDeploy.Inputs.DeploymentGroupAutoRollbackConfigurationArgs
        {
            Enabled = true,
            Events = new[]
            {
                "DEPLOYMENT_FAILURE",
            },
        },
        AlarmConfiguration = new Aws.CodeDeploy.Inputs.DeploymentGroupAlarmConfigurationArgs
        {
            Alarms = new[]
            {
                "my-alarm-name",
            },
            Enabled = true,
        },
        OutdatedInstancesStrategy = "UPDATE",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.iam.RolePolicyAttachment;
import com.pulumi.aws.iam.RolePolicyAttachmentArgs;
import com.pulumi.aws.codedeploy.Application;
import com.pulumi.aws.codedeploy.ApplicationArgs;
import com.pulumi.aws.sns.Topic;
import com.pulumi.aws.sns.TopicArgs;
import com.pulumi.aws.codedeploy.DeploymentGroup;
import com.pulumi.aws.codedeploy.DeploymentGroupArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupEc2TagSetArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupTriggerConfigurationArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupAutoRollbackConfigurationArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupAlarmConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("codedeploy.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var example = new Role("example", RoleArgs.builder()
            .name("example-role")
            .assumeRolePolicy(assumeRole.json())
            .build());

        var aWSCodeDeployRole = new RolePolicyAttachment("aWSCodeDeployRole", RolePolicyAttachmentArgs.builder()
            .policyArn("arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole")
            .role(example.name())
            .build());

        var exampleApplication = new Application("exampleApplication", ApplicationArgs.builder()
            .name("example-app")
            .build());

        var exampleTopic = new Topic("exampleTopic", TopicArgs.builder()
            .name("example-topic")
            .build());

        var exampleDeploymentGroup = new DeploymentGroup("exampleDeploymentGroup", DeploymentGroupArgs.builder()
            .appName(exampleApplication.name())
            .deploymentGroupName("example-group")
            .serviceRoleArn(example.arn())
            .ec2TagSets(DeploymentGroupEc2TagSetArgs.builder()
                .ec2TagFilters(                
                    DeploymentGroupEc2TagSetEc2TagFilterArgs.builder()
                        .key("filterkey1")
                        .type("KEY_AND_VALUE")
                        .value("filtervalue")
                        .build(),
                    DeploymentGroupEc2TagSetEc2TagFilterArgs.builder()
                        .key("filterkey2")
                        .type("KEY_AND_VALUE")
                        .value("filtervalue")
                        .build())
                .build())
            .triggerConfigurations(DeploymentGroupTriggerConfigurationArgs.builder()
                .triggerEvents("DeploymentFailure")
                .triggerName("example-trigger")
                .triggerTargetArn(exampleTopic.arn())
                .build())
            .autoRollbackConfiguration(DeploymentGroupAutoRollbackConfigurationArgs.builder()
                .enabled(true)
                .events("DEPLOYMENT_FAILURE")
                .build())
            .alarmConfiguration(DeploymentGroupAlarmConfigurationArgs.builder()
                .alarms("my-alarm-name")
                .enabled(true)
                .build())
            .outdatedInstancesStrategy("UPDATE")
            .build());

    }
}
resources:
  example:
    type: aws:iam:Role
    properties:
      name: example-role
      assumeRolePolicy: ${assumeRole.json}
  aWSCodeDeployRole:
    type: aws:iam:RolePolicyAttachment
    name: AWSCodeDeployRole
    properties:
      policyArn: arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole
      role: ${example.name}
  exampleApplication:
    type: aws:codedeploy:Application
    name: example
    properties:
      name: example-app
  exampleTopic:
    type: aws:sns:Topic
    name: example
    properties:
      name: example-topic
  exampleDeploymentGroup:
    type: aws:codedeploy:DeploymentGroup
    name: example
    properties:
      appName: ${exampleApplication.name}
      deploymentGroupName: example-group
      serviceRoleArn: ${example.arn}
      ec2TagSets:
        - ec2TagFilters:
            - key: filterkey1
              type: KEY_AND_VALUE
              value: filtervalue
            - key: filterkey2
              type: KEY_AND_VALUE
              value: filtervalue
      triggerConfigurations:
        - triggerEvents:
            - DeploymentFailure
          triggerName: example-trigger
          triggerTargetArn: ${exampleTopic.arn}
      autoRollbackConfiguration:
        enabled: true
        events:
          - DEPLOYMENT_FAILURE
      alarmConfiguration:
        alarms:
          - my-alarm-name
        enabled: true
      outdatedInstancesStrategy: UPDATE
variables:
  assumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - codedeploy.amazonaws.com
            actions:
              - sts:AssumeRole

When a deployment runs, CodeDeploy queries EC2 for instances matching the tag filters in ec2TagSets. The serviceRoleArn grants permissions to read instance metadata and execute deployments. The triggerConfigurations property sends SNS notifications on deployment events, while autoRollbackConfiguration automatically reverts failed deployments. The alarmConfiguration property integrates with CloudWatch alarms to trigger rollbacks when metrics breach thresholds.

Deploy ECS services with blue/green traffic shifting

Container workloads on ECS benefit from blue/green deployments that provision a new task set, shift traffic gradually, and terminate old tasks only after validation.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.codedeploy.Application("example", {
    computePlatform: "ECS",
    name: "example",
});
const exampleDeploymentGroup = new aws.codedeploy.DeploymentGroup("example", {
    appName: example.name,
    deploymentConfigName: "CodeDeployDefault.ECSAllAtOnce",
    deploymentGroupName: "example",
    serviceRoleArn: exampleAwsIamRole.arn,
    autoRollbackConfiguration: {
        enabled: true,
        events: ["DEPLOYMENT_FAILURE"],
    },
    blueGreenDeploymentConfig: {
        deploymentReadyOption: {
            actionOnTimeout: "CONTINUE_DEPLOYMENT",
        },
        terminateBlueInstancesOnDeploymentSuccess: {
            action: "TERMINATE",
            terminationWaitTimeInMinutes: 5,
        },
    },
    deploymentStyle: {
        deploymentOption: "WITH_TRAFFIC_CONTROL",
        deploymentType: "BLUE_GREEN",
    },
    ecsService: {
        clusterName: exampleAwsEcsCluster.name,
        serviceName: exampleAwsEcsService.name,
    },
    loadBalancerInfo: {
        targetGroupPairInfo: {
            prodTrafficRoute: {
                listenerArns: [exampleAwsLbListener.arn],
            },
            targetGroups: [
                {
                    name: blue.name,
                },
                {
                    name: green.name,
                },
            ],
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.codedeploy.Application("example",
    compute_platform="ECS",
    name="example")
example_deployment_group = aws.codedeploy.DeploymentGroup("example",
    app_name=example.name,
    deployment_config_name="CodeDeployDefault.ECSAllAtOnce",
    deployment_group_name="example",
    service_role_arn=example_aws_iam_role["arn"],
    auto_rollback_configuration={
        "enabled": True,
        "events": ["DEPLOYMENT_FAILURE"],
    },
    blue_green_deployment_config={
        "deployment_ready_option": {
            "action_on_timeout": "CONTINUE_DEPLOYMENT",
        },
        "terminate_blue_instances_on_deployment_success": {
            "action": "TERMINATE",
            "termination_wait_time_in_minutes": 5,
        },
    },
    deployment_style={
        "deployment_option": "WITH_TRAFFIC_CONTROL",
        "deployment_type": "BLUE_GREEN",
    },
    ecs_service={
        "cluster_name": example_aws_ecs_cluster["name"],
        "service_name": example_aws_ecs_service["name"],
    },
    load_balancer_info={
        "target_group_pair_info": {
            "prod_traffic_route": {
                "listener_arns": [example_aws_lb_listener["arn"]],
            },
            "target_groups": [
                {
                    "name": blue["name"],
                },
                {
                    "name": green["name"],
                },
            ],
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codedeploy"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := codedeploy.NewApplication(ctx, "example", &codedeploy.ApplicationArgs{
			ComputePlatform: pulumi.String("ECS"),
			Name:            pulumi.String("example"),
		})
		if err != nil {
			return err
		}
		_, err = codedeploy.NewDeploymentGroup(ctx, "example", &codedeploy.DeploymentGroupArgs{
			AppName:              example.Name,
			DeploymentConfigName: pulumi.String("CodeDeployDefault.ECSAllAtOnce"),
			DeploymentGroupName:  pulumi.String("example"),
			ServiceRoleArn:       pulumi.Any(exampleAwsIamRole.Arn),
			AutoRollbackConfiguration: &codedeploy.DeploymentGroupAutoRollbackConfigurationArgs{
				Enabled: pulumi.Bool(true),
				Events: pulumi.StringArray{
					pulumi.String("DEPLOYMENT_FAILURE"),
				},
			},
			BlueGreenDeploymentConfig: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigArgs{
				DeploymentReadyOption: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs{
					ActionOnTimeout: pulumi.String("CONTINUE_DEPLOYMENT"),
				},
				TerminateBlueInstancesOnDeploymentSuccess: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs{
					Action:                       pulumi.String("TERMINATE"),
					TerminationWaitTimeInMinutes: pulumi.Int(5),
				},
			},
			DeploymentStyle: &codedeploy.DeploymentGroupDeploymentStyleArgs{
				DeploymentOption: pulumi.String("WITH_TRAFFIC_CONTROL"),
				DeploymentType:   pulumi.String("BLUE_GREEN"),
			},
			EcsService: &codedeploy.DeploymentGroupEcsServiceArgs{
				ClusterName: pulumi.Any(exampleAwsEcsCluster.Name),
				ServiceName: pulumi.Any(exampleAwsEcsService.Name),
			},
			LoadBalancerInfo: &codedeploy.DeploymentGroupLoadBalancerInfoArgs{
				TargetGroupPairInfo: &codedeploy.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoArgs{
					ProdTrafficRoute: &codedeploy.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoProdTrafficRouteArgs{
						ListenerArns: pulumi.StringArray{
							exampleAwsLbListener.Arn,
						},
					},
					TargetGroups: codedeploy.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArray{
						&codedeploy.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs{
							Name: pulumi.Any(blue.Name),
						},
						&codedeploy.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs{
							Name: pulumi.Any(green.Name),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.CodeDeploy.Application("example", new()
    {
        ComputePlatform = "ECS",
        Name = "example",
    });

    var exampleDeploymentGroup = new Aws.CodeDeploy.DeploymentGroup("example", new()
    {
        AppName = example.Name,
        DeploymentConfigName = "CodeDeployDefault.ECSAllAtOnce",
        DeploymentGroupName = "example",
        ServiceRoleArn = exampleAwsIamRole.Arn,
        AutoRollbackConfiguration = new Aws.CodeDeploy.Inputs.DeploymentGroupAutoRollbackConfigurationArgs
        {
            Enabled = true,
            Events = new[]
            {
                "DEPLOYMENT_FAILURE",
            },
        },
        BlueGreenDeploymentConfig = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigArgs
        {
            DeploymentReadyOption = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs
            {
                ActionOnTimeout = "CONTINUE_DEPLOYMENT",
            },
            TerminateBlueInstancesOnDeploymentSuccess = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs
            {
                Action = "TERMINATE",
                TerminationWaitTimeInMinutes = 5,
            },
        },
        DeploymentStyle = new Aws.CodeDeploy.Inputs.DeploymentGroupDeploymentStyleArgs
        {
            DeploymentOption = "WITH_TRAFFIC_CONTROL",
            DeploymentType = "BLUE_GREEN",
        },
        EcsService = new Aws.CodeDeploy.Inputs.DeploymentGroupEcsServiceArgs
        {
            ClusterName = exampleAwsEcsCluster.Name,
            ServiceName = exampleAwsEcsService.Name,
        },
        LoadBalancerInfo = new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoArgs
        {
            TargetGroupPairInfo = new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoArgs
            {
                ProdTrafficRoute = new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoProdTrafficRouteArgs
                {
                    ListenerArns = new[]
                    {
                        exampleAwsLbListener.Arn,
                    },
                },
                TargetGroups = new[]
                {
                    new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs
                    {
                        Name = blue.Name,
                    },
                    new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs
                    {
                        Name = green.Name,
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.codedeploy.Application;
import com.pulumi.aws.codedeploy.ApplicationArgs;
import com.pulumi.aws.codedeploy.DeploymentGroup;
import com.pulumi.aws.codedeploy.DeploymentGroupArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupAutoRollbackConfigurationArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupDeploymentStyleArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupEcsServiceArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupLoadBalancerInfoArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupLoadBalancerInfoTargetGroupPairInfoProdTrafficRouteArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Application("example", ApplicationArgs.builder()
            .computePlatform("ECS")
            .name("example")
            .build());

        var exampleDeploymentGroup = new DeploymentGroup("exampleDeploymentGroup", DeploymentGroupArgs.builder()
            .appName(example.name())
            .deploymentConfigName("CodeDeployDefault.ECSAllAtOnce")
            .deploymentGroupName("example")
            .serviceRoleArn(exampleAwsIamRole.arn())
            .autoRollbackConfiguration(DeploymentGroupAutoRollbackConfigurationArgs.builder()
                .enabled(true)
                .events("DEPLOYMENT_FAILURE")
                .build())
            .blueGreenDeploymentConfig(DeploymentGroupBlueGreenDeploymentConfigArgs.builder()
                .deploymentReadyOption(DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs.builder()
                    .actionOnTimeout("CONTINUE_DEPLOYMENT")
                    .build())
                .terminateBlueInstancesOnDeploymentSuccess(DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs.builder()
                    .action("TERMINATE")
                    .terminationWaitTimeInMinutes(5)
                    .build())
                .build())
            .deploymentStyle(DeploymentGroupDeploymentStyleArgs.builder()
                .deploymentOption("WITH_TRAFFIC_CONTROL")
                .deploymentType("BLUE_GREEN")
                .build())
            .ecsService(DeploymentGroupEcsServiceArgs.builder()
                .clusterName(exampleAwsEcsCluster.name())
                .serviceName(exampleAwsEcsService.name())
                .build())
            .loadBalancerInfo(DeploymentGroupLoadBalancerInfoArgs.builder()
                .targetGroupPairInfo(DeploymentGroupLoadBalancerInfoTargetGroupPairInfoArgs.builder()
                    .prodTrafficRoute(DeploymentGroupLoadBalancerInfoTargetGroupPairInfoProdTrafficRouteArgs.builder()
                        .listenerArns(exampleAwsLbListener.arn())
                        .build())
                    .targetGroups(                    
                        DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs.builder()
                            .name(blue.name())
                            .build(),
                        DeploymentGroupLoadBalancerInfoTargetGroupPairInfoTargetGroupArgs.builder()
                            .name(green.name())
                            .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:codedeploy:Application
    properties:
      computePlatform: ECS
      name: example
  exampleDeploymentGroup:
    type: aws:codedeploy:DeploymentGroup
    name: example
    properties:
      appName: ${example.name}
      deploymentConfigName: CodeDeployDefault.ECSAllAtOnce
      deploymentGroupName: example
      serviceRoleArn: ${exampleAwsIamRole.arn}
      autoRollbackConfiguration:
        enabled: true
        events:
          - DEPLOYMENT_FAILURE
      blueGreenDeploymentConfig:
        deploymentReadyOption:
          actionOnTimeout: CONTINUE_DEPLOYMENT
        terminateBlueInstancesOnDeploymentSuccess:
          action: TERMINATE
          terminationWaitTimeInMinutes: 5
      deploymentStyle:
        deploymentOption: WITH_TRAFFIC_CONTROL
        deploymentType: BLUE_GREEN
      ecsService:
        clusterName: ${exampleAwsEcsCluster.name}
        serviceName: ${exampleAwsEcsService.name}
      loadBalancerInfo:
        targetGroupPairInfo:
          prodTrafficRoute:
            listenerArns:
              - ${exampleAwsLbListener.arn}
          targetGroups:
            - name: ${blue.name}
            - name: ${green.name}

The blueGreenDeploymentConfig controls how CodeDeploy provisions the green fleet and when it terminates blue tasks. The deploymentStyle property sets deploymentType to BLUE_GREEN and enables traffic control. The ecsService property identifies the target cluster and service, while loadBalancerInfo specifies the target groups and listener for traffic shifting. CodeDeploy creates a new task set, shifts traffic through the load balancer, and terminates the old task set after the configured wait time.

Deploy to EC2 with Classic ELB traffic control

Applications using Classic Elastic Load Balancers can perform blue/green deployments by discovering existing instances and shifting traffic through the load balancer.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.codedeploy.Application("example", {name: "example-app"});
const exampleDeploymentGroup = new aws.codedeploy.DeploymentGroup("example", {
    appName: example.name,
    deploymentGroupName: "example-group",
    serviceRoleArn: exampleAwsIamRole.arn,
    deploymentStyle: {
        deploymentOption: "WITH_TRAFFIC_CONTROL",
        deploymentType: "BLUE_GREEN",
    },
    loadBalancerInfo: {
        elbInfos: [{
            name: exampleAwsElb.name,
        }],
    },
    blueGreenDeploymentConfig: {
        deploymentReadyOption: {
            actionOnTimeout: "STOP_DEPLOYMENT",
            waitTimeInMinutes: 60,
        },
        greenFleetProvisioningOption: {
            action: "DISCOVER_EXISTING",
        },
        terminateBlueInstancesOnDeploymentSuccess: {
            action: "KEEP_ALIVE",
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.codedeploy.Application("example", name="example-app")
example_deployment_group = aws.codedeploy.DeploymentGroup("example",
    app_name=example.name,
    deployment_group_name="example-group",
    service_role_arn=example_aws_iam_role["arn"],
    deployment_style={
        "deployment_option": "WITH_TRAFFIC_CONTROL",
        "deployment_type": "BLUE_GREEN",
    },
    load_balancer_info={
        "elb_infos": [{
            "name": example_aws_elb["name"],
        }],
    },
    blue_green_deployment_config={
        "deployment_ready_option": {
            "action_on_timeout": "STOP_DEPLOYMENT",
            "wait_time_in_minutes": 60,
        },
        "green_fleet_provisioning_option": {
            "action": "DISCOVER_EXISTING",
        },
        "terminate_blue_instances_on_deployment_success": {
            "action": "KEEP_ALIVE",
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/codedeploy"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := codedeploy.NewApplication(ctx, "example", &codedeploy.ApplicationArgs{
			Name: pulumi.String("example-app"),
		})
		if err != nil {
			return err
		}
		_, err = codedeploy.NewDeploymentGroup(ctx, "example", &codedeploy.DeploymentGroupArgs{
			AppName:             example.Name,
			DeploymentGroupName: pulumi.String("example-group"),
			ServiceRoleArn:      pulumi.Any(exampleAwsIamRole.Arn),
			DeploymentStyle: &codedeploy.DeploymentGroupDeploymentStyleArgs{
				DeploymentOption: pulumi.String("WITH_TRAFFIC_CONTROL"),
				DeploymentType:   pulumi.String("BLUE_GREEN"),
			},
			LoadBalancerInfo: &codedeploy.DeploymentGroupLoadBalancerInfoArgs{
				ElbInfos: codedeploy.DeploymentGroupLoadBalancerInfoElbInfoArray{
					&codedeploy.DeploymentGroupLoadBalancerInfoElbInfoArgs{
						Name: pulumi.Any(exampleAwsElb.Name),
					},
				},
			},
			BlueGreenDeploymentConfig: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigArgs{
				DeploymentReadyOption: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs{
					ActionOnTimeout:   pulumi.String("STOP_DEPLOYMENT"),
					WaitTimeInMinutes: pulumi.Int(60),
				},
				GreenFleetProvisioningOption: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigGreenFleetProvisioningOptionArgs{
					Action: pulumi.String("DISCOVER_EXISTING"),
				},
				TerminateBlueInstancesOnDeploymentSuccess: &codedeploy.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs{
					Action: pulumi.String("KEEP_ALIVE"),
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.CodeDeploy.Application("example", new()
    {
        Name = "example-app",
    });

    var exampleDeploymentGroup = new Aws.CodeDeploy.DeploymentGroup("example", new()
    {
        AppName = example.Name,
        DeploymentGroupName = "example-group",
        ServiceRoleArn = exampleAwsIamRole.Arn,
        DeploymentStyle = new Aws.CodeDeploy.Inputs.DeploymentGroupDeploymentStyleArgs
        {
            DeploymentOption = "WITH_TRAFFIC_CONTROL",
            DeploymentType = "BLUE_GREEN",
        },
        LoadBalancerInfo = new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoArgs
        {
            ElbInfos = new[]
            {
                new Aws.CodeDeploy.Inputs.DeploymentGroupLoadBalancerInfoElbInfoArgs
                {
                    Name = exampleAwsElb.Name,
                },
            },
        },
        BlueGreenDeploymentConfig = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigArgs
        {
            DeploymentReadyOption = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs
            {
                ActionOnTimeout = "STOP_DEPLOYMENT",
                WaitTimeInMinutes = 60,
            },
            GreenFleetProvisioningOption = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigGreenFleetProvisioningOptionArgs
            {
                Action = "DISCOVER_EXISTING",
            },
            TerminateBlueInstancesOnDeploymentSuccess = new Aws.CodeDeploy.Inputs.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs
            {
                Action = "KEEP_ALIVE",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.codedeploy.Application;
import com.pulumi.aws.codedeploy.ApplicationArgs;
import com.pulumi.aws.codedeploy.DeploymentGroup;
import com.pulumi.aws.codedeploy.DeploymentGroupArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupDeploymentStyleArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupLoadBalancerInfoArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigGreenFleetProvisioningOptionArgs;
import com.pulumi.aws.codedeploy.inputs.DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Application("example", ApplicationArgs.builder()
            .name("example-app")
            .build());

        var exampleDeploymentGroup = new DeploymentGroup("exampleDeploymentGroup", DeploymentGroupArgs.builder()
            .appName(example.name())
            .deploymentGroupName("example-group")
            .serviceRoleArn(exampleAwsIamRole.arn())
            .deploymentStyle(DeploymentGroupDeploymentStyleArgs.builder()
                .deploymentOption("WITH_TRAFFIC_CONTROL")
                .deploymentType("BLUE_GREEN")
                .build())
            .loadBalancerInfo(DeploymentGroupLoadBalancerInfoArgs.builder()
                .elbInfos(DeploymentGroupLoadBalancerInfoElbInfoArgs.builder()
                    .name(exampleAwsElb.name())
                    .build())
                .build())
            .blueGreenDeploymentConfig(DeploymentGroupBlueGreenDeploymentConfigArgs.builder()
                .deploymentReadyOption(DeploymentGroupBlueGreenDeploymentConfigDeploymentReadyOptionArgs.builder()
                    .actionOnTimeout("STOP_DEPLOYMENT")
                    .waitTimeInMinutes(60)
                    .build())
                .greenFleetProvisioningOption(DeploymentGroupBlueGreenDeploymentConfigGreenFleetProvisioningOptionArgs.builder()
                    .action("DISCOVER_EXISTING")
                    .build())
                .terminateBlueInstancesOnDeploymentSuccess(DeploymentGroupBlueGreenDeploymentConfigTerminateBlueInstancesOnDeploymentSuccessArgs.builder()
                    .action("KEEP_ALIVE")
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:codedeploy:Application
    properties:
      name: example-app
  exampleDeploymentGroup:
    type: aws:codedeploy:DeploymentGroup
    name: example
    properties:
      appName: ${example.name}
      deploymentGroupName: example-group
      serviceRoleArn: ${exampleAwsIamRole.arn}
      deploymentStyle:
        deploymentOption: WITH_TRAFFIC_CONTROL
        deploymentType: BLUE_GREEN
      loadBalancerInfo:
        elbInfos:
          - name: ${exampleAwsElb.name}
      blueGreenDeploymentConfig:
        deploymentReadyOption:
          actionOnTimeout: STOP_DEPLOYMENT
          waitTimeInMinutes: 60
        greenFleetProvisioningOption:
          action: DISCOVER_EXISTING
        terminateBlueInstancesOnDeploymentSuccess:
          action: KEEP_ALIVE

The greenFleetProvisioningOption with DISCOVER_EXISTING tells CodeDeploy to find existing instances rather than creating new ones. The deploymentReadyOption with STOP_DEPLOYMENT pauses the deployment for manual validation. The terminateBlueInstancesOnDeploymentSuccess action of KEEP_ALIVE preserves old instances after deployment, allowing you to validate before cleanup. Traffic shifts through the Classic ELB specified in elbInfos.

Beyond these examples

These snippets focus on specific deployment group features: EC2 tag-based targeting and ECS service deployments, blue/green deployments with traffic control, and rollback configuration and deployment notifications. They’re intentionally minimal rather than full deployment pipelines.

The examples rely on pre-existing infrastructure such as CodeDeploy applications, IAM roles with deployment permissions, EC2 instances or ECS clusters/services, load balancers and target groups, and SNS topics or CloudWatch alarms. They focus on configuring the deployment group rather than provisioning the surrounding infrastructure.

To keep things focused, common deployment group patterns are omitted, including:

  • Auto Scaling group integration (autoscalingGroups)
  • On-premises instance targeting (onPremisesInstanceTagFilters)
  • Custom deployment configurations (deploymentConfigName)
  • Termination hooks for Auto Scaling (terminationHookEnabled)

These omissions are intentional: the goal is to illustrate how each deployment group feature is wired, not provide drop-in deployment modules. See the CodeDeploy DeploymentGroup resource reference for all available configuration options.

Let's configure AWS CodeDeploy Deployment Groups

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Blue/Green Deployments
Why is my Auto Scaling Group conflicting with Pulumi state when using COPY_AUTO_SCALING_GROUP?
Using COPY_AUTO_SCALING_GROUP with greenFleetProvisioningOption causes CodeDeploy to create a new Auto Scaling Group that isn’t managed by Pulumi, leading to configuration conflicts. Use DISCOVER_EXISTING with separate blue and green Auto Scaling Groups instead.
How do I set up blue/green deployments for ECS?
Configure four key components: (1) deploymentStyle with deploymentType: "BLUE_GREEN" and deploymentOption: "WITH_TRAFFIC_CONTROL", (2) blueGreenDeploymentConfig for deployment timing and termination behavior, (3) ecsService with your cluster and service names, and (4) loadBalancerInfo with target group pairs for traffic routing.
How do I set up blue/green deployments with Classic ELB?
Set deploymentStyle to blue/green with traffic control, configure loadBalancerInfo with elbInfos pointing to your Classic ELB, and use greenFleetProvisioningOption with action: "DISCOVER_EXISTING" to reference existing Auto Scaling Groups.
What's the difference between in-place and blue/green deployments?
In-place deployments update instances in the existing environment, while blue/green deployments provision a new environment (green) and shift traffic from the old environment (blue). Blue/green requires deploymentStyle configuration and load balancer setup.
IAM & Permissions
What IAM role is required for CodeDeploy deployments?
Create an IAM role with a trust policy allowing codedeploy.amazonaws.com to assume it, then attach the AWS managed policy arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole. Pass this role’s ARN to serviceRoleArn.
Instance Targeting & Selection
How do I target specific EC2 instances for deployment?
Use ec2TagSets with ec2TagFilters to specify key-value tag filters. Each tag set can contain multiple filters, and instances must match all filters within a set to be targeted.
What happens to EC2 instances launched during an active deployment?
By default (outdatedInstancesStrategy: "UPDATE"), new instances receive the deployed application revision. Set to "IGNORE" if you want mid-deployment instances to skip the current deployment.
Deployment Configuration
What deployment configurations are available?
The default is CodeDeployDefault.OneAtATime, which deploys to one instance at a time. You can specify other built-in configurations (like CodeDeployDefault.ECSAllAtOnce for ECS) or custom configurations using deploymentConfigName.
How do I enable automatic rollback on deployment failure?
Configure autoRollbackConfiguration with enabled: true and specify trigger events like DEPLOYMENT_FAILURE in the events array.
Monitoring & Notifications
How do I get notified about deployment events?
Set up triggerConfigurations with an SNS topic ARN, a trigger name, and the events you want to monitor (such as DeploymentFailure, DeploymentSuccess, or DeploymentStop).
How do I use CloudWatch alarms to monitor deployments?
Configure alarmConfiguration with enabled: true and provide an array of CloudWatch alarm names in the alarms field. CodeDeploy will monitor these alarms during deployment.

Using a different cloud?

Explore integration guides for other cloud providers: