4m1r
4m1r

Reputation: 12552

AWS Cloudformation Template with variable from current CFT

I'm having a hard time figuring out how to use a value from a current stack when applying a new change-set template. As you can imagine, many of the current configuration parameters of a stack are going to be needed to re-apply a new set. However, I can't really find the definitive documentation on how to do this.

So far, I'm looking at something like this.

  "DomainName": {
    "Value": {"Ref": "AWS::S3::Bucket::DomainName"}
  }

Where I'm hoping the change set generator will use this Ref value to get the current domain name of the configured S3 bucket.

Maybe this is not how change-sets work at all? I would imagine the configuration is merged with the previous configuration at run-time, so you should have access to some of the previous instance variables?

Thanks.

Upvotes: 0

Views: 1933

Answers (1)

Michal Gasek
Michal Gasek

Reputation: 6413

What you define in CloudFormation template are so called Resources. Example of resources are:

  • AWS::S3::Bucket
  • AWS::EC2::Instance
  • AWS::EC2::VPC

Each resource has Properties that you define when declaring them in a CloudFormation template. Let's take AWS::S3::Bucket resource as an example.

{
  "Resources" : {

    "MyBucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "BucketName" : "my-bucket-name"
      }
    }

  }
}

BucketName is a property of "MyBucket" resource.

Resources typically also have Return Values. A return value is something that you can use in your CloudFormation templates to build cross-reference logic and relationships between resources. Each resource usually has a "default" return value, and this value is returned when you reference a certain resource using Ref intrinsic function within the template. In case of AWS::S3::Bucket resource, this "default" return value is simply a BucketName. This means that if you would like to use my-bucket-name somewhere else in your template, you would use Ref intrinsic function on MyBucket resource. As an example, we can create AWS::S3::BucketPolicy resource, BucketName (in fact Bucket) is one of properties of AWS::S3::BucketPolicy. Let's do it then:

{
  "Resources" : {

    "MyBucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "BucketName" : "my-bucket-name"
      }
    },

    "MyBucketPolicy" : {
      "Type" : "AWS::S3::BucketPolicy",
      "Properties" : {
        "Bucket" : { "Ref" : "MyBucket" },
        "PolicyDocument" : JSON_STRUCTURE_SKIPPED_FOR_CLARITY
      }
    }

  }
}

Note that I didn't write "Bucket" : "my-bucket-name", in MyBucketPolicy resource above, I actually want to reference MyBucket there. CloudFormation engine will replace { "Ref" : "MyBucket" } value with "my-bucket-name" when I deploy the template.

Some resources provide extra Return Values (attributes), these values are accessible by using Fn::GetAtt intrinsic function. AWS::S3::Bucket extra return values / attributes are:

  • DomainName
  • DualStackDomainName
  • WebsiteURL

Syntax of Fn::GetAtt intrinsic function is shown below:

{ "Fn::GetAtt" : [ "logicalNameOfResource", "attributeName" ] }

In order to get DomainName from "AWS::S3::Bucket resource, you would do it like this:

{ "Fn::GetAtt" : [ "MyBucket", "DomainName" ] }

You could use DomainName for example in CloudFormation stack outputs section. Complete example follows:

{
  "Resources" : {

    "MyBucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "BucketName" : "my-bucket-name"
      }
    },

    "MyBucketPolicy" : {
      "Type" : "AWS::S3::BucketPolicy",
      "Properties" : {
        "Bucket" : { "Ref" : "MyBucket" },
        "PolicyDocument" : JSON_STRUCTURE_SKIPPED_FOR_CLARITY
      }
    }

  },

  "Outputs" : {

    "MyBucketDomainName" : {
      "Description" : "Domain name of my bucket",
      "Value" : { "Fn::GetAtt" : [ "MyBucket", "DomainName" ] }
    }
  }
}

You will find information about all Resources, their Properties and Return Values (these accessible via Ref as well as Fn::GetAtt functions) in AWS Resource Types Reference.

Hope this helps!

Upvotes: 3

Related Questions