Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform provides many features including:
- Infrastructure as Code: High-level syntax (HCL), change management
- Execution Plan: Plan and predict changes
- Resource Graph: Parallel and serial execution
- Change Automation: Complex changeset, clone deployments
Terraform saves the infrastructure deployment state in terraform state files. Save the terraform state files in remote backend, such as S3.
- Remote state is protected with locks that prevent corruption
- Stored only in memory; sensitive information is kept on backend
Keep the terraform code for various environments (dev, stage, prod) common, and separate environment specific variables in var files.
- Reduces amount of code duplication
- Store all variables in a .tfvars file (eg. stage.tfvars, prod.tfvars)
- Load env variables at runtime
Once resources have been created in remote state, it can be referenced from other depoyments using remote backend or data-sources.
Terraform has formatting and validation options.
terraform validate
- validates syntax on terraform files in the directory
terraform fmt
- rewrites terraform files in proper format/style
tflint
can be used to validate provider specific issues
Add appropriate tags to track your deployment assets. Create a convention to tag the asset, such as
environment
, application
, owner-name
, owner-email
Package infrastructure code into reusable and composable modules.
Its always easier to manage smaller de-coupled deployments, instead of a big deployment with different kinds of resources.
Always review the plan with team, before applying the infrastructure changes.
Terraform Module are re-usable and composible blueprint for your infrastructure solutions.
- Architecture and Solution abstraction: Apps and Database
- Reusable library for Infrastructure
- Compose modules to build end-to-end stack
- Lots of open-source on Terraform registry
Following are some of the best practices to create good terraform modules:
- Create meaningful abstractions
- Recommended module repo name:
terraform-<provider>-<name>
- Follow standard module structure
- Semantically version (x.y.z) modules: git tags
- Include usage examples
- Good README