RDV Tech Agile Partner : AWS Cloudformation – Part 4

By Olivier Robert, a Senior Consultant and DevOps Engineer at Agile Partner.

In Part 3, we ended up with a bastion host and a private host. But we still have a file named vpc.yalm. And we are still going to add to that file, in theory. So, maybe now would be a good time to split our infrastructure in different files.

We are going to separate the content from the vpc.yaml file and use a master.yaml file to do so. The master.yaml file will link to the vpc.yalm file and to the rest of our infrastructure yaml files.

What we will need in the master.yaml file are all the parameters and associated metadata because this is going to be the file we upload to Cloudformation. The other files will be at the ready in an S3 bucket.

You have already used Cloudformation in Part 1,2 and 3. But your IAM user will need S3 rights to create or at least upload and access files. If your IAM user has these permissions already, you are good to go. If not, you will have to ask your administrator for these permissions. If you have admin permissions already, you can add the necessary permissions to the IAM user you are using for this series or if it is your main IAM user, there is nothing to do. As service permissions can get tricky very quickly, in the discovery phase, it is best to not limit yourself too much with restrictive permissions. But, “with great power …”

As a side note, I suggest to create an IAM user with administrator permissions in a dedicated AWS throwaway account in your Organisation during the exploration phase. If this does not make any sense to you at this stage, it’s absolutely fine. Forget it, and move on.

Let’s create an S3 bucket. Give it a name, select the region you are working in and nothing more. Create it. Done.

 

 

We can add the VPC part in to the S3 bucket, we just have to remove the bastion and private host bits from the vpc.yaml file in the Metadata, Parameters and Resources sections. Once the file is uploaded, we need to copy the files URL.

 

 

We can now create a master.yaml file. In it, we will have parameters for all stacks we will refer to. For now, we will have the exact same Metadata, and Parameters sections as in the vpc.yaml file we just uploaded.

The Resources section will change. We will reference our S3 vpc.yaml via its S3 URL. We will as well set all parameters needed in the vpc stack.

Here is the Resources section. If you are unsure, everything is in the Github repository: check out tag part4.1.

 

 

Upload the vpc.yaml file to your S3 bucket and update the master stack. Always update the master stack! Not the nested stack. This will ensure Cloudformation stays in sync with changes and rollbacks.

When you update, re-use the same master stack. We did not change it. Click the “Next” buttons up to “Update Stack” and click it.

 

 

 

The master stack updates, the VPC stack updates. Click on the VPC stack and go to the Outputs tab. There is the information we can refer to in the master stack.

 

 

We know part of the information for our bastion stack is in the VPCStack, in the Outputs, and we named them ProjectXDVPCID and ProjectXPublic1.

The key pair and ssh CIDR will be added as normal parameters. To avoid confusion, we name them exactly as they are named in the bastion.yaml file. Here is our Resources section for the nested bastion stack.

 

 

Upload the bastion.yaml file to your S3 bucket and update the master stack. This time, our master stack has changed, so we need to re-upload our master.yaml file to Cloudformation.

 

 

In the Parameters, I chose my SSH CIDR (my outgoing IP address at work) and my key pair (cfntest) exactly like I did in Part 3. Next your way to the “Update Stack” button. In “Change set preview” you can see that the bastion stack is going to be added to our infrastructure.

 

 

Update the master stack.

Oh!Oh! I have a Rollback going on … Let’s keep it real. This is going to happen to you too 😉 And in my case, it says a made an error in the bastion stack where SubnetID does not have a value.

 

 

Allright, my master.yaml says.

 

 

My bastion.yaml file uses SubnetID, aaaha! I will change that in the bastion.yaml file so the propper variable is used: VPCSubnetID.

Same player, shoot again! And we have our new stack up. The bastion host is up and running.

 

 

Don’t forget you can always refer to the Github repository: check out tag part4.2.

We can add a private host now for our app: app.yml.

We will need the VPC ID for the app and the Bastion security group ID for the app’s security group. We will need a key pair (we will keep the key pair used for the bastion host) and a VPC subnet for the EC2 instance.

We know how to get the VPC ID and a subnet from the VPC stack. We get the key pair from the master Parameters in Cloudformation. We need to get the bastion security group from the bastion stack. So, we need to edit the Outputs sections.

 

 

It is left for you as an exercice to do the app.yaml file. If you are in trouble along the way, you can check out tag part4.3 in the Github repository.

Upload the modified bastion.yaml file and update the master stack.

We will need the reference to the bastion security group in the Outputs of the bastion stack before we proceed with the app stack.

 

 

Add he new app.yaml file to your S3 bucket. Update the master stack on Cloudformation with the modified master.yaml file (now containing the resource for the app stack).

 

 

Let’s test if we can log on to the bastion host and then to the private host.

 

 

 

It works as planned.

We are now at the very same stage we left off in Part 3. But we have a much better layout for the components that are making up our infrastructure.

If you encounter errors you can’t fix, you can always delete the master stack and start over: you can check out tags part4.1, part4.2 and part 4.3.

Join me in Part 5 where we will deploy an nginx into our app stack with a twist and load balance it.