A Docker image that contains terraform and ansible that can be used for CI runners

Docker Terraform Ansible

A Docker image that contains terraform and ansible that can be used for CI runners with support for Terraform Inventories


Sample usage for Gitlab, let's use this .gitlab-ci.yml as a reference

image: alexecus/docker-terransible

  - create
  - provision

  stage: create
  when: manual
    - terraform init
    - terraform apply -auto-approve

  stage: dev
  when: manual
    - terraform init
    - terraform state pull > terraform.tfstate
    - ansible-playbook --inventory-file=$(which terraform-inventory) playbook.yml
    - rm terraform.tfstate

Important tip Terraform manages a server by maintaining a state file named terraform.tfstate. It is recommended to use remote state management, wherein the state file is stored in a remote location. Terraform natively supports this and you can read more about it on the documentation here.

Why do we need terraform's remote state management ?

If you run terraform on pipelines, each run would create a terraform state file if it does not exist. One drawback of terraform is that the state file should always be in-synced with the server changes it do. Tracking those changes are written within the state file. Not having a synced state file and server state would incur errors whenever terraform performs an action on a server. The best solution is to have each pipeline job execution refer to a single state file all the time.

What does terraform-inventory do ?

Terraform inventory is a script that extracts an ansible inventory file out of a terraform state file. Until terraform supports ansible provisioner natively, this approach I believe is a better alternative.

Why do we need to pull the state file before running ansible ?

If you will assign static IPs to your server, you can omit this step and specify an inventory file with your server's IP instead. However, this approach is much more flexible, a terraform state file would contain all information about the server, including the server's IP address. With this approach, no need to manually manage how ansible would connect to your servers, just give it the terraform state file.