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 FREEFrequently Asked Questions
Blue/Green Deployments
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.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.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.deploymentStyle configuration and load balancer setup.IAM & Permissions
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
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.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
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.autoRollbackConfiguration with enabled: true and specify trigger events like DEPLOYMENT_FAILURE in the events array.Monitoring & Notifications
triggerConfigurations with an SNS topic ARN, a trigger name, and the events you want to monitor (such as DeploymentFailure, DeploymentSuccess, or DeploymentStop).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: