SlideShare una empresa de Scribd logo
1 de 25
Descargar para leer sin conexión
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
AWS CloudFormation macros: Coding
best practices
Dan Blanco
Developer Advocate
AWS CloudFormation
Amazon Web Services
M A D 2 0 1
Jing Ling
Senior Product Manager
AWS CloudFormation
Amazon Web Services
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Agenda
• Deep dive
• Introduction to macros
• DSL vs. custom resources vs. macros
• Creating and using macros
• Example macros
• Development best practices
• Writing
• Testing
• Deploying
• Live demo
• Setting up your environment (CI/CD pipeline)
• Authoring and deploying your macros
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
InfrastructureascodewithAWSCloudFormation
Code in YAML or JSON
directly or use sample
templates
Upload local files or
from an Amazon S3
bucket
Create stack using
console, API, or the
AWS CLI
Stacks and
resources are
provisioned
S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
What’s a macro?
Custom template processing code
Runs on entire template or a snippet
Executes on template ingestion
Runs a Lambda function on your behalf
Create your own intrinsic functions
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
DSL vs. custom resources vs. macros
TemplateProvisioning
LockTemplate
Templatecanchange Resourcesareprovisioned
TemplateVerification
Templatecannotchange
Runtime
Custom
Resources
ConsumeTemplate
Macros
TemplateGeneration
Template iscomposed
DSL
• Runs before resources are
provisioned
• Can modify the template
• Runs while resources are
being provisioned
• Has context of other resources in
the stack
• !Refs, !GetAtts, etc., are
fully realized
• Can fail a stack or continue on
• Needs to handle
create/update/delete scenarios
• Generates AWS
CloudFormation templates
• No access to AWS CloudFormation
pre-processing or stack resources
• Use native language constructs and
libraries
• Examples:
• CDK
• SparkleFormation
• Troposphere
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Steps to create and use a macro
1. Write, test, and deploy your macro to Lambda
2. Register your macro to AWS CloudFormation; this reserves the macro name in
your account and region
3. Invoke your registered macro through a AWS CloudFormation template
A macro is invoked through a transform function and can be scoped to be template-wide
or a single resource
S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Macro examples
Iterator/Loop
• Make me X number of this resource
Execute Python
• Pass arbitrary code
Globals
• Add Global Variables
Defaults
• If resource X is declared, add default attributes
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Iterator/loop:Usingyourmacro
Transform:
- Count
Resources:
Bucket:
Type: AWS::S3::Bucket
Count: 3
Transform:
- Count
Sqs:
Type: AWS:::SQS::Queue
Count: 2
Resources:
Bucket1:
Type: AWS::S3::Bucket
Bucket2:
Type: AWS::S3::Bucket
Bucket3:
Type: AWS::S3::Bucket
Resources:
Sqs1:
Type: AWS:::SQS::Queue
Sqs2:
Type: AWS:::SQS::Queue
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Iterator/loop:Lambdacode
import copy
def process_template(template):
new_template = copy.deepcopy(template)
status = 'success'
for name, resource in template['Resources'].items():
if 'Count' in resource:
count = new_template['Resources'][name].pop('Count')
multiplied = multiply(name, new_template['Resources'][name], count)
if not set(multiplied.keys()) & set(new_template['Resources'].keys()):
new_template['Resources'].update(multiplied)
else:
status = 'failed'
return status, template
return status, new_template
def multiply(resource_name, resource_structure, count):
resources = {}
for iteration in range(1, count):
resources[resource_name+str(iteration)] = resource_structure
return resources
def handler(event, context):
result = process_template(event['fragment'])
return {
'requestId': event['requestId'],
'status': result[0],
'fragment': result[1],
}
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Iterator/loop:Deployandregisterthemacro
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
Macro:
Type: AWS::CloudFormation::Macro
Properties:
Name: Count
FunctionName: !GetAtt CountMacroFunction.Arn
CountMacroFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: src
Handler: index.handler
Runtime: python3.6
Timeout: 5
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
ExecutePythonmacro
AWSTemplateFormatVersion: "2010-09-09"
Description: tests String macro functions
Parameters:
Tags:
Default:
"Env=Prod,Application=MyApp,BU=ModernisationTeam"
Type: "CommaDelimitedList"
Resources:
S3Bucket:
Type: "AWS::S3::Bucket"
Properties:
Tags: |
#!PyPlate
output = []
for tag in params['Tags']:
key, value = tag.split('=')
output.append({"Key": key, "Value": value})
Transform: [PyPlate]
def handler(event, context):
macro_response = {
"requestId": event["requestId"],
"status": "success"
}
try:
params = {
"params": event["templateParameterValues"],
"template": event["fragment"],
"account_id": event["accountId"],
"region": event["region"]
}
response = event["fragment"]
macro_response["fragment"] =
obj_iterate(response, params)
except Exception as e:
traceback.print_exc()
macro_response["status"] = "failure"
macro_response["errorMessage"] = str(e)
return macro_response
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Macro:Globalvariables
Transform: Globals
Globals:
SomeText: some-text
ThingTag:
Key: Thing
Value: This is a thing
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: "@SomeText"
Tags:
- "@ThingTag"
- Key: OtherThing
Value: Other thing value
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: “some-text"
Tags:
- Key: Thing
Value: This is a thing
- Key: OtherThing
Value: Other thing value
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Globalvariables
class Repeater():
def __init__(self, template):
self.repeaters = template["Globals"]
del template["Globals"]
self.template = template
def process(self):
return self.__walk(self.template)
def __walk(self, fragment):
if isinstance(fragment, str) and any(fragment == "@{}".format(key) for key in self.repeaters):
return self.repeaters[fragment[1:]]
elif isinstance(fragment, dict):
return {
key: self.__walk(value)
for key, value
in fragment.items()
}
elif isinstance(fragment, list):
return [
self.__walk(value)
for value in fragment
]
return fragment
def handler(event, context):
return {
"requestId": event["requestId"],
"status": "success",
"fragment": Repeater(event["fragment"]).process(),
}
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Generateadditionalresourcesandsetdefaultsmacro
Transform: Defaults
Resources:
Bucket1:
Type: AWS::S3::Bucket
Resources:
Bucket1:
Type: AWS::S3::Bucket
Properties:
AccessControl: Private
Bucket1Policy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: Bucket1
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Deny
Principal: "*"
Action: "s3:Delete*"
Resource:
Fn::Sub:
"arn:aws:s3:::${Bucket1}/*"
Condition:
Bool:
aws:MultiFactorAuthPresent:
"false"
Whenever a bucket is defined…
• Add access control property
• Add bucket policy
• Generate additional resources, intrinsic function
calls, conditions, more
• Macro can allow user to override defaults
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Advanced:Settingupdefaults
DEFAULTS = json.load(open("defaults.json"))
def interpolate(name, string):
return string.replace("{$}", name)
def get_additional_resources(name, props):
additional_resources = {}
for key, value in props.items():
key = interpolate(name, key)
if isinstance(value, dict):
additional_resources[key] = get_additional_resources(name, value)
elif isinstance(value, list):
additional_resources[key] = [
get_additional_resources(name, v)
for v in value
]
elif isinstance(value, str):
additional_resources[key] = interpolate(name, value)
else:
additional_resources[key] = value
return additional_resources
def process_property(key, default, resource):
# Recursive
prop = resource[key]
if isinstance(prop, dict):
if "Defaults::Override" in prop:
resource[key] = prop["Defaults::Override"]
else:
resource[key] = default
elif isinstance(default, dict):
for k in default.keys():
if k in prop.keys():
process_property(k, default[k], prop)
else:
prop[k] = default[k]
else:
resource[key] = default
def process_resource(name, resource, additional_resources):
default = DEFAULTS[resource["Type"]]
if "Properties" not in resource:
resource["Properties"] = {}
# Handle properties
for key, prop in default["Properties"].items():
if key not in resource["Properties"]:
resource["Properties"][key] = prop
else:
process_property(key, prop, resource["Properties"])
# Add additional resources
additional_resources.update(get_additional_resources(name, default.get("AdditionalResources", {})))
def process(template):
additional_resources = {}
for name, resource in template["Resources"].items():
if resource["Type"] in DEFAULTS:
process_resource(name, resource, additional_resources)
template["Resources"].update(additional_resources)
return template
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Advanced:Settingupdefaults
{
"AWS::S3::Bucket": {
"Properties": {
"AccessControl": "Private",
"VersioningConfiguration": {
"Status": "Enabled"
}
},
"AdditionalResources": {
"{$}Policy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "{$}"
},
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:Delete*",
"Resource": {
"Fn::Sub": "arn:aws:s3:::${{$}}/*"
},
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
…
Specify additional resources in a side file
S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Writing
• Set up your authoring environment
• Set up a CI/CD pipeline before you even start
• Use your IDE of choice, set up for your favorite language
• Keep it simple
• Determine if your macro should be a snippet or template-wide
• A macro should do one thing well
• Don’t be afraid to break larger macros apart into smaller ones
• Make it testable
• Keep your functions small
• Macros are pure by default; no state required
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Test your macro
Test like you would a Lambda function
Use AWS SAM or serverless local for testing
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Deploy your macro
Deploy like you would a Lambda function
Use AWS SAM, serverless, Chalice, or Zappa
S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
© 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T
Summary
• Remember when a macro runs
• Determine if snippet or template-wide
• Keep it simple
• Set up your pipeline first
• Test, test, test
Thank you!
S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
Dan Blanco
Developer Advocate
AWS CloudFormation
@thedanblanco
Jing Ling
Product Manager
AWS CloudFormation

Más contenido relacionado

La actualidad más candente

La actualidad más candente (20)

DevOps on AWS
DevOps on AWSDevOps on AWS
DevOps on AWS
 
AWS 기반 클라우드 아키텍처 모범사례 - 삼성전자 개발자 포털/개발자 워크스페이스 - 정영준 솔루션즈 아키텍트, AWS / 유현성 수석,...
AWS 기반 클라우드 아키텍처 모범사례 - 삼성전자 개발자 포털/개발자 워크스페이스 - 정영준 솔루션즈 아키텍트, AWS / 유현성 수석,...AWS 기반 클라우드 아키텍처 모범사례 - 삼성전자 개발자 포털/개발자 워크스페이스 - 정영준 솔루션즈 아키텍트, AWS / 유현성 수석,...
AWS 기반 클라우드 아키텍처 모범사례 - 삼성전자 개발자 포털/개발자 워크스페이스 - 정영준 솔루션즈 아키텍트, AWS / 유현성 수석,...
 
2-ARC.pdf
2-ARC.pdf2-ARC.pdf
2-ARC.pdf
 
E-Commerce 를 풍성하게 해주는 AWS 기술들 - 서호석 이사, YOUNGWOO DIGITAL :: AWS Summit Seoul ...
E-Commerce 를 풍성하게 해주는 AWS 기술들 - 서호석 이사, YOUNGWOO DIGITAL :: AWS Summit Seoul ...E-Commerce 를 풍성하게 해주는 AWS 기술들 - 서호석 이사, YOUNGWOO DIGITAL :: AWS Summit Seoul ...
E-Commerce 를 풍성하게 해주는 AWS 기술들 - 서호석 이사, YOUNGWOO DIGITAL :: AWS Summit Seoul ...
 
Deploy and Govern at Scale with AWS Control Tower
Deploy and Govern at Scale with AWS Control TowerDeploy and Govern at Scale with AWS Control Tower
Deploy and Govern at Scale with AWS Control Tower
 
Amazon EKS - Elastic Container Service for Kubernetes
Amazon EKS - Elastic Container Service for KubernetesAmazon EKS - Elastic Container Service for Kubernetes
Amazon EKS - Elastic Container Service for Kubernetes
 
SEC306 Using Microsoft Active Directory Across On-Premises and AWS Cloud Wind...
SEC306 Using Microsoft Active Directory Across On-Premises and AWS Cloud Wind...SEC306 Using Microsoft Active Directory Across On-Premises and AWS Cloud Wind...
SEC306 Using Microsoft Active Directory Across On-Premises and AWS Cloud Wind...
 
AWS Core Services Overview, Immersion Day Huntsville 2019
AWS Core Services Overview, Immersion Day Huntsville 2019AWS Core Services Overview, Immersion Day Huntsville 2019
AWS Core Services Overview, Immersion Day Huntsville 2019
 
Programming Infrastructure with AWS CDK
Programming Infrastructure with AWS CDKProgramming Infrastructure with AWS CDK
Programming Infrastructure with AWS CDK
 
AWS 101
AWS 101AWS 101
AWS 101
 
AWSome Day Online 2020_Module 1: Introduction to the AWS Cloud
AWSome Day Online 2020_Module 1: Introduction to the AWS CloudAWSome Day Online 2020_Module 1: Introduction to the AWS Cloud
AWSome Day Online 2020_Module 1: Introduction to the AWS Cloud
 
Advanced networking on AWS | AWS Floor28
Advanced networking on AWS | AWS Floor28Advanced networking on AWS | AWS Floor28
Advanced networking on AWS | AWS Floor28
 
Serverless Architecture on AWS
Serverless Architecture on AWSServerless Architecture on AWS
Serverless Architecture on AWS
 
Introduction to Amazon Lightsail
Introduction to Amazon LightsailIntroduction to Amazon Lightsail
Introduction to Amazon Lightsail
 
AWS 클라우드 비용 최적화를 위한 TIP - 임성은 AWS 매니저
AWS 클라우드 비용 최적화를 위한 TIP - 임성은 AWS 매니저AWS 클라우드 비용 최적화를 위한 TIP - 임성은 AWS 매니저
AWS 클라우드 비용 최적화를 위한 TIP - 임성은 AWS 매니저
 
AWS Control Tower
AWS Control TowerAWS Control Tower
AWS Control Tower
 
Aws VPC
Aws VPCAws VPC
Aws VPC
 
AWS Containers Day.pdf
AWS Containers Day.pdfAWS Containers Day.pdf
AWS Containers Day.pdf
 
Deep Dive on AWS Lambda
Deep Dive on AWS LambdaDeep Dive on AWS Lambda
Deep Dive on AWS Lambda
 
Introduction to Amazon Web Services by i2k2 Networks
Introduction to Amazon Web Services by i2k2 NetworksIntroduction to Amazon Web Services by i2k2 Networks
Introduction to Amazon Web Services by i2k2 Networks
 

Similar a AWS CloudFormation macros: Coding best practices - MAD201 - New York AWS Summit

Similar a AWS CloudFormation macros: Coding best practices - MAD201 - New York AWS Summit (20)

Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
Beyond the Basics: Advanced Infrastructure as Code Programming on AWS (DEV327...
 
CloudFormation techniques from the Dutch trenches (DVC07) - AWS re:Invent 2018
CloudFormation techniques from the Dutch trenches (DVC07) - AWS re:Invent 2018CloudFormation techniques from the Dutch trenches (DVC07) - AWS re:Invent 2018
CloudFormation techniques from the Dutch trenches (DVC07) - AWS re:Invent 2018
 
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
Build AWS CloudFormation Custom Resources (DEV417-R2) - AWS re:Invent 2018
 
Hands-On with Advanced AWS CloudFormation Techniques and New Features (DEV335...
Hands-On with Advanced AWS CloudFormation Techniques and New Features (DEV335...Hands-On with Advanced AWS CloudFormation Techniques and New Features (DEV335...
Hands-On with Advanced AWS CloudFormation Techniques and New Features (DEV335...
 
(DVO304) AWS CloudFormation Best Practices
(DVO304) AWS CloudFormation Best Practices(DVO304) AWS CloudFormation Best Practices
(DVO304) AWS CloudFormation Best Practices
 
Deep Dive into AWS SAM: re:Invent 2018 Recap at the AWS Loft - San Francisco
Deep Dive into AWS SAM: re:Invent 2018 Recap at the AWS Loft - San FranciscoDeep Dive into AWS SAM: re:Invent 2018 Recap at the AWS Loft - San Francisco
Deep Dive into AWS SAM: re:Invent 2018 Recap at the AWS Loft - San Francisco
 
Deep Dive into AWS SAM
Deep Dive into AWS SAMDeep Dive into AWS SAM
Deep Dive into AWS SAM
 
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
Running Serverless at The Edge (CTD302) - AWS re:Invent 2018
 
Meetup bangalore aug31st2019
Meetup bangalore aug31st2019Meetup bangalore aug31st2019
Meetup bangalore aug31st2019
 
Building Serverless Applications Using AWS AppSync and Amazon Neptune (SRV307...
Building Serverless Applications Using AWS AppSync and Amazon Neptune (SRV307...Building Serverless Applications Using AWS AppSync and Amazon Neptune (SRV307...
Building Serverless Applications Using AWS AppSync and Amazon Neptune (SRV307...
 
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
 
AWS SSA Webinar 28 - Getting Started with AWS - Infrastructure as Code
AWS SSA Webinar 28 - Getting Started with AWS - Infrastructure as CodeAWS SSA Webinar 28 - Getting Started with AWS - Infrastructure as Code
AWS SSA Webinar 28 - Getting Started with AWS - Infrastructure as Code
 
Building CICD Pipelines for Serverless Applications
Building CICD Pipelines for Serverless ApplicationsBuilding CICD Pipelines for Serverless Applications
Building CICD Pipelines for Serverless Applications
 
Automate your Amazon SageMaker Workflows (July 2019)
Automate your Amazon SageMaker Workflows (July 2019)Automate your Amazon SageMaker Workflows (July 2019)
Automate your Amazon SageMaker Workflows (July 2019)
 
Cloudformation101
Cloudformation101Cloudformation101
Cloudformation101
 
Twelve-Factor serverless applications - MAD307 - New York AWS Summit
Twelve-Factor serverless applications - MAD307 - New York AWS SummitTwelve-Factor serverless applications - MAD307 - New York AWS Summit
Twelve-Factor serverless applications - MAD307 - New York AWS Summit
 
AWS CloudFormation Intrinsic Functions and Mappings
AWS CloudFormation Intrinsic Functions and Mappings AWS CloudFormation Intrinsic Functions and Mappings
AWS CloudFormation Intrinsic Functions and Mappings
 
Alex Casalboni - Configuration management and service discovery - Codemotion ...
Alex Casalboni - Configuration management and service discovery - Codemotion ...Alex Casalboni - Configuration management and service discovery - Codemotion ...
Alex Casalboni - Configuration management and service discovery - Codemotion ...
 
Deep Dive on AWS CloudFormation
Deep Dive on AWS CloudFormationDeep Dive on AWS CloudFormation
Deep Dive on AWS CloudFormation
 
Local Testing and Deployment Best Practices for Serverless Applications - AWS...
Local Testing and Deployment Best Practices for Serverless Applications - AWS...Local Testing and Deployment Best Practices for Serverless Applications - AWS...
Local Testing and Deployment Best Practices for Serverless Applications - AWS...
 

Más de Amazon Web Services

Tools for building your MVP on AWS
Tools for building your MVP on AWSTools for building your MVP on AWS
Tools for building your MVP on AWS
Amazon Web Services
 
How to Build a Winning Pitch Deck
How to Build a Winning Pitch DeckHow to Build a Winning Pitch Deck
How to Build a Winning Pitch Deck
Amazon Web Services
 
Building a web application without servers
Building a web application without serversBuilding a web application without servers
Building a web application without servers
Amazon Web Services
 
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
Amazon Web Services
 

Más de Amazon Web Services (20)

Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
Come costruire servizi di Forecasting sfruttando algoritmi di ML e deep learn...
 
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
Big Data per le Startup: come creare applicazioni Big Data in modalità Server...
 
Esegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS FargateEsegui pod serverless con Amazon EKS e AWS Fargate
Esegui pod serverless con Amazon EKS e AWS Fargate
 
Costruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWSCostruire Applicazioni Moderne con AWS
Costruire Applicazioni Moderne con AWS
 
Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot Come spendere fino al 90% in meno con i container e le istanze spot
Come spendere fino al 90% in meno con i container e le istanze spot
 
Open banking as a service
Open banking as a serviceOpen banking as a service
Open banking as a service
 
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
Rendi unica l’offerta della tua startup sul mercato con i servizi Machine Lea...
 
OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...OpsWorks Configuration Management: automatizza la gestione e i deployment del...
OpsWorks Configuration Management: automatizza la gestione e i deployment del...
 
Microsoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows WorkloadsMicrosoft Active Directory su AWS per supportare i tuoi Windows Workloads
Microsoft Active Directory su AWS per supportare i tuoi Windows Workloads
 
Computer Vision con AWS
Computer Vision con AWSComputer Vision con AWS
Computer Vision con AWS
 
Database Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatareDatabase Oracle e VMware Cloud on AWS i miti da sfatare
Database Oracle e VMware Cloud on AWS i miti da sfatare
 
Crea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJSCrea la tua prima serverless ledger-based app con QLDB e NodeJS
Crea la tua prima serverless ledger-based app con QLDB e NodeJS
 
API moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e webAPI moderne real-time per applicazioni mobili e web
API moderne real-time per applicazioni mobili e web
 
Database Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatareDatabase Oracle e VMware Cloud™ on AWS: i miti da sfatare
Database Oracle e VMware Cloud™ on AWS: i miti da sfatare
 
Tools for building your MVP on AWS
Tools for building your MVP on AWSTools for building your MVP on AWS
Tools for building your MVP on AWS
 
How to Build a Winning Pitch Deck
How to Build a Winning Pitch DeckHow to Build a Winning Pitch Deck
How to Build a Winning Pitch Deck
 
Building a web application without servers
Building a web application without serversBuilding a web application without servers
Building a web application without servers
 
Fundraising Essentials
Fundraising EssentialsFundraising Essentials
Fundraising Essentials
 
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
AWS_HK_StartupDay_Building Interactive websites while automating for efficien...
 
Introduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container ServiceIntroduzione a Amazon Elastic Container Service
Introduzione a Amazon Elastic Container Service
 

AWS CloudFormation macros: Coding best practices - MAD201 - New York AWS Summit

  • 1. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T AWS CloudFormation macros: Coding best practices Dan Blanco Developer Advocate AWS CloudFormation Amazon Web Services M A D 2 0 1 Jing Ling Senior Product Manager AWS CloudFormation Amazon Web Services
  • 2. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Agenda • Deep dive • Introduction to macros • DSL vs. custom resources vs. macros • Creating and using macros • Example macros • Development best practices • Writing • Testing • Deploying • Live demo • Setting up your environment (CI/CD pipeline) • Authoring and deploying your macros
  • 3. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T InfrastructureascodewithAWSCloudFormation Code in YAML or JSON directly or use sample templates Upload local files or from an Amazon S3 bucket Create stack using console, API, or the AWS CLI Stacks and resources are provisioned
  • 4. S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
  • 5. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T What’s a macro? Custom template processing code Runs on entire template or a snippet Executes on template ingestion Runs a Lambda function on your behalf Create your own intrinsic functions
  • 6. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T DSL vs. custom resources vs. macros TemplateProvisioning LockTemplate Templatecanchange Resourcesareprovisioned TemplateVerification Templatecannotchange Runtime Custom Resources ConsumeTemplate Macros TemplateGeneration Template iscomposed DSL • Runs before resources are provisioned • Can modify the template • Runs while resources are being provisioned • Has context of other resources in the stack • !Refs, !GetAtts, etc., are fully realized • Can fail a stack or continue on • Needs to handle create/update/delete scenarios • Generates AWS CloudFormation templates • No access to AWS CloudFormation pre-processing or stack resources • Use native language constructs and libraries • Examples: • CDK • SparkleFormation • Troposphere
  • 7. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Steps to create and use a macro 1. Write, test, and deploy your macro to Lambda 2. Register your macro to AWS CloudFormation; this reserves the macro name in your account and region 3. Invoke your registered macro through a AWS CloudFormation template A macro is invoked through a transform function and can be scoped to be template-wide or a single resource
  • 8. S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
  • 9. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Macro examples Iterator/Loop • Make me X number of this resource Execute Python • Pass arbitrary code Globals • Add Global Variables Defaults • If resource X is declared, add default attributes
  • 10. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Iterator/loop:Usingyourmacro Transform: - Count Resources: Bucket: Type: AWS::S3::Bucket Count: 3 Transform: - Count Sqs: Type: AWS:::SQS::Queue Count: 2 Resources: Bucket1: Type: AWS::S3::Bucket Bucket2: Type: AWS::S3::Bucket Bucket3: Type: AWS::S3::Bucket Resources: Sqs1: Type: AWS:::SQS::Queue Sqs2: Type: AWS:::SQS::Queue
  • 11. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Iterator/loop:Lambdacode import copy def process_template(template): new_template = copy.deepcopy(template) status = 'success' for name, resource in template['Resources'].items(): if 'Count' in resource: count = new_template['Resources'][name].pop('Count') multiplied = multiply(name, new_template['Resources'][name], count) if not set(multiplied.keys()) & set(new_template['Resources'].keys()): new_template['Resources'].update(multiplied) else: status = 'failed' return status, template return status, new_template def multiply(resource_name, resource_structure, count): resources = {} for iteration in range(1, count): resources[resource_name+str(iteration)] = resource_structure return resources def handler(event, context): result = process_template(event['fragment']) return { 'requestId': event['requestId'], 'status': result[0], 'fragment': result[1], }
  • 12. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Iterator/loop:Deployandregisterthemacro AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: Macro: Type: AWS::CloudFormation::Macro Properties: Name: Count FunctionName: !GetAtt CountMacroFunction.Arn CountMacroFunction: Type: AWS::Serverless::Function Properties: CodeUri: src Handler: index.handler Runtime: python3.6 Timeout: 5
  • 13. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T ExecutePythonmacro AWSTemplateFormatVersion: "2010-09-09" Description: tests String macro functions Parameters: Tags: Default: "Env=Prod,Application=MyApp,BU=ModernisationTeam" Type: "CommaDelimitedList" Resources: S3Bucket: Type: "AWS::S3::Bucket" Properties: Tags: | #!PyPlate output = [] for tag in params['Tags']: key, value = tag.split('=') output.append({"Key": key, "Value": value}) Transform: [PyPlate] def handler(event, context): macro_response = { "requestId": event["requestId"], "status": "success" } try: params = { "params": event["templateParameterValues"], "template": event["fragment"], "account_id": event["accountId"], "region": event["region"] } response = event["fragment"] macro_response["fragment"] = obj_iterate(response, params) except Exception as e: traceback.print_exc() macro_response["status"] = "failure" macro_response["errorMessage"] = str(e) return macro_response
  • 14. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Macro:Globalvariables Transform: Globals Globals: SomeText: some-text ThingTag: Key: Thing Value: This is a thing Resources: Bucket: Type: AWS::S3::Bucket Properties: BucketName: "@SomeText" Tags: - "@ThingTag" - Key: OtherThing Value: Other thing value Resources: Bucket: Type: AWS::S3::Bucket Properties: BucketName: “some-text" Tags: - Key: Thing Value: This is a thing - Key: OtherThing Value: Other thing value
  • 15. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Globalvariables class Repeater(): def __init__(self, template): self.repeaters = template["Globals"] del template["Globals"] self.template = template def process(self): return self.__walk(self.template) def __walk(self, fragment): if isinstance(fragment, str) and any(fragment == "@{}".format(key) for key in self.repeaters): return self.repeaters[fragment[1:]] elif isinstance(fragment, dict): return { key: self.__walk(value) for key, value in fragment.items() } elif isinstance(fragment, list): return [ self.__walk(value) for value in fragment ] return fragment def handler(event, context): return { "requestId": event["requestId"], "status": "success", "fragment": Repeater(event["fragment"]).process(), }
  • 16. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Generateadditionalresourcesandsetdefaultsmacro Transform: Defaults Resources: Bucket1: Type: AWS::S3::Bucket Resources: Bucket1: Type: AWS::S3::Bucket Properties: AccessControl: Private Bucket1Policy: Type: AWS::S3::BucketPolicy Properties: Bucket: Ref: Bucket1 PolicyDocument: Version: "2012-10-17" Statement: - Effect: Deny Principal: "*" Action: "s3:Delete*" Resource: Fn::Sub: "arn:aws:s3:::${Bucket1}/*" Condition: Bool: aws:MultiFactorAuthPresent: "false" Whenever a bucket is defined… • Add access control property • Add bucket policy • Generate additional resources, intrinsic function calls, conditions, more • Macro can allow user to override defaults
  • 17. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Advanced:Settingupdefaults DEFAULTS = json.load(open("defaults.json")) def interpolate(name, string): return string.replace("{$}", name) def get_additional_resources(name, props): additional_resources = {} for key, value in props.items(): key = interpolate(name, key) if isinstance(value, dict): additional_resources[key] = get_additional_resources(name, value) elif isinstance(value, list): additional_resources[key] = [ get_additional_resources(name, v) for v in value ] elif isinstance(value, str): additional_resources[key] = interpolate(name, value) else: additional_resources[key] = value return additional_resources def process_property(key, default, resource): # Recursive prop = resource[key] if isinstance(prop, dict): if "Defaults::Override" in prop: resource[key] = prop["Defaults::Override"] else: resource[key] = default elif isinstance(default, dict): for k in default.keys(): if k in prop.keys(): process_property(k, default[k], prop) else: prop[k] = default[k] else: resource[key] = default def process_resource(name, resource, additional_resources): default = DEFAULTS[resource["Type"]] if "Properties" not in resource: resource["Properties"] = {} # Handle properties for key, prop in default["Properties"].items(): if key not in resource["Properties"]: resource["Properties"][key] = prop else: process_property(key, prop, resource["Properties"]) # Add additional resources additional_resources.update(get_additional_resources(name, default.get("AdditionalResources", {}))) def process(template): additional_resources = {} for name, resource in template["Resources"].items(): if resource["Type"] in DEFAULTS: process_resource(name, resource, additional_resources) template["Resources"].update(additional_resources) return template
  • 18. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Advanced:Settingupdefaults { "AWS::S3::Bucket": { "Properties": { "AccessControl": "Private", "VersioningConfiguration": { "Status": "Enabled" } }, "AdditionalResources": { "{$}Policy": { "Type": "AWS::S3::BucketPolicy", "Properties": { "Bucket": { "Ref": "{$}" }, "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:Delete*", "Resource": { "Fn::Sub": "arn:aws:s3:::${{$}}/*" }, "Condition": { "Bool": { "aws:MultiFactorAuthPresent": "false" } … Specify additional resources in a side file
  • 19. S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
  • 20. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Writing • Set up your authoring environment • Set up a CI/CD pipeline before you even start • Use your IDE of choice, set up for your favorite language • Keep it simple • Determine if your macro should be a snippet or template-wide • A macro should do one thing well • Don’t be afraid to break larger macros apart into smaller ones • Make it testable • Keep your functions small • Macros are pure by default; no state required
  • 21. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Test your macro Test like you would a Lambda function Use AWS SAM or serverless local for testing
  • 22. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Deploy your macro Deploy like you would a Lambda function Use AWS SAM, serverless, Chalice, or Zappa
  • 23. S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.
  • 24. © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved.S U M M I T Summary • Remember when a macro runs • Determine if snippet or template-wide • Keep it simple • Set up your pipeline first • Test, test, test
  • 25. Thank you! S U M M I T © 2019, Amazon Web Services, Inc. or its affiliates. All rights reserved. Dan Blanco Developer Advocate AWS CloudFormation @thedanblanco Jing Ling Product Manager AWS CloudFormation