Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Automating your Infrastructure Deployment with AWS CloudFormation and AWS OpsWorks

8,206 views

Published on

When you’re building a new application you need to get new features out fast. Managing your application’s infrastructure as well as responding to changing conditions can be cumbersome and error prone if you rely on manual processes. Treating your infrastructure as code allows you to provision and update complex environments in a predictable manner. You can also offer a pre-defined catalogue of environments for development, testing and experimentation, unlocking your ability to innovate. This session will walk through practical examples and live demonstrations using AWS CloudFormation, AWS OpsWorks, orchestration engines and source control systems to automate your infrastructure deployment and maintenance.

Speaker: Richard Busby, Solutions Architect, Amazon Web Services

Published in: Technology

Automating your Infrastructure Deployment with AWS CloudFormation and AWS OpsWorks

  1. 1. Automating your infrastructure deployment with CloudFormation and OpsWorks Richard Busby, Solutions Architect Amazon Web Services
  2. 2. Business 101 Technical 201 Technical 301 Technical 401 Technical Session Grading
  3. 3. • Repeatable deployments • Versioned Infrastructure as code • Use-case specific deployments • Management at scale • Application automation Why treat your infrastructure as code?
  4. 4. • Repeatable deployments • Versioned Infrastructure as code • Use-case specific deployments • Management at scale • Application automation A love story
  5. 5. A Simple Wordpress deployment with CloudFormation Users Web Server RDS Database security group security group
  6. 6. Automating instance configuration: using cfn-init "Resources" : { "WebServer": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } }, "UserData" : { "/opt/aws/bin/cfn-init -s<stackID> -r<ResourceID> --region <Region>" } • Packages • Groups • Users • Sources • Files • Commands • Services
  7. 7. Automating instance configuration: using cfn-init "Resources" : { "WebServer": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } }, "UserData" : { "/opt/aws/bin/cfn-init -s<stackID> -r<ResourceID> --region <Region>" } • Packages • Groups • Users • Sources • Files • Commands • Services
  8. 8. Automating instance configuration: using cfn-init "Resources" : { "WebServer": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } }, "UserData" : { "/opt/aws/bin/cfn-init -s<stackID> -r<ResourceID> --region <Region>" } • Packages • Groups • Users • Sources • Files • Commands • Services
  9. 9. How cfn-init works instancestack "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } AWS CloudFormation
  10. 10. How cfn-init works instancestack #> cfn-init -–stack <stackname> --resource <resourcename> "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } AWS CloudFormation
  11. 11. How cfn-init works instancestack #> cfn-init -–stack <stackname> --resource <resourcename> "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } Get metadata, perform actions AWS CloudFormation
  12. 12. Signalling instance configuration: using creationPolicy "Resources" : { "WebServer": { "Type": "AWS::EC2::Instance", "CreationPolicy": { "ResourceSignal": { "Count": "1", "Timeout": "PT15M" } } }, "Metadata" : { "UserData" : { "/opt/aws/bin/cfn-signal –-stack <stackID> --resource <ResourceID> --success" } } • Property of an EC2 instance or Auto Scaling Group • Inform CloudFormation when configuration is complete
  13. 13. Signalling instance configuration: using creationPolicy "Resources" : { "WebServer": { "Type": "AWS::EC2::Instance", "CreationPolicy": { "ResourceSignal": { "Count": "1", "Timeout": "PT15M" } } }, "Metadata" : { "UserData" : { "/opt/aws/bin/cfn-signal –-stack <stackID> --resource <ResourceID> --success" } } • Property of an EC2 instance or Auto Scaling Group • Inform CloudFormation when configuration is complete
  14. 14. How creationPolicy works "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } instancestackAWS CloudFormation
  15. 15. How creationPolicy works #> cfn-signal --success --stack <stackname> --resource <resourcename> "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } instancestackAWS CloudFormation
  16. 16. How creationPolicy works #> cfn-signal --success --stack <stackname> --resource <resourcename> Send completion signal "AWS::CloudFormation::Init" : { "config" : { "packages" : { "httpd" : ["2.4.12"] } "commands" : { "WriteDemoToFile" : { "command" : "echo "Demo" > test.txt" } } } } instancestackAWS CloudFormation
  17. 17. Completing instance configuration: using waitCondition "Resources" : { "WaitCondition" : { "Type" : "AWS::CloudFormation::WaitCondition", "DependsOn" : "WebServer", "Properties" : { "Handle" : {"Ref" : "WaitHandle"}, "Timeout" : "600" } }, "WebServer": { "Type": "AWS::EC2::Instance", "Metadata" : { "UserData" : { "/opt/aws/bin/cfn-signal –success <waitconditionhandle>" } } • A separate resource
  18. 18. Completing instance configuration: using WaitCondition Instance A stackAWS CloudFormation Instance B
  19. 19. Completing instance configuration: using WaitCondition WaitCondition Resource "Count": "2" Instance A stackAWS CloudFormation Instance B #> cfn-signal –-success <URL> #> cfn-signal –-success <URL>
  20. 20. Completing instance configuration: using WaitCondition WaitCondition Resource "Count": "2" Instance A stackAWS CloudFormation Instance B #> cfn-signal –-success <URL> Send Completion signal #> cfn-signal –-success <URL>
  21. 21. Create Templates from your environment with CloudFormer
  22. 22. The love story so far...
  23. 23. The love story so far... • Repeatable deployments
  24. 24. Versioning your infrastructure Users Web Server RDS Database security group security groupRoute 53
  25. 25. Versioning your infrastructure Users Web Server RDS Database security group security groupRoute 53
  26. 26. • Modify existing template • Or create a new one – Ensure all resources are present • Infrastructure as Code: – Store in version control – Store with your code – Git, Subversion, etc Update your template, apply it to the stack "Resources" : { "BrandNewDNSrecord" : { "Type" : "AWS::Route53::RecordSet", "Properties" : { "Comment" : "Demo for Summit 2015", "HostedZoneId" : "ABC123BUZZY", "Name" : "summit.buzzy.geek.nz.", "TTL" : "60", "Type" : "A" } } }
  27. 27. Controlling stack updates: Resource updates
  28. 28. Controlling stack updates: Resource updates
  29. 29. • Prevent updates to resources within the stack • Explicitly override during updates – A temporary change of policy Controlling stack updates: stack policies { "Statement" : [ { "Effect" : "Deny", "Action" : "Update:*", "Principal": "*", "Resource" : "*" } ] }
  30. 30. Updating a stack where Resource properties require replacement
  31. 31. Updating a stack where Resource properties require replacement
  32. 32. Updating a stack where Resource properties require replacement
  33. 33. Controlling stack deletion: DeletionPolicy "Resources" : { "myS3Bucket" : { "Type" : "AWS::S3::Bucket", "DeletionPolicy" : "Retain" } }
  34. 34. Demo 1
  35. 35. The love story so far...
  36. 36. The love story so far... • Repeatable deployments • Versioned Infrastructure as code
  37. 37. Deploying different environments • Multiple similar environments – Production – Test, Development – Multiple AWS regions • Avoid becoming a template factory – Fewer, more adaptable templates
  38. 38. Example: Production or Dev? stack Auto Scaling stack Elastic Load Balancing template Prod Dev Web Server security group RDS Database security group security group Instances RDS Database security group
  39. 39. • A parameter to specify the kind of stack Parameters and Conditions "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" } "Conditions" : { "UseProdCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Prod"] }, "UseDevCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Dev"] } "Resources": { "WebServer": { "Type": "AWS::EC2::Instance", "Condition": "useDevCondition", },
  40. 40. • A parameter to specify the kind of stack • Conditions that will be evaluated Parameters and Conditions "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" } "Conditions" : { "UseProdCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Prod"] }, "UseDevCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Dev"] } "Resources": { "WebServer": { "Type": "AWS::EC2::Instance", "Condition": "UseDevCondition", },
  41. 41. • A parameter to specify the kind of stack • Conditions that will be evaluated • Determines whether a resource or property should be created Parameters and Conditions "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" } "Conditions" : { "UseProdCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Prod"] }, "UseDevCondition" : { "Fn::Equals" : [{"Ref" : "EnvironmentType"}, "Dev"] } "Resources": { "WebServer": { "Type": "AWS::EC2::Instance", "Condition": "UseDevCondition", },
  42. 42. Example: Production or Dev? stack Auto Scaling stack Elastic Load Balancing template Web Server security group RDS Database security group security group Instances Parameter: Prod or Dev RDS Database security group
  43. 43. • Logic about how a resource will be created Mappings "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" }, "Mappings" : { "SourceAMI" : { "Prod" : { "ap-southeast-1" : "ami-d34db33f", "us-east-1" : "ami-12345678" }, "Dev" : { "ap-southeast-1" : "ami-d5f8fc0d", "us-east-1" : "ami-b6c63d8f" } } } "Resources": { "WebServer": { "ImageID" : { "Fn::FindInMap" : [ "SourceAMI", { "Ref" : "EnvironmentType" }, { "Ref" : "AWS::Region" ] }
  44. 44. • A mapping consists of two- level key:value pairs Mappings "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" }, "Mappings" : { "SourceAMI" : { "Prod" : { "ap-southeast-1" : "ami-d34db33f", "us-east-1" : "ami-12345678" }, "Dev" : { "ap-southeast-1" : "ami-d5f8fc0d", "us-east-1" : "ami-b6c63d8f" } } } "Resources": { "WebServer": { "ImageID" : { "Fn::FindInMap" : [ "SourceAMI", { "Ref" : "EnvironmentType" }, { "Ref" : "AWS::Region" ] }
  45. 45. Looking up the mapping "Parameters" : { "EnvironmentType" : { "Description" : "Production or Development environment", "AllowedValues" : [ "Prod", "Dev" ], "ConstraintDescription" : "Must be Prod or Dev" }, "Mappings" : { "SourceAMI" : { "Prod" : { "ap-southeast-1" : "ami-d34db33f", "us-east-1" : "ami-12345678" }, "Dev" : { "ap-southeast-1" : "ami-d5f8fc0d", "us-east-1" : "ami-b6c63d8f" } } } "Resources": { "WebServer": { "ImageID" : { "Fn::FindInMap" : [ "SourceAMI", { "Ref" : "EnvironmentType" }, { "Ref" : "AWS::Region" ] } • Referenced by a property
  46. 46. Demo 2
  47. 47. The love story so far...
  48. 48. The love story so far... • Repeatable deployments • Versioned Infrastructure as code • Use-case specific deployments
  49. 49. Expanding your use of CloudFormation: 
 Working with multiple templates • An inevitability as you grow – Stack limits (60 outputs, 200 resources, 51200 bytes) – Segregation of duties – Velocity of change • Layers of stacks – Identity – Network – Shared services – Back end services – Front end services
  50. 50. Nested stacks stack stack template Amazon VPC Auto Scaling Elastic Load Balancing RDS Database security group security group Instances
  51. 51. Chaining stacks together stacktemplate ”Outputs" : { ”VPCInfo" : { ”VPCName” : { ”Fn::GetAtt" : { ”VPC:Name”} } »VPCid" : { ”Fn::GetAtt" : { ”VPC::ID” } } } Outputs Amazon VPC
  52. 52. Chaining stacks together stacktemplate ”Outputs" : { ”VPCInfo" : { ”VPCName” : { ”Fn::GetAtt" : { ”VPC:Name”} } »VPCid" : { ”Fn::GetAtt" : { ”VPC::ID” } } } Outputs #> DeployComputeStack.rb Amazon VPC
  53. 53. Chaining stacks together stack stack template ”Outputs" : { ”VPCInfo" : { ”VPCName” : { ”Fn::GetAtt" : { ”VPC:Name”} } »VPCid" : { ”Fn::GetAtt" : { ”VPC::ID” } } } Outputs #> DeployComputeStack.rb Amazon VPC Auto Scaling Elastic Load Balancing security group Instances
  54. 54. The love story so far...
  55. 55. The love story so far... • Repeatable deployments • Versioned Infrastructure as code • Use-case specific deployments • Management at scale
  56. 56. Hi!  I’m  Ben  Salt. Senior  Solutions  Architect, Platform  Services  Team,  Xero.
  57. 57. Xero Leading small business cloud platform Vision Millions of people all over the world love doing business on Xero Mission Grow prosperity by connecting people through beautifully designed business software Goal Achieving scale and value by winning one million+ customers
  58. 58. Technology at Xero • Mostly a Microsoft shop – Big SQL Server user – Lots of .NET web applications
 • Linux is used for some functionality – Redis – Cassandra – Elastic Search
  59. 59. Our Journey – In the beginning
  60. 60. Our Journey – Introducing CloudFormation • Started Small – A single template – Provisioned a VPC, Subnets, Internet Gateway, NAT instance and Windows box! • Then – we added more... – Added some more network configuration – Provisioned some more Windows boxes
  61. 61. Our Journey – Introducing CloudFormation • But, we ran into some problems – There is a file size limit – 460,800 bytes – JSON syntax validation – Lots of changes, engineers starting to overwrite each other – Other limits, in particular • 60 parameters • 60 outputs
  62. 62. Our Journey – Tooling • JSON Syntax Validation – We wrote a Powershell JSON validation script – Recently expanded it validate parameters • Source Control – Placed CloudFormation scripts in Source Control – Wrote a “Sync to S3” script • Visual Studio – Helped with syntax – AWS Tools for Visual Studio are a must!
  63. 63. Our Journey – Nested Stacks • To get around the file size and parameter issue: – Split the stack into a number of components – AWS::CloudFormation::Stack – Parameters made parts of the stack reusable • VPC Formation • Web Server Provisioning
  64. 64. Our Journey – Fun with Parameters • String • Number • List<Number> • CommaDelimitedList • AWS::EC2::KeyPair::KeyName • AWS::EC2::SecurityGroup::Id • AWS::EC2::VPC::Id • List<AWS::EC2::VPC::Id> • List<AWS::EC2::SecurityGroup::Id> • List<AWS::EC2::Subnet::Id> http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
  65. 65. Our Journey – Fun with Parameters "Parameters" : { "ipProxyPublic1" : { "Description" : "Public IP Address for Proxy1", "Type" : "String” }, "SecurityGroupForProxy" : { "Description" : "Comma Delimited String of Security Groups...”, "Type" : "List<AWS::EC2::SecurityGroup::Id>” } }
  66. 66. Our Journey – Fun with Parameters "DeployProxy": { "Type" : "AWS::CloudFormation::Stack”, "Properties" : { "TemplateURL" : "proxy.template", "Parameters" : { "ipProxyPublic1" : { "Fn::GetAtt" : [ "CreateElasticIPs", "Outputs.eipProxyPublicAddress1" ] }, "SecurityGroupForProxy" : {"Fn::Join" : [ ",", [ { "Fn::GetAtt" : [ "CreateSecurityGroups", "Outputs.sgAllowELBAccess" ] }, { "Fn::GetAtt" : [ "CreateSecurityGroups", "Outputs.sgManagementAccess"] } ]]} } } }
  67. 67. Our Journey – What we ended up with Main Stack DeployNetwork >DeployVPC1 >DeployVPC2 >DeployVPC3 VPCPeering >DeploySubnetsforVPC1 >DeploySubnetsforVPC2 >DeploySubnetsforVPC3 DeployCoreInfrastructure CreateElasticIPs >CreateSecurityGroups >DeployProxy >FirstDomainController >SubsequentDomainController >FirstDNSServer >SubsequentDNSServer >RemoteDesktopServers DeployApplicationStack ...
  68. 68. Our Journey – Nested Stacks
  69. 69. Our Journey – What’s Next? • CI / CD – Automates the creation and updates of the stack • Decomposing the Nested Stack – Let CI assist with the orchestration • Implement an Infrastructure Testing Framework – Infrastructure as code is great – but how do you test it?
  70. 70. OpsWorks
  71. 71. OpsWorks: model your application
  72. 72. OpsWorks lifecycle events setup configure deploy undeploy shutdown
  73. 73. Chef recipe + Metadata = Command execute "mysql-connect" do command "/usr/bin/mysql -u#{node[:deploy][:myphpapp][:database][:username]} -p#{node[:deploy][:myphpapp][:database][:password]} #{node[:deploy][:myphpapp][:database][:database]} … "deploy": { "myphpapp": { "database": { "username": "root", "password": "abcxyz", … "/usr/bin/mysql -uroot –pabcxyz myphpapp … Configure with Chef recipes
  74. 74. Setup Configure Deploy Execute recipes Shutdown Attach recipes to events
  75. 75. App Server Setup Configure Deploy Execute recipes Shutdown Attach recipes to events Setup Configure Deploy
  76. 76. App Server RDS Database Setup Configure Deploy Execute recipes Shutdown Attach recipes to events Setup Configure Deploy Setup Configure
  77. 77. App Server RDS Database Setup Configure Deploy Execute recipes Shutdown Attach recipes to events Setup Configure Deploy Setup Configure Configure
  78. 78. App Server RDS Database Setup Configure Deploy Execute recipes Shutdown App Server Attach recipes to events Setup Configure Deploy Setup Configure Configure
  79. 79. App Server RDS Database Setup Configure Deploy Execute recipes Shutdown App Server Attach recipes to events Setup Configure Deploy Change permissions Setup Configure Configure
  80. 80. • OpsWorks items as CloudFormation resources • Automate deployment with CloudFormation • Automate "Day 2" management tasks with OpsWorks Combining OpsWorks and CloudFormation "Resources" : { "WordPressStack" : { "Type" : "AWS::OpsWorks::Stack", "Properties" : { "Name" : "MyWordPressStack", "ServiceRoleArn" : "arn:aws:iam::0123456789:role/service-role", "DefaultSshKeyName" : {"Ref":"KeyName"} } }, "myLayer": { "Type": "AWS::OpsWorks::Layer", "Properties": { "StackId": {"Ref": "WordPressStack"}, "Name": "PHP App Server", "Type": "php-app" } }
  81. 81. The love story so far...
  82. 82. The love story so far... • Repeatable deployments • Versioned Infrastructure as code • Use-case specific deployments • Management at scale • Application automation
  83. 83. Next steps • Get the templates used in this session: http://s3.buzzy.geek.nz/summit2015 • Experiment!

×