Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross account S3 access through CloudFormation CLi

I am trying to create a CloudFormation Stack using the AWS CLI by running the following command:

aws cloudformation create-stack --debug --stack-name ${stackName} --template-url ${s3TemplatePath} --parameters '${parameters}' --region eu-west-1

The template resides in an S3 bucket in the another account, lets call this account 456. The bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::123:root"
                ]
            },
            "Action": [
                "s3:*"
            ],
            "Resource": "arn:aws:s3:::cloudformation.template.eberry.digital/*"
        }
    ]
}

("Action: * " is for debugging).

Now for a twist. I am logged into account 456 and I run

aws sts assume-role --role-arn arn:aws:iam::123:role/delegate-access-to-infrastructure-account-role --role-session-name jenkins

and the set the correct environment variables to access 123. The policy attached to the role that I assume allow the user Administrator access while I debug - which still doesn't work.

aws s3api list-buckets

then display the buckets in account 123.

To summarize:

  • Specifying a template in an S3 bucket owned by account 456, into CloufFormation in the console, while logged into account 123 works.
  • Specifying a template in an S3 bucket owned by account 123, using the CLI, works.
  • Specifying a template in an S3 bucket owned by account 456, using the CLI, doesn't work.

The error:

An error occurred (ValidationError) when calling the CreateStack operation: S3 error: Access Denied For more information check http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html

I don't understand what I am doing wrong and would by thankful for any ideas. In the meantime I will upload the template to all accounts that will use it.

like image 528
Jonatan Avatar asked Jan 08 '18 12:01

Jonatan


1 Answers

Amazon S3 provides cross-account access through the use of bucket policies. These are IAM resource policies (which are applied to resources—in this case an S3 bucket—rather than IAM principals: users, groups, or roles). You can read more about how Amazon S3 authorises access in the Amazon S3 Developer Guide.

I was a little confused about which account is which, so instead I'll just say that you need this bucket policy when you want to deploy a template in a bucket owned by one AWS account as a stack in a different AWS account. For example, the template is in a bucket owned by AWS account 111111111111 and you want to use that template to deploy a stack in AWS account 222222222222. In this case, you'll need to be logged in to account 222222222222 and specify that account as the principal in the bucket policy.

The following is an example bucket policy that provides access to another AWS account; I use this on my own CloudFormation templates bucket.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::AWS_ACCOUNT_ID_WITHOUT_HYPHENS:root"
      },
      "Action": [
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:GetObjectTagging",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::S3_BUCKET_NAME",
        "arn:aws:s3:::S3_BUCKET_NAME/*"
      ]
    }
  ]
}

You'll need to use the 12-digit account identifier for the AWS account you want to provide access to, and the name of the S3 bucket (you can probably use "Resource": "*", but I haven't tested this).

like image 172
Calrion Avatar answered Sep 30 '22 11:09

Calrion