Terraform Playbook: Team Practices, Integration with Ansible, and Maintainable Code Standards

Terraform playbooks are not a single product. In practice the term covers two overlapping ideas: a documented set of team practices for writing and operating Terraform safely, and the operational pattern of combining Terraform with configuration management such as Ansible to turn provisioned infrastructure into usable systems. The reference material shows both angles, from dxw’s maintainable Terraform Code Playbook to a practical team playbook for keeping Terraform boring and predictable, and to a concrete tutorial coupling Terraform Droplet creation with Ansible bootstrapping.

Introduction

Terraform projects often start quickly and become difficult to review as they grow. Teams that treat Terraform as shared, long-lived infrastructure code rather than magic produce small changes, reviewed plans, protected state, and an obvious blast radius before apply. The same teams standardise module patterns, naming, backend config, and pipeline steps so new contributors can ship infrastructure changes without decoding tribal lore. When Terraform is forced to act as a general-purpose orchestration tool for runbooks, data migrations, or application deploys, it becomes cranky.

A second practical need is making provisioned resources usable immediately. Terraform creates infrastructure, often blank by default. Ansible executes playbooks written in YAML to bootstrap servers, install software, create users, and configure services. Running Ansible directly after Terraform provisioning makes resources usable faster and creates repeatable configuration across the fleet.

The dxw Terraform Code Playbook as a reference

dxw’s Terraform Code Playbook is described as a reference for creating maintainable Terraform projects and modules. The documentation is published at terraform-code-playbook.dxw.com and is dxw’s reference for creating maintainable Terraform projects and modules.

The playbook repository supports local development and preview:

  • Run the setup command. This installs the dependencies required for running the project.
    script/setup
  • To just update dependencies, you can run the bootstrap command, though this currently does the same as script/setup due to the small number of dependencies required:
    script/bootstrap
  • To run the server, from the root directory, run:
    script/server
    This runs the server on localhost:4000.

  • To proof the HTML for things like dead links, run:
    bundle exec jekyll build bundle exec htmlproofer _site

The contents of dxw’s Terraform Code Playbook is released under a Creative Commons Attribution-NonCommercial licence. You are free to reuse and adapt this content with credit, for non-commercial purposes.

The This Playbook section provides information on how to make changes to this documentation.

Team playbook for Terraform without tears

Terraform Without Tears: Our Practical Team Playbook frames the operational mindset.

We’ve all seen it: one heroic engineer writes a handful of terraform files, applies on a Friday afternoon, and suddenly the entire team is living in a suspense thriller. The fix isn’t more heroics—it’s treating terraform like what it really is: shared, long-lived infrastructure code that needs the same care as application code.

Baseline mindset is simple: terraform should be predictable. That means changes are small, plans are reviewed, state is protected, and the blast radius is obvious before we type apply.

The team aims for boring repeatability: if two people run the same workflow, they should get the same result. When terraform is “surprising,” it’s almost always because of weak structure, such as everything in one place, weak process such as no plan review, or weak guardrails such as state stored who-knows-where.

The learning curve is kept kind. Terraform has enough sharp edges without home-grown weirdness. So the team standardises: consistent module patterns, consistent naming, consistent backend config, and a consistent pipeline. That consistency lets new folks ship infra changes without needing to decode tribal lore.

Finally, the playbook accepts that terraform is not a general-purpose orchestration tool. When it is forced to do runbooks, data migrations, or app deploys, it gets cranky—and so do we.

Terraform and Ansible integration pattern

Ansible is a configuration management tool that executes playbooks, which are lists of customizable actions written in YAML on specified target servers. It can perform all bootstrapping operations, like installing and updating software, creating and removing users, and configuring system services. As such, it is suitable for bringing up servers you deploy using Terraform, which are created blank by default.

Ansible and Terraform are not competing solutions, because they resolve different phases of infrastructure and software deployment. Terraform allows you to define and create the infrastructure of your system, encompassing the hardware that your applications will run on. Conversely, Ansible configures and deploys software by executing its playbooks on the provided server instances. Running Ansible on the resources Terraform provisioned directly after their creation allows you to make the resources usable for your use case much faster. It also enables easier maintenance and troubleshooting, because all deployed servers will have the same actions applied to them.

A tutorial example deploys Droplets using Terraform, and then immediately after their creation, bootstraps the Droplets using Ansible. Ansible is invoked directly from Terraform when a resource deploys.

Ansible playbook for initial server setup

You’ll now create an Ansible playbook that performs the initial server setup tasks, such as creating a new user and upgrading the installed packages. You’ll instruct Ansible on what to do by writing tasks, which are units of action that are executed on target hosts. Tasks can use built-in functions, or specify custom commands to be run. Besides the tasks for the initial setup, you’ll also install the Apache web server and enable its mod_rewrite module.

Before writing the playbook, ensure that your public and private SSH keys, which correspond to the one in your DigitalOcean account, are available and accessible on the machine from which you’re running Terraform and Ansible. A typical location for storing them on Linux would be ~/.ssh, although you can store them in other places.

Note: On Linux, you’ll need to ensure that the private key file has appropriate permissions.

The playbook is saved and closed. You’ll now modify the Droplet deployment code to execute this playbook when the Droplets have finished provisioning.

Provisioners in Terraform

Terraform offers two provisioners that execute commands: local-exec and remote-exec, which run commands locally or remotely respectively.

  • remote-exec requires connection data, such as type and access keys, while local-exec does everything on the machine Terraform is executing on, and so does not require connection information.

It’s important to note that local-exec runs immediately after the resource you have defined it for has finished provisioning; therefore, it does not wait for the resource to actually boot up. It runs after the cloud platform acknowledges its presence in the system.

