The aws:codedeploy/deploymentGroup:DeploymentGroup resource, part of the Pulumi AWS provider, defines a CodeDeploy deployment group that specifies which instances or services receive application revisions and how deployments execute. This guide focuses on three capabilities: EC2 tag-based targeting, ECS blue/green deployments, and Classic ELB traffic shifting.
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 roles, and compute resources.
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 for instances matching the ec2TagFilters criteria and deploys the application revision to them. The ec2TagSets property groups filters together; instances must match all filters within a set. The triggerConfigurations property sends SNS notifications on deployment events like failures. The autoRollbackConfiguration automatically reverts to the previous revision when deployments fail.
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 deploymentStyle property sets the deployment type to BLUE_GREEN and enables traffic control through the load balancer. The blueGreenDeploymentConfig controls timing: deploymentReadyOption determines when traffic shifts (here, immediately), and terminateBlueInstancesOnDeploymentSuccess waits 5 minutes before terminating old tasks. The loadBalancerInfo property connects the deployment to your ALB listener and target groups, enabling CodeDeploy to shift traffic between blue and green task sets.
Deploy to EC2 with Classic ELB traffic control
Applications using Classic Load Balancers can perform blue/green deployments by discovering existing instances and controlling when old instances terminate.
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 use pre-provisioned instances rather than creating new ones. The deploymentReadyOption with STOP_DEPLOYMENT pauses for manual approval before shifting traffic. The terminateBlueInstancesOnDeploymentSuccess with KEEP_ALIVE preserves old instances after deployment, allowing you to manage their lifecycle separately.
Beyond these examples
These snippets focus on specific deployment group features: EC2 tag-based targeting and ECS service deployments, blue/green deployment configuration, and load balancer integration and traffic control. 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, ECS clusters, or load balancers, and SNS topics for notifications. 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)
- Alarm-based deployment controls (alarmConfiguration)
- 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 CI/CD 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 FREEFrequently Asked Questions
Blue/Green Deployments
greenFleetProvisioningOption with the COPY_AUTO_SCALING_GROUP action 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.deploymentStyle with deploymentType: BLUE_GREEN and deploymentOption: WITH_TRAFFIC_CONTROL. Configure ecsService with your cluster and service names, and use loadBalancerInfo with targetGroupPairInfo to define production traffic routes and target groups.loadBalancerInfo with elbInfos containing your ELB name, and set deploymentStyle to BLUE_GREEN with WITH_TRAFFIC_CONTROL.IAM & Permissions
codedeploy.amazonaws.com to assume it, then attach the AWS managed policy arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole. Pass the role’s ARN to serviceRoleArn.Instance Targeting & Scaling
ec2TagFilters or ec2TagSets to specify tag-based filters. Each filter includes key, type (such as KEY_AND_VALUE), and value to match your instances.outdatedInstancesStrategy controls this behavior. The default UPDATE ensures new instances receive the deployment. Set to IGNORE if you want new instances to skip the current deployment.Monitoring & Rollback
autoRollbackConfiguration with enabled: true and specify events such as DEPLOYMENT_FAILURE to trigger automatic rollback.alarmConfiguration to specify alarm names and set enabled: true. CodeDeploy will monitor these alarms during deployment.triggerConfigurations with triggerEvents (like DeploymentFailure), a triggerName, and triggerTargetArn pointing to your SNS topic.Deployment Configuration
CodeDeployDefault.OneAtATime, which deploys to one instance at a time. You can customize this using deploymentConfigName.deploymentStyle to choose between in-place deployments (update existing instances) or blue/green deployments (provision new instances). Set deploymentOption to WITH_TRAFFIC_CONTROL to route traffic through a load balancer.pulumi import with the format app_name:deployment_group_name, for example: pulumi import aws:codedeploy/deploymentGroup:DeploymentGroup example my-application:my-deployment-group.Using a different cloud?
Explore integration guides for other cloud providers: