How do I deploy artifacts to Amazon S3 in a different AWS account using CodePipeline and a canned ACL?

Last updated: 2022-01-05

I want to deploy artifacts to an Amazon Simple Storage Service (Amazon S3) bucket in a different account. Is there a way to do that using AWS CodePipeline with an Amazon S3 deploy action provider and a canned Access Control List (ACL)?

Resolution

Note: The following example procedure assumes the following:

  • You have two AWS accounts: A development account and a production account.
  • The input bucket in the development account is called codepipeline-input-bucket (with versioning activated).
  • The default artifact bucket in the development account is called codepipeline-us-east-1-0123456789.
  • The output bucket in the production account is called codepipeline-output-bucket.
  • You're deploying artifacts from the development account to an S3 bucket in the production account.
  • You're using a canned ACL to provide the bucket owner in the production account with access to the objects owned by the development account.
    Note: To deploy artifacts and set the production account as object owner, see How do I deploy artifacts to Amazon S3 in a different account using CodePipeline?

Create a CodePipeline in the development account

1.    Open the CodePipeline console. Then, choose Create pipeline.

2.    For Pipeline name, enter a name for your pipeline. For example: crossaccountdeploy.

Note: The Role name text box is populated automatically with the service role name AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy. You can also choose another, existing service role.

3.    Expand the Advanced settings section.

4.    For Artifact store, choose Default location.
Note: You can select Custom location if that's required for your use case.

5.    For Encryption key, select Default AWS Managed Key.

6.    Choose Next.

7.    On the Add source stage page, for Source provider, choose Amazon S3.

8.    For Bucket, enter the name of your development input S3 bucket. For example: codepipeline-input-bucket.
Important: The input bucket must have versioning activated to work with CodePipeline.

9.    For S3 object key, enter sample-website.zip.

Important: To use an example AWS website instead of your own website, see Tutorial: Create a pipeline that uses Amazon S3 as a deployment provider. Then, search for "sample static website" in the Prerequisites of the 1: Deploy Static Website Files to Amazon S3 section.

10.    For Change detection options, choose Amazon CloudWatch Events (recommended).

11.    Choose Next.

12.    On the Add build stage page, choose Skip build stage. Then, choose Skip.

13.    On the Add deploy stage page, for Deploy provider, choose Amazon S3.

14.    For Region, choose the AWS Region that your output S3 bucket is in. For example: US East (N. Virginia).

15.    For Bucket, enter the name of your production output S3 bucket. For example: codepipeline-output-bucket.

16.    Select the Extract file before deploy check box.
Note: If needed, enter a path for Deployment path.

17.    Expand Additional configuration.

18.    For Canned ACL, choose bucket-owner-full-control.
Note: The bucket-owner-full-control gives the bucket owner in the production account full access to the objects deployed and owned by the development account. For more information, see Canned ACL.

19.    Choose Next.

20.    Choose Create pipeline. The pipeline runs, but the source stage fails. The following error appears: "The object with key 'sample-website.zip' does not exist."

The Upload the sample website to the input bucket section of this article describes how to resolve this error.

Configure a CodePipeline service role with an AWS Identity and Access Management (IAM) policy that adds S3 access for the output bucket of the production account

1.    Open the IAM console in the development account.

2.    In the navigation pane, choose Policies. Then, choose Create policy.

3.    Choose the JSON tab. Then, enter the following policy into the JSON editor:

Important: Replace codepipeline-output-bucket with your production output S3 bucket's name.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::codepipeline-output-bucket/*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::codepipeline-output-bucket"
        }
    ]
}

4.    Choose Review policy.

5.    For Name, enter a name for the policy. For example: prodbucketaccess.

6.    Choose Create policy.

7.    In the navigation pane, choose Roles.

8.    From the list of roles, choose AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy. This is the CodePipeline service role.
Note: You can use your own service role, if required for your use case.

9.    Choose Attach polices.

10.    Select the policy that you created (prodbucketaccess). Then, choose Attach policy to grant CodePipeline access to the production output S3 bucket.

Configure the output bucket in the production account to allow access from the development account

1.    Open the Amazon S3 console in the production account.

2.    In the Bucket name list, choose your production output S3 bucket. For example: codepipeline-output-bucket.

3.    Choose Permissions. Then, choose Bucket Policy.

4.    In the text editor, enter the following policy, and then choose Save:

Important: Replace dev-account-id with your development environment's AWS account ID. Replace codepipeline-output-bucket with your production output S3 bucket's name.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::dev-account-id:root"
            },
            "Action": "s3:Put*",
            "Resource": "arn:aws:s3:::codepipeline-output-bucket/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::dev-account-id:root"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::codepipeline-output-bucket"
        }
    ]
}

Upload the sample website to the input bucket

1.    Open the Amazon S3 console in the development account.

2.    In the Bucket name list, choose your development input S3 bucket. For example: codepipeline-input-bucket.

3.    Choose Upload. Then, choose Add files.

4.    Select the sample-website.zip file that you downloaded.

5.    Choose Upload to run the pipeline. When the pipeline runs, the following occurs:

  • The source action selects the sample-website.zip from the development input S3 bucket (codepipeline-input-bucket). Then, the source action places the zip file as a source artifact inside the default artifact bucket in the development account (codepipeline-us-east-1-0123456789).
  • In the deploy action, the CodePipeline service role (AWSCodePipelineServiceRole-us-east-1-crossaccountdeploy) uses its access to deploy to the production output S3 bucket (codepipeline-output-bucket). The deploy action also applies the canned ACL bucket-owner-full-control.

Note: The development account is the owner of the extracted objects in the production output S3 bucket (codepipeline-output-bucket). The bucket owner in the production account also has full access to the deployed artifacts.


Did this article help?


Do you need billing or technical support?