CLI/workflow lib around for management of CloudFormation stacks
Project description
About
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)
Docs
Full docs are at https://tropostack.readthedocs.io/en/latest/
Installation
$ pip install tropostack
Or, you can use setup.py to install from a cloned repository:
$ python setup.py 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_' @property def r_bucket(self): return s3.Bucket( 'MyBucketResource', BucketName=self.conf['bucket_name'] ) # Stack Outputs are defined as class properties prefixed with 'o_' @property def o_bucket_arn(self): _id = 'BucketArn' return Output( _id, 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) cli.run()
The above already gives you a usable CLI around your stack definition.
Assuming you put it inside an executable file called s3_minimal.py, you’d be able to call it already:
$ ./s3_minimal.py -h usage: s3_minimal.py [-h] {apply,create,delete,outputs,print,update,validate} positional arguments: {apply,create,delete,outputs,print,update,validate} optional arguments: -h, --help show this help message and exit
You can now inspect the “raw” CloudFormation code generated by the stack:
$ ./s3_minimal.py print Outputs: BucketArn: Description: The ARN of the S3 bucket Export: Name: !Sub '${AWS::StackName}-BucketArn' Value: !GetAtt 'MyBucketResource.Arn' Resources: MyBucketResource: Properties: 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:
$ ./s3_minimal.py 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:
$ ./s3_minimal.py 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:
$ ./s3_minimal.py 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.