Transcript
Page 1: Immutable Deployments with AWS CloudFormation and AWS Lambda

(and AWS Lambda)

Page 2: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 3: Immutable Deployments with AWS CloudFormation and AWS Lambda

& aoepeople!

Page 4: Immutable Deployments with AWS CloudFormation and AWS Lambda

E-Commerce: Magento

CMS: TYPO3

Portals: ZF, Symfony,…

Mobile Searchperience: ElasticSearch

250+ people world-wide

(in 8 locations)

Global Enterprise Projects

Infrastructure: AWS

Page 5: Immutable Deployments with AWS CloudFormation and AWS Lambda

CloudFormation Lambda “Immutable”

Page 6: Immutable Deployments with AWS CloudFormation and AWS Lambda

/i(m)ˈmyo͞odəb(ə)l/

adjective

unchanging over time or unable to be changed.

“disposable” “ephemeral”

Page 7: Immutable Deployments with AWS CloudFormation and AWS Lambda

Pet Cattle

Page 8: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 9: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 10: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 11: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 12: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 13: Immutable Deployments with AWS CloudFormation and AWS Lambda

not disposable disposable

Page 14: Immutable Deployments with AWS CloudFormation and AWS Lambda

disposable

not disposable

disposable

Page 15: Immutable Deployments with AWS CloudFormation and AWS Lambda

Static Resources Build VPC Build

Page 16: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 17: Immutable Deployments with AWS CloudFormation and AWS Lambda

Build Bucket

IAM Setup

VPC

Static Resources

Build

Manual Setup

separate

CloudFormation

Stacks use resources

from underlying stacks as input

parameters Lambda functions,

Monitoring,…

Page 18: Immutable Deployments with AWS CloudFormation and AWS Lambda

Build Bucket

IAM Setup

Environment A (e.g. prod) Environment B (e.g. stage)

VPC VPC

Static Resources Static Resources

Build Build Build Build

Build X Build X+1 Build X Build X+1

Manual Setup

different scopes (build, environment,

account, global…)

Page 19: Immutable Deployments with AWS CloudFormation and AWS Lambda

Build Bucket

IAM Setup

Environment A (e.g. prod) Environment B (e.g. stage) Environment C (e.g. qa) Environment D (e.g. dev)

IAM Setup

VPC VPC VPC VPC

Static Resources Static Resources Static Resources Static Resources

Build Build Build Build Build Build Build Build

Build X Build X+1 Build X Build X+1 Build X Build X+1 Build X Build X+1

Manual Setup Manual Setup

Build Bucket Access

Page 20: Immutable Deployments with AWS CloudFormation and AWS Lambda

Private subnets

Public subnets

ElastiCache (Redis)

with replication groups

for cache and sessions

RDS (multi-az) with

DB subnet group

Bastion

server

s3: media

storage*

Route 53: DNS

configuration CloudFront

distribution

SSL

Certificates

Security group for Varnish servers

Security group for Magento servers

Security group for Load Balancer

Static Resources

Page 21: Immutable Deployments with AWS CloudFormation and AWS Lambda

Build

Auto Scaling group

Auto Scaling group

Elastic Load

Balancer

Auto-

Scaling

Group

Launch

Configurati

on

Scaling

Policy

Page 22: Immutable Deployments with AWS CloudFormation and AWS Lambda

Build

Auto Scaling group

Auto Scaling group

Elastic Load

Balancer

Auto-

Scaling

Group

Launch

Configurati

on

Scaling

Policy

Auto Scaling group Auto Scaling group

Page 23: Immutable Deployments with AWS CloudFormation and AWS Lambda

+1

Baking AMIs

Page 25: Immutable Deployments with AWS CloudFormation and AWS Lambda

Keep it simple…!

Page 26: Immutable Deployments with AWS CloudFormation and AWS Lambda

✔ ✔ (✔)

Page 27: Immutable Deployments with AWS CloudFormation and AWS Lambda

the “last mile”

most underestimated CFN feature!

Page 28: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 29: Immutable Deployments with AWS CloudFormation and AWS Lambda

var r = require('cfn-response'); exports.handler = function (event, context) { […] var res = {}; if (event.RequestType == 'Create') { res.Password = randomPassword(20); } r.send(event, context, r.SUCCESS, res); };

Page 30: Immutable Deployments with AWS CloudFormation and AWS Lambda

"IndexerDb": { "Type": "AWS::RDS::DBInstance", "Properties": { [...] "MasterUserPassword": {"Fn::GetAtt": ["GenerateDbPassword", "Password"]}, [...] } },

"GenerateDbPassword": { "Type": "Custom::PasswordGenerator", "Properties": { "ServiceToken": {"Ref": "PasswordGeneratorArn"} } },

Page 31: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 32: Immutable Deployments with AWS CloudFormation and AWS Lambda

• launch some ASGs (set DesiredCapacity) • create database passwords • tag all resources (incl. ElastiCache!) • restore database and media files • (one-time) install scripts (db migrations,…) • detect Varnish backends • wait for healthy backends in the ELBs • run infrastructure tests • cache warming • update Route53 records sets • delete old stacks • …