You’ll now add provisioner definitions to your Droplet to run Ansible after deployment.

Verification and teardown

You will reach the default Apache welcome page, signifying the successful installation of the web server. This means that Terraform provisioned your servers and your Ansible playbook executed on it successfully.

To check that the SSH key was correctly added to sammy on the provisioned Droplets, connect to one of them with the following command:

  • ssh -i privatekeylocation sammy@dropletipaddress

Remember to put in the private key location and the IP address of one of the provisioned Droplets, which you can find in your Terraform output.

The output will look similar to the following:

OutputWelcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-121-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of ... System load: 0.0 Processes: 88 Usage of /: 6.4% of 24.06GB Users logged in: 0 Memory usage: 20% IP address for eth0: ip_address Swap usage: 0% IP address for eth1: ip_address 0 packages can be updated. 0 updates are security updates. New release '20.04.1 LTS' available. Run 'do-release-upgrade' to upgrade to it. *** System restart required *** Last login: ... ...

You’ve successfully connected to the target and obtained shell access for the sammy user, which confirms that the SSH key was correctly configured for that user.

You can destroy the deployed Droplets by running the following command, entering yes when prompted:

  • terraform destroy -var "dotoken=${DOPAT}"

Comparative view of playbook approaches

The material covers documentation playbooks, team process playbooks, and operational integration playbooks.

Playbook Type Focus Key Artifact
dxw Terraform Code Playbook Maintainable project and module structure Reference documentation, Jekyll site
Team Practical Playbook Process and guardrails for safe reviews Small changes, plan review, protected state
Terraform + Ansible Integration Provision then configure Terraform provisioners, Ansible YAML playbooks

Provisioner characteristics

Provisioner Execution Location Requires Connection Data Timing Note
local-exec Locally on Terraform machine No Runs immediately after resource provisioning, does not wait for boot
remote-exec Remotely on target Yes Requires connection data such as type and access keys

Typical commands from the references

  • script/setup - installs dependencies for the playbook site
  • script/bootstrap - updates dependencies
  • script/server - runs server on localhost:4000
  • bundle exec jekyll build - builds HTML
  • bundle exec htmlproofer _site - checks dead links
  • terraform destroy -var "do_token=${DO_PAT}" - destroys deployed Droplets

Ecosystem guidance and learning paths

The platform engineering playbook lists specialized guides and tools relevant to Terraform practice:

Specialized Guides

  • Terraform Best Practices - Community-driven recommendations
  • Google Cloud Terraform Guide - GCP-specific patterns (2024)
  • AWS Provider Best Practices - AWS tagging and organization
  • Terraform Module Patterns - Reusable module design
  • Gruntwork Production Guide - Enterprise patterns

Video Tutorials

  • Complete Terraform Course - TechWorld with Nana (2.5 hours)
  • Terraform in 100 Seconds - Fireship quick intro
  • HashiCorp Terraform Tutorials - Official series
  • Terraform for AWS - freeCodeCamp course (2 hours)

Professional Courses

  • HashiCorp Certified: Terraform Associate - Official certification
  • Terraform Cloud Engineer - Free HashiCorp tutorials
  • Infrastructure Automation - Google Cloud course (Free audit)
  • Terraform Deep Dive - Advanced Pluralsight course (Paid)

Books

  • "Terraform: Up & Running" by Yevgeniy Brikman - Purchase on O'Reilly | Amazon
  • "Infrastructure as Code" by Kief Morris - Purchase on O'Reilly
  • "Terraform in Action" by Scott Winkler - Purchase on Manning

Interactive Tools

  • HashiCorp Learn - Official interactive tutorials
  • Terraform Play - Browser-based labs
  • Killercoda Terraform - Free hands-on scenarios
  • Terraform Visual - Visualize infrastructure graphs

Ecosystem Tools

  • OpenTofu - 23.2k⭐ Open source Terraform fork
  • Terragrunt - 8.1k⭐ Keep configurations DRY
  • Atlantis - 7.8k⭐ Terraform pull request automation
  • tfsec - 6.7k⭐ Security scanner for Terraform

Community & Support

  • HashiCorp Discuss

Conclusion

A Terraform playbook is a combination of documented standards, team process, and integration patterns. The dxw Terraform Code Playbook provides a concrete, reusable reference for creating maintainable Terraform projects and modules with a documented setup workflow and Creative Commons Attribution-NonCommercial licensing. The practical team playbook adds the human layer: treat Terraform as shared infrastructure code, keep changes small, review plans, protect state, make blast radius obvious, and standardise module patterns, naming, backend config, and pipeline so repeatability is boring and onboarding is kind.

Operationally, Terraform and Ansible complement each other. Terraform defines and creates infrastructure; Ansible configures and deploys software via YAML playbooks that can create users, upgrade packages, and install services like Apache with mod_rewrite. Provisioners bridge the two, with local-exec running commands on the machine executing Terraform immediately after provisioning is acknowledged, and remote-exec running commands on the target when connection data is supplied. The tutorial workflow demonstrates SSH key preparation in ~/.ssh with appropriate permissions, verification via SSH to sammy on the provisioned Droplet, and safe teardown with terraform destroy.

Together these references form a complete playbook for keeping Terraform predictable, reviewable, and paired with configuration management to make infrastructure usable from the first apply.

Sources

  1. https://github.com/dxw/terraform-code-playbook
  2. https://devopsoasis.blog/terraform-without-tears-our-practical-team-playbook/
  3. https://www.digitalocean.com/community/tutorials/how-to-use-ansible-with-terraform-for-configuration-management
  4. https://platformengineeringplaybook.com/technical/terraform/

Related Posts