A complete version of the network stack template can be found at https://github.com/PacktPublishing/AWS-DevOps-Simplified/blob/main/chapter-4/ cfn-templates/network-stack.yml.

From the AWS console, let’s initiate a new session for our Cloud9 IDE. Once logged in, switch to the chapter-4/ resources and trigger a stack deployment with the following command:

aws cloudformation deploy \

–stack-name networking-stack \

–region eu-central-1 \

–parameter-overrides EnvironmentName=aws-devops-simplified \ –template-file network-stack.yml

Waiting for changeset to be created..

Waiting for stack create/update to complete

Successfully created/updated stack – networking-stack

At this point, all the networking resources should be available in your AWS account, in the eu-central-1 region, allowing us to proceed with the application deployment. Let’s see what theapplication design and corresponding stack look like.

If you would like to see the exported data from this stack, CloudFormation offers a CLI command for this. It lists all the stack exports available in this AWS account, in the targeted region:

bash-5.1# aws cloudformation list-exports \ –region eu-central-1 \

“Exports”:

“ExportingStackId”: “arn:aws:cloudformation:eu-central-1:

643998996127:stack/networking-stack/7405c610-8540-11ed-a5cd-02aac4a6643a”,

“Name”: “networking-stack-vpc-id”,

“Value”: “vpc-0c522c9e7f154179e”

Hosting a sample web application with an application load balancer and Auto Scaling groups

We created our network resources across two separate availability zones in the eu-central-1 region. For the application to benefit from this, we will deploy an Auto Scaling group (ASG) that covers both of these AZs. An ASG is an EC2 feature that offers automatic scale-in and scale-out of your application workloads, depending on some usage metrics. Due to the scope of this chapter, we will not go into a lot of the configuration details; instead; we will focus more on how the resources from the previous stack deployment will be consumed by our application. Since our backend instances will be hosted in the private subnets, we will expose them to the outside world via an internet-facing ABL, deployed in public subnets. The final application design that we will deploy can be seen in Figure 4.4:

Figure 4.4: Web application with ALB and Auto Scaling groups

Let’s discuss the various CloudFormation resources that come together to host the web application on top of the infrastructure components we deployed in the previous section.

Application Load Balancer

The ALB is the component that supports both internet-facing and internal-only deployments. For our use case, we go with an internet-facing deployment scheme and host the load balancer in the public subnets. When an end user accesses the ALB domain in their browser, it resolves to the public IP addresses of the corresponding network interfaces, and the traffic is forwarded to the backend EC2 instances:

Resources:

AppLoadBalancer:

Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties:

Type: application

Scheme: internet-facing

Subnets:

– Fn::ImportValue:

‘Fn::Sub’: “${NetworkStackName}-public-subnet1”

– Fn::ImportValue:

‘Fn::Sub’: “${NetworkStackName}-public-subnet2”

SecurityGroups:

– !Ref AppLoadBalancerSecurityGroup

AppLoadBalancerSecurityGroup:

Type: AWS::EC2::SecurityGroup

Properties:

GroupDescription: This is the Security Group for ALB

SecurityGroupIngress:

– IpProtocol: tcp

FromPort: 80

ToPort: 80

CidrIp: 0.0.0.0/0

SecurityGroupEgress:

– IpProtocol: tcp

FromPort: 0

ToPort: 65535

CidrIp: 0.0.0.0/0

VpcId:

Fn::ImportValue:

‘Fn::Sub’: “${NetworkStackName}-vpc-id”…

ALB requires security group attachments, just like EC2 instances. Since this is an internet-facing application, we open the tcp traffic to the entire world with an ingress route for0.0.0.0/0, over port 80.

I would like to highlight the use of two intrinsic functions that were referenced in this template:

  • Importing stack outputs from a different deployment:

Fn::ImportValue, as its name suggests, is used to import the outputs from another stack. We used the aws cloudformation list-exports command to list the exports from the network stack. The same values are referenced here, using this function. This is how CloudFormation allows you to resolve inter-stack dependencies while keeping the templates modular, and teams agile.

  • Substituting data for generating configurations at runtime:

Not all configurations can be statically defined in the templates. As seen in this example, the network stack could have been named in different ways. To keep the template definition flexible, we substituted the value of the respective parameter to form a well-defined string. Eventually, this allows us to import the required value from another stack.

Leave a Reply

Your email address will not be published. Required fields are marked *