Using AWS CloudFormation’s Transform Function

Why use CloudFormation’s Transform Function?

There are two good reasons for using CloudFormation’s “Transform” function to include files. These two reasons are described below:

  1. Consistency.
    1. By including a snippet in each and every CloudFormation template – you’ll ensure that the included code is the same, stack to stack.
  2. Code reuse.
    1. You won’t need to update code across multiple stacks when you need to make changes. You will need to update stacks to get changes made to the included files – but you won’t have to update the actual code in each stack.

How to do this?

Creating a CloudFormation File that uses an Include.

You need to include a Fn::Transform statement where the given file is to be included. An example included is below:

Fn::Transform:
  Name: AWS::Include
  Parameters:
    Location : s3://187376578462-fn-transform-include/ubuntu_ami.yaml

An example of an include in the “Mappings” section of a CloudFormation template would look like:

Mappings:
  Fn::Transform:
    Name: AWS::Include
    Parameters:
      Location : s3://187376578462-fn-transform-include/ubuntu_ami.yaml

Lastly, here is a screenshot of a CloudFormation file that uses an include – see line 29.

CloudFormation - Fn Transform
CloudFormation template that utilizes a Transform function to include a file.

Creating the Included File

You will need to create a file that will be included in a given CloudFormation stack. This file is going to be inserted where the Fn::Transform statement is – this is akin to “import” or “include” in a programming language or “catting” two files together in a *nix Operating System.

The included file should look akin to the following:

AWSRegionArch2AMI:
  us-east-1:
    '64': ami-ddf13fb0
  us-west-1:
    '64': ami-b20542d2
  us-west-2:
    '64': ami-b9ff39d9
CloudFormation - File to be Included
File to be included in a CloudFormation template.

Uploading the Included File

The file that _will be_ included needs to be uploaded to S3. You can do this using the aws s3 command – see below:

aws s3 cp ubuntu_ami.yaml s3://$ubuntu_ami_file_s3_path --region us-west-2
CloudFormation - Included File Upload
AWS S3 command uploading a file to be included in a CloudFormation template.

Creating the CloudFormation Stack with an Include

You’ll need to use the “aws cloudformation deploy” command to deploy or update the given template. An example is below:

aws cloudformation deploy --stack-name FunctionTransformInclude --template-file autoscaling_with_yaml_userdata.yaml --parameter-overrides ubuntuAMISMapping3Location=s3://$ubuntu_ami_file_s3_path --region us-west-2
CloudFormation - Fn Transform Launch Stack
AWS CloudFormation “Deploy” command creating a CloudFormation stack

Summary

I’m planning on using for AMI mappings in particular, as well as for including sections of CloudFormation that might be better generated using code (for instance, user-data might be a consideration). I’ve yet to consider the use of “Fn::Transform / Include” to improve the security of stacks by removing passwords.

If you have questions or comments – reach me at colin@cloudavail.com.

Creating Expiring IAM Users

A common question I get from folks is “how do I create a temporary AWS IAM user” or “how do I grant access to x service” for only a period of time. Typically, you’d want to use the IAM “Condition” element, which I’ll demonstrate how to do this in the remainder of this blog post. I’ll be using the example of creating an IAM “Power Users” policy that expires on January 31st of 2016 in this example.

Understanding IAM “Power Users” Policy:

The reason I like the IAM “Power Users” policy is that many organizations are moving to the model of fully empowered Engineering staff (meaning organizations where all Engineering staff have Administrator access). This model works well for many organizations, with one exception – allowing all Engineering staff to reset passwords means that when an employee leaves an organization you can’t be certain you have removed their access completely. Consider the case where an ex-employee has just created a new user or provided a password reset – they may know that accounts’s username password even after their own account has been disabled or removed. The other reason I like “Power Users” – despite the “deny” of actions on IAM resources – IAM users can still reset their own passwords despite the deny on IAM user actions (see: http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_passwords_user-change-own.html#ManagingUserPwdSelf-Console).

Creating the Expiring IAM Power User Policy:

To create an “Power User” IAM policy, do the following:

  1. Login to the IAM Console within the AWS Console.
  2. Select “Policies” from the left-hand navigation and click “Create Policy”
    1. Select “Copy an AWS Managed Policy”
    2. In “Step 2: Set Permissions”, select the “Power User” policy.
    3. In “Step 3: Review Policy”, add the following:
      “Condition”: {
      “DateLessThan”: {
      “aws:CurrentTime”: “2016-01-31T12:00:00Z”
      }
      The outcome will look like the image below:
      IAM Policy - Adding Condition
  3. Click “Create Policy”

The magic here is that the Statement within the IAM Policy will only be allowed when the condition is true.

Attach the Policy to a User or Group:

  1. Login to IAM Console within the AWS Console.
  2. Select “Policies” from the left-hand navigation and select the “Power User” policy you had created previously. See image below:
    IAM Policy - Filtered and Power User Selected
  3. Scroll down to the “Attached Entities” section, click “Attend Entity” and add the Users (or Groups) to which you wish to attach this policy. See image below:
    IAM Policy - Attached Entities

Notes:

  1. After “Policy Expiration” the IAM user will still be able to login to the AWS Console. They won’t have permissions to issue any API commands, however.

References:

  1. IAM “Conditions” Reference is available here: http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition.