Skip to content

Commit

Permalink
Added NAT Gateway functionality, improved EIP model, and added CloudF…
Browse files Browse the repository at this point in the history
…ormation Wait functionality.
  • Loading branch information
bkrodgers committed Jan 25, 2016
1 parent f6cd38e commit 9455a02
Show file tree
Hide file tree
Showing 15 changed files with 722 additions and 25 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,7 +3,19 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [3.0.7] - 2016-01-21

### Added

- Add ability to work with NAT gateways. Requires a custom Lambda function. See README.md.
- Added `AWS::CloudFormation::WaitCondition` and `AWS::CloudFormation::WaitConditionHandle` to support pausing
for resources to do things.

### Changed

- Improved EIP model to better handle VPC vs Classic EIPs. Changes are backwards compatible, but
existing methods are now deprecated.

## [3.0.4] - 2015-11-30

Expand Down
36 changes: 36 additions & 0 deletions README.md
Expand Up @@ -83,6 +83,8 @@ describe("Template Lookup") {
- AWS::AutoScaling::AutoScalingGroup
- AWS::AutoScaling::LaunchConfiguration
- AWS::AutoScaling::ScalingPolicy
- AWS::CloudFormation::WaitCondition
- AWS::CloudFormation::WaitConditionHandle
- AWS::CloudWatch::Alarm
- AWS::DynamoDB::Table
- AWS::EC2::CustomerGateway
Expand Down Expand Up @@ -134,6 +136,40 @@ describe("Template Lookup") {
- AWS::SQS::Queue
- AWS::SQS::QueuePolicy

### Custom types

This project packages certain useful custom CloudFormation types. These are Lambda backed types that perform
tasks that CloudFormation does not natively support. In order to use them, you must upload the Lambda function
to your account and region. The code for these functions is found in this repo under assets/custom-types.

## NAT Gateways
CloudFormation does not yet support the new managed NAT gateways. In order to make use of these, a custom
function has been implemented. At whatever time Amazon updates CF to support these natively, this functionality
will be deprecated and removed.

If you use the raw `Custom::NatGateway` and `Custom::NatGatewayRoute` objects directly, you'll need to set up
WaitCondition and WaitConditionHandles as well. See the `withNAT()` implementations for more details.
We highly recommend using the `Builder`'s `withNAT()` function, as it takes care of the complexity of this.

To set up the necessary Lambda functions:

1. Open a shell with the `aws` cli installed and configured for the AWS account and region you want to deploy to.
You must have permissions to create Lambda functions and IAM roles. You also need `npm` installed.
2. `git clone` this repo.
3. `cd <this repo>/assets/custom-types/nat-gateway`
4. Review the code in nat_gateway.js and the policies we're about to create for you, along with deploy.sh.
(Not that you can't trust us, but we're about to upload code to your account and create an IAM role to do things.)
5. WARNING: This will deploy the Lambda function as `cf-nat-gateway` in your account.
*IN THE UNLIKELY EVENT YOU ARE ALREADY USING THIS NAME, IT WILL BE OVERWRITTEN!* You can change this in the script,
but will need to pass in the ARN, instead of using the default as described below.
6. Run ./deploy.sh

The `ServiceToken` parameter (or `cfNATLambdaARN` parameter in `withNat()`) needs to be the ARN to the Lambda function.
If you are deploying the function to the default name of `cf-nat-gateway`, you can use `Custom::NatGateway.defaultServiceToken`,
which will construct an ARN from the AWS account, region, and this default function name.

Credit for the Lambda function script: http://www.spacevatican.org/2015/12/20/cloudformation-nat-gateway/

## Releasing

This project uses the sbt release plugin. After the changes you want to
Expand Down
1 change: 1 addition & 0 deletions assets/custom-types/nat-gateway/.gitignore
@@ -0,0 +1 @@
target
46 changes: 46 additions & 0 deletions assets/custom-types/nat-gateway/deploy.sh
@@ -0,0 +1,46 @@
#!/bin/bash
rm -rf target
mkdir -p target
cd target
cp ../nat_gateway.js nat_gateway.js
npm install aws-sdk
zip -r nat_gateway.zip nat_gateway.js node_modules/
cd ..

account_id=$(aws iam get-user | jq -r .User.Arn | perl -pe 's/arn:aws:iam::(\d+):.*/$1/')

role=lambda-execution-cf-nat-gateway
function_name=cf-nat-gateway

if ! aws iam get-role --role-name $role >/dev/null 2>&1 ; then
aws iam create-role --role-name $role \
--assume-role-policy-document file://trust-policy.json
fi

aws iam put-role-policy --role-name $role \
--policy-name $role \
--policy-document file://policy.json

# The role seems to take a little time to settle down and work. Because...amazon.

sleep 10

if aws lambda get-function --function-name $function_name >/dev/null 2>&1 ; then
aws lambda update-function-code --function-name $function_name \
--zip-file fileb://target/nat_gateway.zip
else
while ! aws lambda create-function --function-name $function_name \
--description "Custom CloudFormation function for managing NAT Gateways" \
--runtime nodejs \
--role arn:aws:iam::${account_id}:role/${role} \
--handler nat_gateway.handler \
--timeout 300 \
--zip-file fileb://target/nat_gateway.zip ; do

echo "The 'The role defined for the function cannot be assumed by Lambda' error you may have just seen is time based. Sleeping 1 and trying again."
echo "If you saw a different error or this doesn't resolve itself after a few tries, hit ctrl-c"
sleep 1
done
fi


0 comments on commit 9455a02

Please sign in to comment.