Usage

In a nutshell

  1. Create an instance of cfp.StackParameters.

  2. Call cfp.StackParameters.add() to set the parameter values.

  3. Pass cfp.StackParameters.api_parameters to your Boto3 function.

Setting parameter values

Known values

To pass known (hard-coded or otherwise looked-up) values, simply call cfp.StackParameters.add() with those values.

For example:

from cfp import StackParameters

sp = StackParameters()
sp.add("ParameterA", "Value A")
sp.add("ParameterB", "Value B")

Previous values

To use a parameter’s previous value, pass an instance of cfp.sources.UsePreviousValue.

For example:

from cfp import StackParameters
from cfp.sources import UsePreviousValue

sp = StackParameters()
sp.add("InstanceType", UsePreviousValue())

Systems Manager Parameter Store look-ups

To look-up and set values from Systems Manager Parameter Store, set the parameter’s value to an instance of cfp.sources.FromParameterStore.

While CloudFormation does have baked-in support for reading Systems Manager parameters, it can read only parameters in the same region and account as your stack. CFP supports cross-region and cross-account look-ups.

The following example reads three parameters:

  1. /instance-type is read using the current default credentials and region.

  2. /log-level is read using the current default credentials from “eu-west-2”.

  3. /secret-sauce is read using a Boto3 session crafted for reading from a different AWS account.

from cfp import StackParameters
from cfp.sources import FromParameterStore

sp = StackParameters()

sp.add(
   "InstanceType",
   FromParameterStore("/instance-type"),
)

sp.add(
   "LogLevel",
   FromParameterStore("/log-level", region="eu-west-2"),
)

sp.add(
   "SecretSauce",
   FromParameterStore("/secret-sauce", session=other_account),
)

Passing stack parameters to Boto3

The cfp.StackParameters.api_parameters property can be passed directly to Boto3 functions like the CloudFormation client’s create_change_set().

For example:

from cfp import StackParameters
from boto3.session import Session

sp = StackParameters()
sp.add("ParameterA", "Value A")
sp.add("ParameterB", "Value B")

client = session.client("cloudformation")
client.create_change_set(
   StackName="MyStack",
   ChangeSetName="MyChangeSet",
   ChangeSetType="UPDATE",
   Parameters=sp.api_parameters,
   TemplateBody="...",
)

Logging parameter values

The cfp.StackParameters.render() function renders the full set of parameters and their values to a string writer.

For example:

from cfp import StackParameters
from io import StringIO


sp = StackParameters()
sp.add("ParameterA", "Value A")
sp.add("ParameterB", "Value B")

writer = StringIO()
sp.render(writer, color=False)

print(writer.getvalue())
ParameterA = Value A
ParameterB = Value B

Unit testing

Say you have a function that builds and returns cfp.StackParameters:

from cfp import StackParameters
from cfp.sources import FromParameterStore

def parameters() -> StackParameters:
   sp = StackParameters()
   sp.add("ParameterA", "Value A")
   sp.add("ParameterB", FromParameterStore("/b"))
   return sp

You can unit test this function by asserting on the length of the cfp.StackParameters as well as the sources of each parameter key:

from cfp import StackParameters
from cfp.sources import FromParameterStore
from example import parameters

def test_parameters__len() -> None:
   sp = parameters()
   assert len(sp) == 2

def test_parameters__param_a() -> None:
   sp = parameters()
   assert sp["ParameterA"] == "Value A"

def test_parameters__param_b() -> None:
   sp = parameters()
   assert sp["ParameterB"] == FromParameterStore("/b")