Page 33: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 34: Immutable Deployments with AWS CloudFormation and AWS Lambda

DesiredCapacity =

Number of Instances in current ASG x 1.2

better safe than sorry…

Page 35: Immutable Deployments with AWS CloudFormation and AWS Lambda

DesiredCapacity =

Number of Instances in current ASG x 1.2

Page 36: Immutable Deployments with AWS CloudFormation and AWS Lambda

DesiredCapacity =

Number of Instances in current ASG x 1.2

ScalingPolicy takes care…

Page 37: Immutable Deployments with AWS CloudFormation and AWS Lambda

"CountInstances": { "Type": "Custom::InstanceCounter", "Properties": { "ServiceToken": {"Ref": "InstanceCounter"}, "AutoScalingGroupTags": [ {"Key": "Environment", "Value": "prod"}, {"Key": "Type", "Value": "Frontend"} ], "Min": 1, "Max": 10, "Factor": "1.5" } },

"FrontendAsg": { "Type": "AWS::AutoScaling::AutoScalingGroup", "Properties": { [...] "DesiredCapacity": {"Fn::GetAtt": ["CountInstances", "Count"]}, "Tags": [ {"Key": "Environment", "Value": "prod", "PropagateAtLaunch": true}, {"Key": "Type", "Value": “Frontend", "PropagateAtLaunch": true} ] } },

Page 38: Immutable Deployments with AWS CloudFormation and AWS Lambda

Update Route53 record set

Page 39: Immutable Deployments with AWS CloudFormation and AWS Lambda

Update Route53 record set

Delete old stacks

Page 40: Immutable Deployments with AWS CloudFormation and AWS Lambda

"UpdateR53": { "DependsOn": [ "MagentoWaitCondition", "MagentoWorkerWaitCondition", "Elb"], "Type": "Custom::Route53Update", "Properties": { "ServiceToken": {"Ref": "R53Updater"}, "Name": {"Fn::Join": ["", [ "www-", {"Ref": "EnvironmentName"} ]]}, "HostedZoneId": {"Ref": "HostedZoneId"}, "AliasTargetDNSName": {"Fn::GetAtt": ["Elb", "DNSName"]}, "AliasTargetHostedZoneId": {"Fn::GetAtt": ["Elb", "CanonicalHostedZoneNameID"]}, "Comment": "Updated via CloudFormation/Lambda" } },

"DeleteStacks": { "Condition": "DeleteOldStacks", "DependsOn": ["UpdateR53"], "Type": "Custom::StackDeleter", "Properties": { "ServiceToken": {"Ref": "StackDeleter"}, "TagFilter": { "Environment": {"Ref": "EnvironmentName"}, "Type": "Deployment"}, "ExceptStackName": {"Ref": "AWS::StackName"} } }

Page 41: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 42: Immutable Deployments with AWS CloudFormation and AWS Lambda

+1

Baking AMIs

Tools+CI

Page 43: Immutable Deployments with AWS CloudFormation and AWS Lambda

Have fun filling out 47 form fields! :)

Page 44: Immutable Deployments with AWS CloudFormation and AWS Lambda

aoepeople/stackformation

command-line tool (Symfony console, uses

AWS SDK for PHP)

integrates nicely into your CI (Jenknis,…)

Page 45: Immutable Deployments with AWS CloudFormation and AWS Lambda

pre-process

Userdata

Lambda JS “Template”

superset of CFN template (JSON)

Parameters lookup from other stacks, env vars,…

Template

Parameter

Values

create/ update

Stack policies, Tags,…

Page 46: Immutable Deployments with AWS CloudFormation and AWS Lambda

Stack magento-stage-build-5

Stack magento-stage-build-6

Stack magento-prod-build-6

Stack magento-prod-build-5

CloudFormation Template

merge & pre-process

“CloudFormation+X” Template(s)

+ Dynamic Parameters

+ Stack Policies

+ Behavior

+ Tags …

Blueprint magento-{env:ENVIRONMENT}-build-{env:BUILD}

Blueprint magento-{env:ENVIRONMENT}-setup

Stack magento-stage-setup

Stack magento-prod-setup

Page 47: Immutable Deployments with AWS CloudFormation and AWS Lambda

blueprints: - stackname: 'magento-{env:BUILD}' template: 'magento.template' stackPolicy: 'policy.json' OnFailure: 'DO_NOTHING' parameters: Build: '{env:BUILD}' KeyPair: '{var:KeyPair}' VPC: '{resource:setupstack:VPC}' Subnet: '{resource:setupstack:Subnet}' InstanceSg: '{resource:setupstack:InstanceSg}' InstanceProfile: '{output:setupstack:InstanceProfile}' BootAmi: 'ami-06116566' tags: Environment: 'prod' Build: '{env:BUILD}'

enforce “immutability” by denying updates!

Page 48: Immutable Deployments with AWS CloudFormation and AWS Lambda

aoepeople/cfn-vpc

aoepeople/cfn-lambdahelper

aoepeople/cfn-amibaker

via composer

Page 49: Immutable Deployments with AWS CloudFormation and AWS Lambda

so we can integrate this into our CI pipeline…

Page 50: Immutable Deployments with AWS CloudFormation and AWS Lambda

Page 51: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 52: Immutable Deployments with AWS CloudFormation and AWS Lambda

aoepeople/awsinspector

command-line tool (Symfony console, uses

AWS SDK for PHP)

Domain models for PHP

Page 53: Immutable Deployments with AWS CloudFormation and AWS Lambda

$repository = new \AwsInspector\Model\Elb\Repository(); $dns = $repository->findElbsByTags([ 'Environment' => 'deploy', 'Build' => 554, 'Type' => 'Frontend’ ])->getFirst()->getDNSName();

Page 54: Immutable Deployments with AWS CloudFormation and AWS Lambda

> bin/awsinspector.php ec2:ssh -t Environment:prod –c Type –c Build

filter by tag

Please select an instance [0] i-1033ed9b (Type: Frontend; Environment: prod; Build: 477) [1] i-4ff36ec8 (Type: Backend; Environment: prod ; Build: 477) [2] i-5ab4322b (Type: Worker; Environment: prod; Build: 477) [3] i-705ad42f (Type: Worker; Environment: prod; Build: 476) >

• will take jump hosts into account (ProxyCommand)

• auto-detects your local

(encrypted) private keys

• multiplexed ssh connections

• run commands directly

Page 55: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 56: Immutable Deployments with AWS CloudFormation and AWS Lambda

logins, orders,…

deployments, scaling activity,…

JMeter response time, error rate,…

CPU, load, network I/O,…

Page 57: Immutable Deployments with AWS CloudFormation and AWS Lambda

correlate metrics from

various sources

Page 58: Immutable Deployments with AWS CloudFormation and AWS Lambda

Grafana ElasticSearch (Service)

time-series database

Page 59: Immutable Deployments with AWS CloudFormation and AWS Lambda

leftovers from “disposed” resources

Page 60: Immutable Deployments with AWS CloudFormation and AWS Lambda

“Ready for testing”

(WaitCondition)

setup terminate

instances

• Install JMeter

• Download

testcase from

S3

• Signal “Ready”

and wait

• Create Security

allowing access

to all IPs and

attach to UAT’s

ELB

Auto-Scaling Group

of Load Generator Instances

Spin up test

environment (incl. restoring db+media

snapshot from prod)

Run Stress Test

Delete test

environment* Delete self*

1.

2.

3. 4.

Time

timeout 3600 jmeter –n –t testcase.jmx

*via Lambda custom resource

Pushing samples in near real-time

via custom JMeter backend

listener

“Testing Completed”

(WaitCondition)

JMeter test

CloudFormation Stack

CloudFormation

Stack

Grafana ElasticSearch (Service)

CloudWatch

Lambda

find relevant resources for the current deployment (via tags),

collect metrics, and push them to ElasticSearch

Page 61: Immutable Deployments with AWS CloudFormation and AWS Lambda

CloudFormation Stack

• Install JMeter

• Download

testcase from S3

• Signal “Ready”

and wait

• Create SG

allowing access

to all IPs and

attach to UAT’s

ELB

Auto-Scaling Group of Load Generator Instances

Run Stress Test 2.

Time

timeout 3600 jmeter –n –t testcase.jmx

Delete test

environment* Delete self*

3. 4.

*via Lambda custom resource

Lambda

Grafana ElasticSearch (Service)

CloudWatch find relevant resources for the

current deployment (via tags),

collect metrics and push them to

ElasticSearch

Spin up test

environment (incl. restoring db+media

snapshot from prod)

1.

CloudFormation

Stack

setup terminate

instances JMeter test

Pushing samples in near real-time

via custom JMeter backend listener

“Ready for testing”

(WaitCondition)

“Testing Completed”

(WaitCondition)

Page 62: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 63: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 64: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 65: Immutable Deployments with AWS CloudFormation and AWS Lambda

https://blogs.aws.amazon.com/application-

management/post/Tx38Z5CAM5WWRXW/Faster-Auto-Scaling-in-AWS-

CloudFormation-Stacks-with-Lambda-backed-Custom-Resou

Page 66: Immutable Deployments with AWS CloudFormation and AWS Lambda

Provisioning

“Ready for baking”

(WaitCondition)

EC2

AMI Baker

(Lambda) Node.js SDK

AWS CLI

“Baking Completed”

(WaitCondition)

shutdown

(-> terminate)

ec2.createImage

aws ec2 wait image-available

AMI Baker

(Lambda) Node.js SDK

ec2.deleteImage

Custom

CloudFormation

Resource

Time

Page 67: Immutable Deployments with AWS CloudFormation and AWS Lambda
Page 68: Immutable Deployments with AWS CloudFormation and AWS Lambda

Page 69: Immutable Deployments with AWS CloudFormation and AWS Lambda

Follow me on twitter!

My blog


Top Related