AWS CloudFormation creation library that facilitates building infrastructure templates programmatically in Python
Complete implementation of CloudFormation intrinsic functions for references, string manipulation, conditionals, and data transformation within templates. All intrinsic functions inherit from AWSHelperFn and provide JSON serialization.
Base class for all CloudFormation intrinsic functions with common functionality.
class AWSHelperFn:
def __init__(self):
"""Base class for CloudFormation intrinsic functions."""
def to_dict(self) -> Any:
"""
Convert function to dictionary format.
Returns:
Dictionary representation of the function
"""
def to_json(self, indent: int = 4, sort_keys: bool = True) -> str:
"""
Convert function to JSON string.
Args:
indent: JSON indentation
sort_keys: Whether to sort keys
Returns:
str: JSON representation
"""
def getdata(self, data: object) -> Any:
"""
Extract data from objects, handling BaseAWSObject references.
Args:
data: Input data
Returns:
Processed data (resource title for BaseAWSObject instances)
"""Functions for referencing resources, parameters, and resource attributes.
class Ref(AWSHelperFn):
def __init__(self, data: object):
"""
Reference to a resource or parameter.
Args:
data: Resource, parameter, or pseudo parameter to reference
Example:
Ref("MyParameter")
Ref(my_resource)
"""
class GetAtt(AWSHelperFn):
def __init__(self, logicalName: object, attrName: object):
"""
Get attribute value from a resource.
Args:
logicalName: Resource logical name or resource object
attrName: Attribute name to retrieve
Example:
GetAtt("MyInstance", "PublicIp")
GetAtt(my_instance, "PrivateDnsName")
"""
class ImportValue(AWSHelperFn):
def __init__(self, data: object):
"""
Import value from cross-stack export.
Args:
data: Export name to import
Example:
ImportValue("NetworkStack-VPC-ID")
ImportValue(Sub("${NetworkStack}-VPC-ID"))
"""Functions for string manipulation and transformation.
class Join(AWSHelperFn):
def __init__(self, delimiter: object, values: object):
"""
Join list of values with delimiter.
Args:
delimiter: String delimiter
values: List of values to join
Example:
Join("", ["https://", GetAtt("MyBucket", "DomainName")])
Join(",", ["value1", "value2", "value3"])
"""
class Sub(AWSHelperFn):
def __init__(self, input_str: object, dict_values: Optional[Dict[str, Any]] = None, **values):
"""
Substitute variables in string template.
Args:
input_str: String template with ${variable} placeholders
dict_values: Dictionary of variable substitutions
**values: Keyword argument substitutions
Example:
Sub("Hello ${name}!", {"name": "World"})
Sub("arn:aws:s3:::${bucket}/*", bucket=Ref("MyBucket"))
Sub("${AWS::StackName}-resource")
"""
class Split(AWSHelperFn):
def __init__(self, delimiter: object, values: object):
"""
Split string by delimiter into list.
Args:
delimiter: String delimiter
values: String to split
Example:
Split(",", "a,b,c") # Returns ["a", "b", "c"]
Split(":", ImportValue("MyStack-AZ-List"))
"""
class Base64(AWSHelperFn):
def __init__(self, data: Any):
"""
Encode string as Base64.
Args:
data: String or function to encode
Example:
Base64("Hello World")
Base64(Sub("#!/bin/bash\necho ${Message}", Message="Hello"))
"""Functions for selecting values from lists and looking up values in mappings.
class Select(AWSHelperFn):
def __init__(self, indx: object, objects: object):
"""
Select item from list by index.
Args:
indx: Index (0-based) to select
objects: List to select from
Example:
Select(0, GetAZs()) # First availability zone
Select(1, Split(",", "a,b,c")) # Returns "b"
"""
class FindInMap(AWSHelperFn):
def __init__(self, mapname: object, toplevelkey: object, secondlevelkey: object,
defaultvalue: Optional[object] = None):
"""
Look up value in mapping.
Args:
mapname: Mapping name
toplevelkey: Top-level key
secondlevelkey: Second-level key
defaultvalue: Default value if key not found
Example:
FindInMap("RegionMap", Ref("AWS::Region"), "AMI")
FindInMap("InstanceTypeMap", Ref("Environment"), "InstanceType", "t2.micro")
"""Functions for conditional logic and boolean operations.
class If(AWSHelperFn):
def __init__(self, cond: object, true: object, false: object):
"""
Conditional selection between two values.
Args:
cond: Condition name to evaluate
true: Value if condition is true
false: Value if condition is false
Example:
If("IsProduction", "m5.large", "t2.micro")
If("CreateBucket", Ref("MyBucket"), Ref("AWS::NoValue"))
"""
class Condition(AWSHelperFn):
def __init__(self, data: object):
"""
Reference to a template condition.
Args:
data: Condition name
Example:
Condition("IsProduction")
"""
class Equals(AWSHelperFn):
def __init__(self, value_one: object, value_two: object):
"""
Compare two values for equality.
Args:
value_one: First value
value_two: Second value
Example:
Equals(Ref("Environment"), "production")
Equals(Ref("AWS::Region"), "us-east-1")
"""
class And(AWSHelperFn):
def __init__(self, cond_one: object, cond_two: object, *conds: object):
"""
Logical AND operation on conditions.
Args:
cond_one: First condition
cond_two: Second condition
*conds: Additional conditions
Example:
And(Equals(Ref("Environment"), "prod"), Equals(Ref("CreateBackup"), "true"))
"""
class Or(AWSHelperFn):
def __init__(self, cond_one: object, cond_two: object, *conds: object):
"""
Logical OR operation on conditions.
Args:
cond_one: First condition
cond_two: Second condition
*conds: Additional conditions
Example:
Or(Equals(Ref("Environment"), "dev"), Equals(Ref("Environment"), "test"))
"""
class Not(AWSHelperFn):
def __init__(self, cond: object):
"""
Logical NOT operation on condition.
Args:
cond: Condition to negate
Example:
Not(Equals(Ref("Environment"), "production"))
"""Functions that interact with AWS services and infrastructure.
class GetAZs(AWSHelperFn):
def __init__(self, region: object = ""):
"""
Get availability zones for region.
Args:
region: Region name (empty string for current region)
Example:
GetAZs() # Current region AZs
GetAZs("us-west-2") # Specific region AZs
"""
class Cidr(AWSHelperFn):
def __init__(self, ipblock: object, count: object, sizemask: Optional[object] = None):
"""
Generate CIDR blocks from IP block.
Args:
ipblock: IP block in CIDR notation
count: Number of subnets to create
sizemask: Subnet mask size (default: depends on count)
Example:
Cidr("10.0.0.0/16", 6, 8) # 6 subnets with /24 masks
Cidr(GetAtt("MyVPC", "CidrBlock"), 2)
"""Pre-defined Ref objects for AWS pseudo parameters.
# Pseudo Parameter Constants
AWS_ACCOUNT_ID: str = "AWS::AccountId"
AWS_NOTIFICATION_ARNS: str = "AWS::NotificationARNs"
AWS_NO_VALUE: str = "AWS::NoValue"
AWS_PARTITION: str = "AWS::Partition"
AWS_REGION: str = "AWS::Region"
AWS_STACK_ID: str = "AWS::StackId"
AWS_STACK_NAME: str = "AWS::StackName"
AWS_URL_SUFFIX: str = "AWS::URLSuffix"
# Pre-defined Ref Objects
AccountId: Ref = Ref(AWS_ACCOUNT_ID)
NotificationARNs: Ref = Ref(AWS_NOTIFICATION_ARNS)
NoValue: Ref = Ref(AWS_NO_VALUE)
Partition: Ref = Ref(AWS_PARTITION)
Region: Ref = Ref(AWS_REGION)
StackId: Ref = Ref(AWS_STACK_ID)
StackName: Ref = Ref(AWS_STACK_NAME)
URLSuffix: Ref = Ref(AWS_URL_SUFFIX)from troposphere import Template, Parameter, Ref, GetAtt
from troposphere.ec2 import Instance
template = Template()
# Parameter reference
instance_type = template.add_parameter(Parameter(
"InstanceType",
Type="String",
Default="t2.micro"
))
# Resource creation with parameter reference
instance = template.add_resource(Instance(
"MyInstance",
ImageId="ami-0abcdef1234567890",
InstanceType=Ref(instance_type) # Reference parameter
))
# Get resource attribute
public_ip = GetAtt(instance, "PublicIp")from troposphere import Join, Sub, Split, Base64
from troposphere.ec2 import Instance
# Join strings
url = Join("", [
"https://",
GetAtt("MyLoadBalancer", "DNSName"),
"/api"
])
# String substitution
user_data = Sub("""#!/bin/bash
echo "Stack: ${AWS::StackName}" >> /var/log/info.log
echo "Region: ${AWS::Region}" >> /var/log/info.log
echo "Custom: ${Message}" >> /var/log/info.log
""", Message="Hello World")
# Base64 encoding for user data
instance = Instance(
"MyInstance",
UserData=Base64(user_data),
# ... other properties
)
# Split string
availability_zones = Split(",", "us-east-1a,us-east-1b,us-east-1c")
first_az = Select(0, availability_zones)from troposphere import Template, Parameter, Condition, If, Equals, And, Or, Not
template = Template()
# Parameters
environment = template.add_parameter(Parameter(
"Environment",
Type="String",
AllowedValues=["dev", "staging", "prod"]
))
backup_enabled = template.add_parameter(Parameter(
"BackupEnabled",
Type="String",
AllowedValues=["true", "false"],
Default="false"
))
# Conditions
template.add_condition("IsProduction",
Equals(Ref(environment), "prod"))
template.add_condition("IsNotDev",
Not(Equals(Ref(environment), "dev")))
template.add_condition("ProdWithBackup",
And(
Equals(Ref(environment), "prod"),
Equals(Ref(backup_enabled), "true")
))
template.add_condition("DevOrStaging",
Or(
Equals(Ref(environment), "dev"),
Equals(Ref(environment), "staging")
))
# Conditional resource properties
instance = Instance(
"MyInstance",
InstanceType=If("IsProduction", "m5.large", "t2.micro"),
Monitoring=If("ProdWithBackup", True, False)
)from troposphere import Template, FindInMap, Select, GetAZs
template = Template()
# Add mapping
template.add_mapping("RegionMap", {
"us-east-1": {"AMI": "ami-0ff8a91507f77f867"},
"us-west-2": {"AMI": "ami-0bdf93799014acdc4"},
"eu-west-1": {"AMI": "ami-047bb4163c506cd98"}
})
# Use mapping lookup
ami_id = FindInMap("RegionMap", Ref("AWS::Region"), "AMI")
# Select from availability zones
first_az = Select(0, GetAZs())
second_az = Select(1, GetAZs())
# Use in resources
instance = Instance(
"MyInstance",
ImageId=ami_id,
AvailabilityZone=first_az,
InstanceType="t2.micro"
)from troposphere import *
from troposphere.s3 import Bucket
from troposphere.cloudfront import Distribution
# Complex string building with multiple functions
bucket_domain = GetAtt("MyBucket", "RegionalDomainName")
origin_domain = If("UseCloudFront",
GetAtt("MyDistribution", "DomainName"),
bucket_domain
)
api_url = Join("", [
"https://",
origin_domain,
"/api/",
Ref("AWS::StackName"),
"/",
Select(0, Split("-", Ref("AWS::AccountId")))
])
# User data with complex substitution
user_data_script = Sub("""#!/bin/bash
export STACK_NAME="${AWS::StackName}"
export REGION="${AWS::Region}"
export ACCOUNT_ID="${AWS::AccountId}"
export API_URL="${ApiUrl}"
export BUCKET_NAME="${BucketName}"
# Download from S3
aws s3 cp s3://${BucketName}/scripts/setup.sh /tmp/setup.sh
chmod +x /tmp/setup.sh
/tmp/setup.sh
""", {
"ApiUrl": api_url,
"BucketName": Ref("MyBucket")
})Install with Tessl CLI
npx tessl i tessl/pypi-troposphere