Another option for deployment is to use AWS CloudFormation. CloudFormation is a service that lets you provision all sorts of AWS resources, offering an IaC approach. You define your resources in one or multiple templates, written in either YAML or JSON. YAML is typically easier and less verbose, compared to JSON, for humans to read and write. CloudFormation can be used to deploy infrastructure as well as application resources. Therefore, you can create infrastructure resources, such as VPCs, subnets, route tables, IAM roles, security groups, and more, and also deploy EC2 instances, create S3 buckets, instantiate RDS databases, and work with many other resources. For instance, you can also deploy a Lambda function or an application on Elastic Beanstalk using CloudFormation templates. For the complete list of resources supported by CloudFormation, please consult the AWS documentation at https://packt.link/6cofc. Without getting into too much detail and the complete anatomy of a CloudFormation template, we will simply illustrate how resources are actually declared through a concrete example. Take the example of a simple application on Elastic Beanstalk, similar to the sample application we previously created.
Your CloudFormation template first needs to contain the declaration of your Beanstalk environment, for instance, something like the following:
SampleEnvironment:
Type: AWS::ElasticBeanstalk::Environment
Properties:
Description: AWS Elastic Beanstalk Environment running a sample Node.js Application
ApplicationName:
Ref:
SampleApplication
TemplateName:
Ref:
SampleConfigurationTemplate
VersionLabel:
Ref:
SampleApplicationVersion
In the preceding YAML snippet, you can see that the Beanstalk environment definition references additional resources, highlighted in the code. Your CloudFormation template then also needs to include the definition of those referenced resources, that is, the Beanstalk application, the application version, and the application configuration.
The definitions of these resources would look something like this:
SampleApplication:
Type: AWS::ElasticBeanstalk::Application
Properties:
Description: AWS Elastic Beanstalk Sample Node.js Application
SampleApplicationVersion:
Type: AWS::ElasticBeanstalk::ApplicationVersion
Properties:
Description: Version 1.0
ApplicationName:
Ref:
SampleApplication
SourceBundle:
S3Bucket:
Fn::Join:
– “-“
– – elasticbeanstalk-samples
– Ref: AWS::Region
S3Key: nodejs-sample.zip
SampleConfigurationTemplate:
Type: AWS::ElasticBeanstalk::ConfigurationTemplate
Properties:
ApplicationName:
Ref:
SampleApplication
Description: SSH access to Node.JS Application
SolutionStackName: 64bit Amazon Linux 2018.03 v4.7.1 running Node.js
OptionSettings:
– Namespace: aws:autoscaling:launchconfiguration
OptionName: EC2KeyName
Value:
Ref: KeyName
– Namespace: aws:autoscaling:launchconfiguration
OptionName: IamInstanceProfile
Value:
Ref: WebServerInstanceProfile
This is essentially all you need to define your simple Beanstalk application using CloudFormation.
Note that some additional resource definitions have been omitted from the preceding YAML template for the sake of brevity. For a complete and fully functional template, please check out the various examples included in the CloudFormation documentation at https://packt.link/QLYFJ.
CloudFormation templates are deployed in your AWS environment as a stack, using either the AWS Management Console, the AWS CLI, or CloudFormation APIs. Once a CloudFormation stack is deployed, you manage the lifecycle of its resources by updating the stack. Before committing any changes to the stack, you can generate a change set that lets you assess the impact that your changes will have on existing resources. You can then decide whether to carry on with the stack update or amend your changes as needed.
CloudFormation is a vast topic and diving deep into details goes beyond the scope of this book. However, this book will focus on a few points of importance for a solutions architect to make informed design decisions.