A demo project for deploying terraform to instances using ansible terraform module
It supports deploying to multiple environments, based on parameters passed in through jenkins.
We wish to apply terraform configurations to a bunch of remote instances using ansible. This is required to be handle continuously using the Jenkins CI platform.
- live: Holds entrypoint tf configurations for each target environment.
- terraform: Holds the terraform configurations for our remote instances
- terraform-infra: Holds infrastructure terraform code, to deploy our infrastructure, i.e. the jenkins server as well as our target servers.
- ansible_hosts: Holds our target server hosts, segregated by environment (dev, prod etc)
- ansible-pre.yml: An ansible playbook to prepare our target instance with dependencies of our terraform providers. e.g. install docker in instance if we need to deploy docker containers in remote
- ansible.yml: A playbook to handle terraform deployment to remote hosts.
- Jenkinsfile: Jenkins pipeline configuration, used by jenkins to fufil our goal.
- AWS account with credentials stored in
./aws/credentials
. Pass in a profile via theaws_creds_profile
terraform var, defaults toansible-terraform
. - This account must contain all defualt VPC configurations like defualt security group, subnets etc. Pass in the region in as
aws_region
terraform var. - Terraform to deploy base infrastructure
- Anisble for installing docker and other needed tools within the target servers.
-
Deploy basic infrastructure in aws
cd terraform-infra terraform init terraform plan
Apply the infrastructure
terraform apply
-
Populate the
ansible_hosts
file and commit- Fetch Ips of the targets from aws console
- Place them in the
ansible_hosts
file, those terminating withdev
under thedev
host group and theprod
in prod host group - Push your changes to the repository
-
Configure Jenkins server
- Goto to aws console, get the connection command to ssh into jenkins-server
- Follow from https://www.digitalocean.com/community/tutorials/how-to-install-jenkins-on-ubuntu-20-04#step-4-%E2%80%94-setting-up-jenkins
- Configure a
Github Server
inConfigure System
(Use a Personal Access Token as credentials)- Follow from https://plugins.jenkins.io/github/
- Make sure to check
Manage Hooks
- Install the ansible plugin at Jenkins
- Configure ansible at
Global Tools Config
- Name:
ansible
- Path:
/usr/bin
- Name:
- Add the private keys to the target instances, which ansible will use to connect in jenkins credentials
- Use the content of the
ec2-terra-ansi.pem
created while deploying infrastructure - username should be
ubuntu
- The Id of the credentials should be
ubuntu-ssh
- Use the content of the
- Add a multibranch project to this repository
- Make sure to add a branch source pointing to this repository
This repository after configuration will automatically carry out the changes in the terraform
dir on the remote instances using ansible.
Basically just pushing changes to this repository should redeploy your terraform code. It will pause after a plan and you can acknowledge to continue or stop.
The terraform
and live
dir are copied to the remotes before execution, so you can use it to place backend_config_files, terraform_tvars_files for later referencing.
The stages included in the Jenkins pipeline are;
- test - Will carry out terraform validate on your configutions
- pre - run an ansible prepare playbook to deploy to the target instances terraform dependencies
- plan - Will run a plan of your terraform configuration and print the output for validations. (Check the console output for full log)
- approval - Will pause the pipeline and wait for approval before continueing to execute the. You make choose to cancel.
- apply - If approved, will apply the change in the terraform
- You can pass in variables to terraform by passing in the ansible
terraform_tvars
variable, it could be a json (map). - You can also pass in a location to the variables file through
terraform_tvars_files
.
Example
- Passing in
extra-vars
as"terraform_tvars": { "nginx_container_name": "nginx-changed" }
will change the nginx container name in the remote instances. - For the case with a .tvars file for any environment, run terraform with the following
extra-vars
parameter"terraform_tvars_files": "../relative/path/to.tvars"
Deploying to different environments is virtually simple.
- Add the hosts for that environment (e.g. qa) under a
qa
host group inansible_hosts
file - Add a dir, inside of
live
dir with the name of the env, and import the terraform module (see live/dev example) - Add the environment slug as a choice to the
env
parameter in the Jenkinsfile - Commit your code and push
- At Jenkins, go to run with parameters, select
qa
asenv
and then run. - Make sure to other provide the required inputs
- Place your backend files into the
terraform/
dir and commit - You can indicate the terraform backend files by passing in the var
backend_config_files
To destroy existing state, run the the pipeline with the following parameters extra_vars
"state": "absent"