Search code examples
amazon-web-servicesamazon-s3aws-cloudformationamazon-cloudfront

How to access cross region resources in Cloudformation


I have a static website stack that I deploy to us-east-1. I only need the s3 bucket to be deployed in the eu-west-1 region, so to achieve this I used Stack Sets like this;

  StackSet:
    Type: AWS::CloudFormation::StackSet
    Properties:
      Description: Multiple S3 buckets in multiple regions
      PermissionModel: SELF_MANAGED
 
      StackInstancesGroup:
        - DeploymentTargets:
            Accounts:
              - !Ref "AWS::AccountId"
          Regions: 
            - eu-west-1
 
      StackSetName: !Sub "AppBucketStack"
      TemplateBody: |
        AWSTemplateFormatVersion: 2010-09-09
        Description: Create a S3 bucket
        Resources:
          WebsiteBucket:
            Type: AWS::S3::Bucket
            DeletionPolicy: Retain
            UpdateReplacePolicy: Retain
            Properties:
              BucketName: !Join
                - ''
                - - ameta-app-
                  - !Ref 'AWS::Region'
                  - '-'
                  - !Ref 'AWS::AccountId'
              AccessControl: Private
              CorsConfiguration:
                CorsRules:
                - AllowedHeaders:
                  - "*"
                  AllowedMethods:
                  - GET
                  - POST
                  - PUT
                  AllowedOrigins:
                  - "*"
                  MaxAge: 3600
              WebsiteConfiguration:
                IndexDocument: index.html
                ErrorDocument: 404.html
              Tags:
                - Key: Company
          WebsiteBucketPolicy:
            Type: AWS::S3::BucketPolicy
            Properties:
              Bucket: !Ref 'WebsiteBucket'
              PolicyDocument:
                Version: '2012-10-17'
                Statement:
                  - Action:
                      - s3:GetObject
                    Effect: Allow
                    Resource: !Join
                      - ''
                      - - 'arn:aws:s3:::'
                      - !Ref 'WebsiteBucket'
                      - /*
                    Principal:
                      CanonicalUser: !GetAtt OriginAccessIdentity.S3CanonicalUserId

However now I need to address the bucket's domain name(!GetAtt WebsiteBucket.DomainName) in cloudfront which is being deployed in us-east-1. It seems that I can't use the output of the StackSet since the resources are different regions.

Do you guys have any suggestions?


Solution

  • It seems that I can't use the output of the StackSet since the resources are different regions.

    That's correct. You can't reference outputs across regions nor accounts. CloudFormation (CFN) is region-specific. The easiest way is to deploy your resources in us-east-1 and the pass their outputs as parameters to the second stack in different region. You can do it manually, or automatically using AWS CLI or SDK from your local workstation or ec2 instance.

    But if want to keep everything within CFN, you would have to develop a custom resource for the second stack. The resource would be in the form of a lambda function which would use AWS SDK to get the outputs from us-east-1 and pass them to your stack in different region.