AWS - Cloud formation Script to create S3 bucket and Distribution

Mohammed Irfan picture Mohammed Irfan · Dec 17, 2013 · Viewed 10.1k times · Source

I am working on the AWS creation of the bucket and distribution using the scripts. I have created a script and running the stack template script in AWS cloud formation console.

I am creating the bucketpolicy for S3 bucket using the script and canonical ID. Once I create a bucket policy I want to assign it to the "OriginAccessIdentity" dynamically in the script. I want to add the id generated from the bucket policy to "OriginAccessIdentity" attributes.

How to achieve this functionality?

Script :

{
    "AWSTemplateFormatVersion" : "2010-09-09",

    "Description" : "AWS CloudFormation Template S3_With_CloudFront_Distribution",

    "Parameters" : {
        "bucketname" : {
          "Type" : "String",
          "Description" : "test"          
        },

        "cannonicalid" : {
          "Type" : "String",
          "Description" : "234213523145314534523452345234523452345"       
        }
    },

     "Conditions" : {
        "CreateProdResources" : {"Fn::Equals" : [{"Ref" : "EnvType"}, "dev"]}
    },

    "Resources" : {
        "testbucket" : {
          "Type" : "AWS::S3::Bucket",
          "Properties" : {      
            "BucketName" : { "Ref" : "bucketname" },          
            "WebsiteConfiguration" : {
               "IndexDocument" : "index.html"              
            }
          }
        },


        "mybucketpolicy" : {
           "Type" : "AWS::S3::BucketPolicy",
           "Properties" : {
              "PolicyDocument" : {
                 "Id" : "MyPolicy",
                 "Statement" : [ {
                    "Sid" : "Grant a CloudFront Origin Identity access to support private content",
                    "Action" : [ "s3:GetObject" ],
                    "Effect" : "Allow",
                    "Resource" : { "Fn::Join" : [
                          "", [ "arn:aws:s3:::", { "Ref" : "testbucket" } , "/*" ]
                       ] },
                    "Principal" : {
                       "CanonicalUser":{ "Ref" : "cannonicalid" }
                    }
                 } ]
              },
              "Bucket" : { "Ref" : "testbucket" }
              }
        },


        "testdistribution" : {
            "Type" : "AWS::CloudFront::Distribution",
            "Properties" : {
               "DistributionConfig" : {
                   "Origins" : [ {
                           "Id" : "S3Origin",
                           "DomainName" : { "Fn::GetAtt" : [ "testbucket", "DomainName" ] },
                           "S3OriginConfig" : {
                               "OriginAccessIdentity" : "How to configure the id dynamically here"
                           }
                       }
                   ],

                   "Enabled" : "true",
                   "Comment" : "",
                   "DefaultRootObject" : "index.html",                    
                   "Aliases" : [ "test.com" ],

                   "CacheBehaviors" : [ {
                            "TargetOriginId" : "S3Origin",
                            "ForwardedValues" : {
                                "QueryString" : "false"
                            },                            
                            "ViewerProtocolPolicy" : "allow-all",
                            "MinTTL" : "1",
                            "PathPattern" : "resources/*.json"
                        }
                   ],
                   "DefaultCacheBehavior" : {
                       "TargetOriginId" : "S3Origin",
                       "ForwardedValues" : {
                           "QueryString" : "false"
                        },                       
                       "ViewerProtocolPolicy" : "allow-all",
                       "MinTTL" : "1"
                   }
                }
            }
        }
    },
    "Outputs" : {
        "DistributionId" : {
            "Description" : "CloudFront Distribution Id",
            "Value" : { "Ref" : "testdistribution" }
        },
        "DistributionName" : {
             "Description" : "URL to access the CloudFront distribution",
             "Value" : { "Fn::Join" : [ "", ["http://", {"Fn::GetAtt" : ["testdistribution", "DomainName"]} ]]}
        },
        "S3OriginDNSName" : {
             "Description" : "Name of S3 bucket to hold website content.",
             "Value" : { "Fn::GetAtt" : [ "testbucket", "DomainName"] }
        }
  }
}  

Answer

jjanzic picture jjanzic · Nov 20, 2017

Since November 2, 2017 CloudFormation supports this using AWS::CloudFront::CloudFrontOriginAccessIdentity resource.

With a origin access identity resource defined as:

"OriginAccessId": {
    "Type": "AWS::CloudFront::CloudFrontOriginAccessIdentity",
    "Properties": {
        "CloudFrontOriginAccessIdentityConfig": {
            "Comment": "MyDescription"
        }
    }
}

you can reference it in the distribution config with:

"OriginAccessIdentity" : { 
  "Fn::Sub": "origin-access-identity/cloudfront/${OriginAccessId}"
}