Using CloudFormation Modules to improve IAM Least Privilege

Mark Faiers
Contino Engineering
4 min readFeb 15, 2021

--

CloudFormation Modules

CloudFormation recently introduced ‘Modules’. A module is CloudFormation code that can be used to create resources, exactly what you expect from CloudFormation! The difference being that this code can be reused, something previously not possible in CloudFormation.

By the end of this blog you will have learned what advantages CloudFormation Modules bring in general, how they can benefit security, and some of the current limitations of Modules.

Why is this Good?

All developers learn very early on in their careers that code reuse is GOOD, it keeps things consistent, reduces redundant code, and saves vast amounts of time by not trying to solve problems that have already been solved.

Infrastructure Code is no different. I recently worked on a project that involved maintaining legacy CloudFormation code. A requirement came in from security that all S3 buckets must now have Server Access Logging enabled. Updating each and every S3 bucket defined as code was a menial, painstaking task that involved making minor changes in many places, across many repositories. Had this code been modularised this would have been a single, simple change.

Why is this Great?

If code reuse was the only benefit that CloudFormation module brought then it would be a good feature, what makes it a great feature is its potential to enhance security. When applied to IAM policies, least privilege policies can be defined once and re-used across multiple teams and projects. No more wildcards in IAM policies because the developer didn’t know the exact permissions needed by a role and was under pressure to get a release out!

Modules in Action!

Getting started with CloudFormation Modules is very easy, the only prerequisite is that you have the CloudFormation CLI (https://github.com/aws-cloudformation/cloudformation-cli) installed.

Creating a new module involves only a couple of commands:

cfn init

followed by `m` when prompted whether you want to create a Resource, or a Module.

You will then be prompted for a module type, which takes the form:

<Organization>::<Service>::<Name>::MODULE

For this example, we’ll use the value ‘MYORG::IAM::DynamoDBScannerPolicyV1::MODULE’

This will create:

  1. A ‘fragments’ folder — this is where the CloudFormation code lives, it is initialised with some sample code
  2. A .rpdk-config file containing, as the name suggests, module configuration
  3. A rpdk.log file containing logs generated when cfn commands are run

From here you only need to define a CloudFormation template, including Resources, Parameters, and Outputs as you normally would. In this example we’ll create an IAM policy that allows only the ‘dynamodb:Scan’ operation to be performed on a single DynamoDB table:

It contains 2 parameters. ‘TableArn’ to specify which DynamoDB table the policy will allow scan access to, and ‘NamePrefix’ to provide a unique name for each policy so that it can be differentiated if the module is used more than once in the same account.

Once you are happy with the template you can simply run:

cfn submit

This command validates your resource schema and uploads the module to CloudFormation.

You will be informed once the deployment of the module is complete. At that point you are able to use the module in your CloudFormation templates in the same way you would any other resource, with the module type being used in place of the resource type.

In our example we’ll use this module to create a policy that allows scan access to an existing DynamoDB table:

Fantastic, only 8 lines of code and no need to write any IAM policies! This policy is now ready to be attached to a Role/User/Group that needs scan access to the particular DynamoDB table specified.

Such modules could be created for any number of common operations, such as reading from a particular S3 bucket, and is particularly powerful when used to provide Least Privilege IAM Roles in heavily decomposed, such as Serverless, applications that typically need a very small and specific set of IAM permissions.

Limitations

As with all AWS services and features, there are some limitations that you need to be aware of:

  • YAML is not currently supported for CloudFormation modules, JSON must be used.
  • Outputs are not supported so some level of hard-coding must be used to reference resources created via modules.
  • As part of CloudFormation, modules, by default, are only available in a single region, in a single account.

Conclusion

I believe this to be a huge step forward for CloudFormation. If fully taken advantage of this approach could be used to define security standards as code across entire organisations, dramatically improving the organisation’s security posture whilst also saving numerous developer hours.

--

--