-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Add account/region params and setup permissions so an EcsDeployAction in a pipeline in Account A can deploy to a different region in Account B.
Use Case
To keep pipeline accounts separate from environment accounts and to support multi-region deployments.
Proposed Solution
I don't have an elegant proposed solution but I was able to achieve a workaround described below.
Other
I was able to cobble together a workaround by:
- copy
EcsDeployActionto a new module (I called itEcsMultiAccountDeployin examples below), adding in props foraccountandregionwhich are passed to super and removing the role code. - granting the deploy role from the cdk boostrap process the ability to deploy to ecs in each environment account via a cdk stack.
- passing the deploy role from the cdk bootstrap to the new deploy action described in step 1.
There may be a better approach but this worked for me. The reason for using the deploy role from cdk bootstrap is because it already has access to the build artifacts. Maybe there could be a way to augment the permissions of these roles during bootstrapping.
Below are the snippets of my workaround.
Important pieces from EcsMultiAccountDeploy
export interface EcsMultiAccountDeployActionProps extends EcsDeployActionProps {
account: string | undefined;
region: string | undefined;
}
...
constructor(props: EcsMultiAccountDeployActionProps) {
super({
...props,
category: codepipeline.ActionCategory.DEPLOY,
provider: 'ECS',
artifactBounds: deployArtifactBounds(),
inputs: [determineInputArtifact(props)],
resource: props.service,
});
this.props = props;
}In the build stack which contains the pipeline:
// this is the deploy role created by the cdk bootstrap process
const deployRole = iam.Role.fromRoleArn(this, `${stageName}EcsDeployRole`, deployRoleArn);
const action = new EcsMultiAccountDeployAction({
actionName: `${stageName}EcsDeploy`,
service: ecsService,
input: appArtifact,
runOrder: stage.nextSequentialRunOrder(),
account: env.account,
region: env.region,
role: deployRole,
});
stage.addActions(action);In the application stack:
updateDeployRole(props: UpdateDeployRoleProps) {
const { deployRoleArn } = props;
// this is the deploy role created by the cdk bootstrap process
const role = iam.Role.fromRoleArn(this, 'BootstrapDeployRole', deployRoleArn);
// the below is necessary for the ecs depoly
role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: [
'ecs:DescribeServices',
'ecs:DescribeTaskDefinition',
'ecs:DescribeTasks',
'ecs:ListTasks',
'ecs:RegisterTaskDefinition',
'ecs:UpdateService',
],
resources: ['*'],
}));
role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['iam:PassRole'],
resources: ['*'],
conditions: {
StringEqualsIfExists: {
'iam:PassedToService': [
'ec2.amazonaws.com',
'ecs-tasks.amazonaws.com',
],
},
},
}));
}- 👋 I may be able to implement this feature request
-
⚠️ This feature might incur a breaking change
This is a 🚀 Feature Request