Skip to main content

Run functional tests on cloudformation stacks.

Project description

Python Latest Tests Coverage License


Cloud-Radar

Write unit and functional tests for AWS Cloudformation.
Report Bug · Request Feature · Guide

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgements

About The Project

Cloud-Radar is a python module that allows testing of Cloudformation Templates/Stacks using Python.

Unit Testing

You can now unit test the logic contained inside your Cloudformation template. Cloud-Radar takes your template, the desired region and some parameters. We render the template into its final state and pass it back to you.

You can Test:

  • That Conditionals in your template evaluate to the correct value.
  • Conditional resources were created or not.
  • That resources have the correct properties.
  • That resources are named as expected because of !Sub.

You can test all this locally without worrying about AWS Credentials.

Functional Testing

This project is a wrapper around Taskcat. Taskcat is a great tool for ensuring your Cloudformation Template can be deployed in multiple AWS Regions. Cloud-Radar enhances Taskcat by making it easier to write more complete functional tests.

Here's How:

  • You can interact with the deployed resources directly with tools you already know like boto3.
  • You can control the lifecycle of the stack. This allows testing if resources were retained after the stacks were deleted.
  • You can run tests without hardcoding them in a taskcat config file.

This project is new and it's possible not all features or functionality of Taskcat/Cloudformation are supported (see Roadmap). If you find something missing or have a use case that isn't covered then please let me know =)

Built With

Getting Started

Cloud-Radar is available as an easy to install pip package.

Prerequisites

Cloud-Radar requires python >= 3.8

Installation

  1. Install with pip.
    pip install cloud-radar
    

Usage

Unit Testing (Click to expand)

Using Cloud-Radar starts by importing it into your test file or framework. We will use this Template as an example.

from pathlib import Path
from cloud_radar.cf.unit import Template

template_path = Path("tests/templates/log_bucket/log_bucket.yaml")

# template_path can be a str or a Path object
template = Template.from_yaml(template_path.resolve())

params = {"BucketPrefix": "testing", "KeepBucket": "TRUE"}

# parameters and region are optional arguments.
result = template.render(params, region="us-west-2")

assert "LogsBucket" not in result["Resources"]

bucket = result["Resources"]["RetainLogsBucket"]

assert "DeletionPolicy" in bucket

assert bucket["DeletionPolicy"] == "Retain"

bucket_name = bucket["Properties"]["BucketName"]

assert "us-west-2" in bucket_name

The AWS pseudo variables are all class attributes and can be modified before rendering a template.

# The value of 'AWS::AccountId' in !Sub "My AccountId is ${AWS::AccountId}" can be changed:
Template.AccountId = '8675309'

Note: Region should only be changed to change the default value. To change the region during testing pass the desired region to render(region='us-west-2')

The default values for psedo variables:

Name Default Value
AccountId "555555555555"
NotificationARNs []
NoValue ""
Partition "aws"
Region "us-east-1"
StackId ""
StackName ""
URLSuffix "amazonaws.com"
Note: Bold variables are not fully impletmented yet see the Roadmap

A real unit testing example using Pytest can be seen here

Functional Testing (Click to expand) Using Cloud-Radar starts by importing it into your test file or framework.
from pathlib import Path

from cloud_radar.cf.e2e import Stack

# Stack is a context manager that makes sure your stacks are deleted after testing.
template_path = Path("tests/templates/log_bucket/log_bucket.yaml")
params = {"BucketPrefix": "testing", "KeepBucket": "False"}
regions = ['us-west-2']

# template_path can be a string or a Path object.
# params can be optional if all your template params have default values
# regions can be optional, default region is 'us-east-1'
with Stack(template_path, params, regions) as stacks:
    # Stacks will be created and returned as a list in the stacks variable.

    for stack in stacks:
        # stack will be an instance of Taskcat's Stack class.
        # It has all the expected properties like parameters, outputs and resources

        print(f"Testing {stack.name}")

        bucket_name = ""

        for output in stack.outputs:

            if output.key == "LogsBucketName":
                bucket_name = output.value
                break

        assert "logs" in bucket_name

        assert stack.region.name in bucket_name

        print(f"Created bucket: {bucket_name}")

# Once the test is over then all resources will be deleted from your AWS account.

You can use taskcat tokens in your parameter values.

parameters = {
  "BucketPrefix": "taskcat-$[taskcat_random-string]",
  "KeepBucket": "FALSE",
}

You can skip the context manager. Here is an example for unittest

import unittest

from cloud-radar.cf.e2e import Stack

class TestLogBucket(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        template_path = Path("tests/templates/log_bucket/log_bucket.yaml")
        cls.test = Stack(template_path)
        cls.test.create()

    @classmethod
    def tearDownClass(cls):
        cls.test.delete()

    def test_bucket(self):
        stacks = self.__class__.test.stacks

        for stack in stacks:
            # Test

All the properties and methods of a stack instance.

A real functional testing example using Pytest can be seen here

Roadmap

Project

  • Python 3.7 support
  • Add Logging
  • Add Logo
  • Make it easier to interact with stack resources.
    • Getting a resource for testing should be as easy as stack.Resources('MyResource) or template.Resources('MyResource')
  • Easier to pick regions for testing

Unit

  • Add full functionality to pseudo variables.
    • Variables like Partition, URLSuffix should change if the region changes.
    • Variables like StackName and StackId should have a better default than ""
  • Handle References to resources that shouldn't exist.
    • It's currently possible that a !Ref to a Resource stays in the final template even if that resource is later removed because of a conditional.
  • Handle function order
    • Some functions are only allowed in certain parts of the template.

Functional

  • Add the ability to update a stack instance to Taskcat.

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

This project uses poetry to manage dependencies and pre-commit to run formatting, linting and tests. You will need to have both installed to your system as well as python 3.9.

  1. Fork the Project
  2. Setup environment (poetry install)
  3. Setup commit hooks (pre-commit install)
  4. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  5. Commit your Changes (git commit -m 'Add some AmazingFeature')
  6. Push to the Branch (git push origin feature/AmazingFeature)
  7. Open a Pull Request

License

Distributed under the Apache-2.0 License. See LICENSE.txt for more information.

Contact

Levi - @shady_cuz

Acknowledgements

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.

Source Distribution

cloud-radar-0.6.1.tar.gz (22.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloud_radar-0.6.1-py3-none-any.whl (18.1 kB view details)

Uploaded Python 3

File details

Details for the file cloud-radar-0.6.1.tar.gz.

File metadata

  • Download URL: cloud-radar-0.6.1.tar.gz
  • Upload date:
  • Size: 22.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.9.6 Linux/5.8.0-1039-azure

File hashes

Hashes for cloud-radar-0.6.1.tar.gz
Algorithm Hash digest
SHA256 23394a7ede185d99e004a015c59b9dbce46f9c1d69e19f92352f5796e021656e
MD5 eb73d422092bd24549ce7d7cef97e6b8
BLAKE2b-256 0f96c1cfcbb3f6ffaa194e0d0eea1e66ea5c43215a7fd9bdcc386f672a384116

See more details on using hashes here.

File details

Details for the file cloud_radar-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: cloud_radar-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 18.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.9.6 Linux/5.8.0-1039-azure

File hashes

Hashes for cloud_radar-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 261418935b12d7c82f501c62bda173f7a2193bd28b0cff0786f32ca07d024988
MD5 251c026004a32426d4845d6681d18171
BLAKE2b-256 a8af1de2fe91e01bbdb5ecfe7d39d7cfd16dc826c541654579fcd65a573e334a

See more details on using hashes here.

Supported by

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