Cross-account CloudFormation deployments¶
Attini supports deploying CloudFormation across AWS accounts. To enable cross-account deployments we need to do the following:
Create an IAM Role in the target account that the Attini Framework can assume.
Configure the ExecutionRoleArn in the Attini deployment plan to reference the IAM Role from step 1.
Apply an S3 bucket policy to the
attini-artifact-store-{Region}-{AccountId}
bucket that allows the IAM Role from step 1 to get the template from the bucket.
In the example below, the Attini Framework is deployed into eu-west-1 in account 111111111111, and we deploy a CloudFormation stack into account 222222222222.
1. Create a custom execution IAM Role¶
First, we need to create an IAM Role in the target AWS account.
This IAM Role requires permission to manage all the resources in your CloudFormation Stack OR the iam:PassRole
permission if you are using a Stack role.
It also needs permissions to deploy CloudFormation and accessing S3 Objects from attini-artifact-store-{Region**}-{AccountId*}
bucket.
We must also ensure that the Attini Framework can assume the IAM Role.
This is done by allowing the IAM Role to be assumed by the arn:aws:iam::{AccountId*}:role/attini/attini-action-role-{Region**}
IAM Role.
The example IAM Roles below have full EC2 access. However, you should configure the IAM Role to only have access to resources the stack should manage.
Example role configuration
{
"Role": {
"RoleName": "custom-execution-role",
"Arn": "arn:aws:iam::222222222222:role/custom-execution-role",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:role/attini/attini-action-role-eu-west-1"
]
},
"Action": "sts:AssumeRole"
}]
},
"Policies": [{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::attini-artifact-store-eu-west-1-111111111111/*"
},
{
"Effect": "Allow",
"Action": [
"cloudformation:Describe*",
"cloudformation:List*",
"cloudformation:Get*",
"cloudformation:ValidateTemplate",
"cloudformation:CreateStack",
"cloudformation:TagResource",
"cloudformation:UntagResource",
"cloudformation:CancelUpdateStack",
"cloudformation:CreateChangeSet",
"cloudformation:ContinueUpdateRollback",
"cloudformation:UpdateStack",
"cloudformation:DeleteStack"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
],
"Description": "Cross account deployment role"
}
}
Example role configured in CloudFormation
CreateS3ExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: custom-execution-role
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
AWS: arn:aws:iam::111111111111:role/attini/attini-action-role-eu-west-1
Version: 2012-10-17
Policies:
- PolicyName: !Ref AWS::StackName
PolicyDocument:
Version: 2012-10-17
Statement:
- Action: s3:GetObject
Effect: Allow
Resource: arn:aws:s3:::attini-artifact-store-eu-west-1-111111111111/*
- Action:
- cloudformation:Describe*
- cloudformation:List*
- cloudformation:Get*
- cloudformation:ValidateTemplate
- cloudformation:CreateStack
- cloudformation:TagResource
- cloudformation:UntagResource
- cloudformation:CancelUpdateStack
- cloudformation:CreateChangeSet
- cloudformation:ContinueUpdateRollback
- cloudformation:UpdateStack
- cloudformation:DeleteStack
Effect: Allow
Resource: “*”
- Action: ec2:*
Effect: Allow
Resource: “*”
2. Configure the step in the deployment plan¶
We need to configure the deployment plan to use our execution IAM Role when deploying the template. This is done by setting the ExecutionRoleArn property in the AttiniCfn step.
Example of a deployment plan step using an ExecutionRoleArn
Resources:
CrossAccountDeploymentPlan:
Type: Attini::Deploy::DeploymentPlan
Properties:
DeploymentPlan:
StartAt: DeployVpc
States:
DeployVpc:
Type: AttiniCfn
Properties:
Template: /network/vpc.yaml
StackName: vpc
ExecutionRoleArn: arn:aws:iam::222222222222:role/custom-execution-role
End: true
3. Apply an s3 bucket policy¶
Because we are using a custom execution IAM Role we need to make sure that it’s allowed to read the CloudFormation template from S3.
This is easily done by applying an S3 Bucket Policy
to the attini-artifact-store-{Region}-{AccountId}
bucket in the account we are performing the deployment from.
Example of an S3 Bucket Policy
{
"Version":"2012-10-17",
"Statement": [
{
"Sid": "AllowCrossAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::222222222222:role/custom-execution-role"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::attini-artifact-store-eu-west-1-111111111111/*"
}
]
}
That’s it! The deployment plan will now deploy the stack to the target account.