This will be the first time I have written a tutorial directly from a suggestion in our slack channel. I haven't done suggestions up to this point as to try and make sure the channel continues in the right direction to build upon specific skills to get into DevOps.This suggestion fits perfectly with the flow of what I have been doing and I certainly hope it helps all who read (particularly the requester)!I was sent a list of requirements that an employer expected to see in a live demo. Here is the list:Automate provisioning and configuration of NGINX server in Docker container with SSL certificate in AWS cloud using Jenkins, Ansible, Terraform.Assumptions:1. The available free version of Linux2. The latest available version of NGINX for Linux3. EC2 instance size is t2.micro (free tier)4. Must create and use free tier of private AWS account5. The SSL certificate is self-signed6. The AWS Security Group is defaultAcceptance Criteria:1. Post-provisioning report demonstrates evidence ofa. No provisioning errorsb. Sequence of provisioning stepsc. Up and running instance of NGINXd. Listening on ports 80 and 443e. Response on ports 80 and 443f. content of active instance configuration file2. Run automated pipeline 3 times in a row and receive the same result (fully remove provisioned EC2 with components after every deployment, automation is optional for removal)This one was actually fun to work on. So let's try to meet each of these criteria.
Assumptions to complete this tutorial:
- You have an AWS account set up and have IAM profiles on your local.
- You have Jenkins installed and know how to basically use it
- You have Github (and CLI) with ssh keys set up.
- You have terraform installed
- You have Docker Installed
- Basic knowledge of EC2 and security groups
- A key pair already set up to utilize. In this example, mine is devops.pemOur project directory will look like this by the end:Prior to beginning, as always, setup your github repo and get ready to showcase your effort.Then inside that git repo run the following to get the proper ignore file to ignore the terraform junk:
Part 1: NGINX, OpenSSL, and the static site all bundled into DockerThe requirement listed here is for an NGINX Docker container to be deployed onto a linux EC2 host with a self signed SSL cert.For this, we can show off just a little bit and embellish the static hosted site across NGINX.Let's create a directory for our nginx, static-site, and all the required files.Let's start by adding the html and css quick. Of course, feel free to do whatever you want to this.index.htmlindex.cssNext, we can add the standard nginx config, only with some modifications (I have trimmed out the options and added the SSL server with the locations of where our certs will be in the next step):Note: you can find the basic config herenginx.confNow, save those and open up the Dockerfile one level up:Here we are taking the base and lastest Nginx image from docker and then making the dirs for our certs and copying our static files over into /etc/.Then we are running the OpenSSL command to generate a self signed cert with our information. In this case, you will get a security warning when accessing the ec2 from the browser. Go ahead and replace my information with your information in that RUN command.Dockerfilefinally in this step, we can build and push the docker image to your own docker repo:
Part 2: TerraformBefore we tackle the Terraform, make sure you have a security group set up for SSH and TCP. In the requirements they say "default", but that is usually used for VPC internal communication of services. You can decide how you want to handle security, but I've created a secondary SG with the specific requirements.
The Terraform piece is almost an exact copy from DevOps 01 so if you need a refresher, check that post out.back out in our projects root level folder, create the terraform dir and then its child static-site:main.tfNote that you have to fill in your SG id'svariables.tfAnd that is all for Terraform. EASY.
Part 3: Ansible and Dynamic InventoryIf you haven't checked out my other post and video Button Click Environment I will be relying heavily on that tutorial to save time and space.Before you forget, make sure to cp your aws credentials AND EC2 key to the jenkins user if that's the route you are going to take:We want to have ansible run and utilize a Dynamic Inventory to account for EC2 instances coming and going.For this we need the following directory/files:/etc/ansible/aws_ec2.yaml/etc/ansible/group_vars/tag_group_web.yaml/etc/ansible/ansible.cfg./ansible/static-site/site.yamlso let's start with the /etc/ folder. Recall that the boto_profile is your credential for JENKINS in this case./var/lib/jenkins/.aws/credentials/etc/ansible/aws_ec2.yaml/etc/ansible/group_vars/tag_group_web.yaml/etc/ansible/ansible.cfgand finally our ansible playbook in our directory (note the image at the end should be YOUR docker image:./ansible/static-site/site.yamlAnd that's all for Ansible.
Part 4: Jenkins PipelineNow for the grand finale, the Jenkins Pipeline.For the jenkins piece, we will be running jenkins locally and pulling from Git. So push it all up there now.Fire up jenkins and log in.Create a new job and select "Pipeline" (call it something intuitive)Now, I have a Jenkinsfile in my repo that is arbitrary. I keep it there to show off, as well as make edits easily when I need to. We are ultimately going to past it into Jenkins, so its up to you if you want to include it or not.Take a moment to review it. Note the following:
- It has params at the top
- it checks my repo using Jenkins credentials that I supplied in my instance. These are SSH credentials (private key is in jenkins, public key is in Github). I have covered this in other videos.
- The Terraform stage has an if/else statement for apply or destroy
- Ansible has a retry block in case the connection doesn't work on first try (to avoid the error penalty). Also, note that it uses the -i to reference our Dynamic inventory.JenkinsfileScroll down to the bottom where it says "Pipeline" and paste in the Jenkinsfile script. Save it and reload.Try Building it with parameters and see how it goes!You should be able to see each stage complete:
When you are done standing it up you can navigate to your EC2 url and verify it works.You should see the ssl warning when using https
You can verify your SSL info as well by clicking the "Not Secure" at the top left.Click through it and see your static site:
When you are done, You can head back to Jenkins, select "Destroy" and run it! Your verify your instance is terminated and run it for them as many times as they want!That concludes this tutorial. I hope you have enjoyed it!
Disclosure: scottyfullstack.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com.