Skip to main content

CLI/workflow lib around for management of CloudFormation stacks

Project description

pypi version travis build status


Tropostack is a CLI/workflow library that simplifies the creation and management of CloudFormation stacks, based on the excellent Troposphere Project.

Tropostack features:

  • Single stack template = single executable Python file = single CLI

  • Support for different configuration and CLI plugins

  • A collection of generic commands available to each stack (e.g. create)

  • Support for user-defined CLI commands (e.g. upscale)

  • Helper routines (e.g. locate the newest matching AMI)


Full docs are at


$ pip install tropostack

Or, you can use to install from a cloned repository:

$ python install

First stack

You use tropostack as a library to:
  • Consisteny define CloudFormation templates in Python code

  • Have a CLI around each stack definition, enabling it to live as a standalone executable

Here is a minimalistic example of a stack that creates an S3 bucket, and exports the ARN as an Output:

#!/usr/bin/env python3

from troposphere import s3
from troposphere import Output, Export, Sub, GetAtt

from tropostack.base import InlineConfStack
from tropostack.cli import InlineConfCLI

class MyS3BucketStack(InlineConfStack):
    # Name of the stack
    BASE_NAME = 'my-s3-bucket-stack'

    # Define configuration values for the stack
    CONF = {
        # Region is always explicitly required
        'region': 'eu-west-1',
        # Prefix the bucket name with the account ID
        'bucket_name': Sub('${AWS::AccountId}-my-first-tropostack-bucket')

    # Stack Resources are defined as class properties prefixed with 'r_'
    def r_bucket(self):
        return s3.Bucket(

    # Stack Outputs are defined as class properties prefixed with 'o_'
    def o_bucket_arn(self):
        _id = 'BucketArn'
        return Output(
            Description='The ARN of the S3 bucket',
            Value=GetAtt(self.r_bucket, 'Arn'),
            # We're exporting the output as <StackName>-<OutputId>
            # Other stacks can read the output relying on the same convention
            Export=Export(Sub("${AWS::StackName}-%s" % _id))

if __name__ == '__main__':
    # Wrap the stack in a CLI and run it
    cli = InlineConfCLI(MyS3BucketStack)

The above already gives you a usable CLI around your stack definition.

Assuming you put it inside an executable file called, you’d be able to call it already:

$ ./ -h
usage: [-h]

positional arguments:

optional arguments:
  -h, --help            show this help message and exit

You can now inspect the “raw” CloudFormation code generated by the stack:

$ ./ print
    Description: The ARN of the S3 bucket
      Name: !Sub '${AWS::StackName}-BucketArn'
    Value: !GetAtt 'MyBucketResource.Arn'
      BucketName: !Sub '${AWS::AccountId}-my-first-tropostack-bucket'
    Type: AWS::S3::Bucket

Assuming AWS credentials are present in the environment, we can now fire up stack that would create our S3 bucket:

$ ./ create
Stack creation initiated for: arn:aws:cloudformation:eu-west-1:472799024263:stack/my-s3-bucket-stack/dd5e93c0-225c-11ea-93d8-0641c159a77a
TIMESTAMP (UTC)          RESOURCE TYPE                              RESOURCE ID                  STATUS                                   REASON
2019-12-19 12:41:23      AWS::CloudFormation::Stack                 my-s3-bucket-stack           CREATE_IN_PROGRESS                       User Initiated
2019-12-19 12:41:26      AWS::S3::Bucket                            MyBucketResource             CREATE_IN_PROGRESS
2019-12-19 12:41:27      AWS::S3::Bucket                            MyBucketResource             CREATE_IN_PROGRESS                       Resource creation Initiated
2019-12-19 12:41:48      AWS::S3::Bucket                            MyBucketResource             CREATE_COMPLETE
2019-12-19 12:41:50      AWS::CloudFormation::Stack                 my-s3-bucket-stack           CREATE_COMPLETE

We can also inspect the stack Outputs - in this case, the ARN of the bucket:

$ ./ outputs
Stack is in status: CREATE_COMPLETE
OutputKey    OutputValue                                           Description               ExportName
-----------  ----------------------------------------------------  ------------------------  ----------------------------
BucketArn    arn:aws:s3:::472799024263-my-first-tropostack-bucket  The ARN of the S3 bucket  my-s3-bucket-stack-BucketArn

Finally, we can clean up and have our stack deleted:

$ ./ delete
Destroy initiated for stack: my-s3-bucket-stack
TIMESTAMP (UTC)          RESOURCE TYPE                              RESOURCE ID                  STATUS                                   REASON
2019-12-19 12:44:59      AWS::CloudFormation::Stack                 my-s3-bucket-stack           DELETE_IN_PROGRESS                       User Initiated
Stack is gone: my-s3-bucket-stack (An error occurred (ValidationError) when calling the DescribeStackEvents operation: Stack [my-s3-bucket-stack] does not exist)

Stock commands

While the CLI can be expanded/customized for each individual tropostack, there are several subcommands that come out of the box:

  • print - prints the resulting CloudFormation YAML to the screen

  • validate - Sends the CloudFormation template to the AWS API for validation, and reports back result

  • create - Initiates the stack creation (should only be used if the stack does not exist yet)

  • update - Updates an existing stack (should only be used if the stack exists)

  • apply - Idempotently updates or creates a stack, based on whether it exists or not

  • outputs - Shows the outputs of an existing stack

  • delete - Deletes an existing stack

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tropostack-0.4.3.tar.gz (12.5 kB view hashes)

Uploaded source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page