Skip to content

Troposphere via Lambda

Shaun Remekie edited this page Nov 21, 2018 · 1 revision

Troposphere is a Python library for generating Cloudformation templates. Qaz being written in Go, does not natively support Python without spawning a sub-process. Rather than creating local dependencies on Python, Troposphere or any local interpreter/Languages, Qaz harnesses AWS Lambda to run those bits of code. This allows the app itself to not be bogged down by dealing with local python Troposphere scripts.

This article will look at deploying/generating a stack using Troposphere via AWS Lambda. Note that some knowledge of AWS Lambda is required to perform this task.

You can read up on AWS Lambda Here.

This example will use the following Qaz config.

project: test

stacks:
  vpc:
    # Defining template source as a lambda function
    source: lambda:{"stack":"vpc"}@troposphere
    cf:
      cidr: 10.10.0.0/16

Step 1 - Make a directory and install Troposphere directly to it


$ mkdir my-project
$ pip install troposphere -t my-project/
$ cd my-project
$ tree -d
.
├── troposphere
│   ├── helpers
│   └── openstack
└── troposphere-1.9.3.dist-info



Step 2 - Write your Troposphere code.

$ vim stacks.py
from troposphere import ec2, Output
from troposphere import Template, Ref, Tags

class VPC():
    def __init__(self):
        self.template = Template()

        # Build Template
        self.add_vpc()
        self.add_outputs()

    def add_vpc(self):
        # Add vpc
        t = self.template

        self.vpc = t.add_resource(ec2.VPC(
            'VPC',
            CidrBlock="{{ .vpc.cidr }}", # <-- note the Qaz template delimiters here
            Tags=Tags(
                Name='elk_vpc'
            )
        ))

    def add_outputs(self):
        t = self.template

        t.add_output(Output(
            'vpcid',
            Description="Vpc ID",
            Value=Ref(self.vpc)
        ))

    @staticmethod
    def template():
        return VPC().template.to_json()


if __name__ == '__main__':
    print(VPC.template())

The above is a simple Troposphere template that returns Cloudformation for a VPC and outputs

Step 3 - Create a lambda handler

In the same file add the following function

def handle(event, context):
    print(event)

    stacks = {
        'vpc': VPC.template
    }

    return json.loads(
        stacks[event['stack'].lower()]()
    )

This function represents the AWS Lambda handler, which will handle requests/events made to our Lambda function.

Step 4 - Zip it and upload your function.

Create a zip file containing only the files in your project directory. Important: The ZIP file must not contain the project directory itself, only those files and directories it contains.

$ zip -r9 code.zip ./my-project/.

You will require a role arn for the following:

You can create a Lambda function via the AWS Console and upload your zip file there, or you can use the AWS CLI tool.

# AWS CLI
$ aws lambda create-function --function-name=troposphere --handler=stacks.handle --runtime=python2.7 --zip-file=fileb://code.zip --role='arn:aws:iam::999999999:
role/lambda_basic_execution'

Step 5 - All set

Once the function is created, you can simply call the qaz generate command with your config to see the output.

$ qaz generate vpc -c my.config

As previously stated the source has been set to Lambda in the config file, as such, just calling the command above will invoke the function and fetch the output. If source were not set in config, you can specify the source for the stack using the -t --template flags.

$ qaz generate -t vpc::lambda:{"stack":"vpc"}@troposphere