Aller au contenu

Terraform

Basics

Terraform is an infrastructure as Code tool: provision, change and version infrastructure. It differs from Chef/Ansible because: agentless, declarative syntax, immutable principle. It uses HCL (Hashicorp Configuration language)

Concepts

Provider: collection of multiple resource types, using Saas / cloud api

Resource type: any unit of infrastructure which can be provisioned.

  • Resource block: An instance of a resource. Instance id is <type>_<name>

Modules: reusable code organization unit (1 root -> multiple children). Like a function. Any tf file in a directory is a module. Resources in a module A are invisible to module B (default scope).

  • Variables: can be injected in modules. Like function parameters. Can have validation rules & error messages. Can be sensitive (hidden in the plan/apply output)
  • Outputs: returned by modules. Outputs are also used to expose info from other modules.

State: tfstate file. Always cleartext even sensitive values..

Workspace: formerly "environment". Confers tfstate isolation (ex: dev / prod environments or the equivalent of feature branch, depending on the chosen abstraction). They are meant to be shared

Commands:

  • terraform init: creates the project + downloads providers
  • terraform plan: dry-run
  • terraform validate: syntax
  • terraform apply: provision infrastructure, creates tfstate in same directory, display outputs

Securing secrets

Source: Gruntwork - Managing Secrets in Terraform

2 things must be secured AND shared: the secrets and the tfstate. Don't forget that in real life conditions, there are secrets and tfstate for every environment (dev, prod...)

Method 1: Environment variables + remote encrypted tfstate

                      │
           keepass    │  ┌──────────────────────────┐
           etc.       │  │     .env file            │
         git ignored! │  └───────────┬──────────────┘
                                     │
                      │  ┌───────────▼──────────────┐
                      │  │     variables.tf         │
                      │  │                          │
                      │  └─────┬──────────────┬─────┘
                      │        │              │
                      │  ┌─────▼─────┬────────▼─────┐
             Git      │  │           │              │
                      │  │ module 1  │  module 2    │
                      │  │           │              │
                      │  ├───────────┴──────────────┤
                         │     terraform CLI        │
                         └────────┬─────────────────┘
                                  │
                                ┌─┼─┐
                                │ │ │
                         TLS    │ │ │
                                │ │ │
                                └─┼─┘
                                  │
                      │  ┌────────┴───────────┐
    encrypted         │  │                    │
remote tftate backend │  │   tfstate          │
   - S3               │  │   (cleartext)      │
   - Azure Blob       │  │                    │
                      │  └────────────────────┘
                      │

Method 2: secrets manager + remote encrypted tfstate

                      │  ┌─────────────┐
        secret        │  │             │
        manager       │  │  secrets    │
         - Vault      │  └──────────┬──┘
                                    │
                                    │  data source
                                    │
                      │  ┌──────────▼───────────────┐
                      │  │     variables.tf         │
                      │  │                          │
                      │  └─────┬──────────────┬─────┘
                      │        │              │
                      │  ┌─────▼─────┬────────▼─────┐
             Git      │  │           │              │
                      │  │ module 1  │  module 2    │
                      │  │           │              │
                      │  ├───────────┴──────────────┤
                         │     terraform CLI        │
                         └────────┬─────────────────┘
                                  │
                                ┌─┼─┐
                                │ │ │
                         TLS    │ │ │
                                │ │ │
                                └─┼─┘
                                  │
                      │  ┌────────┴───────────┐
    encrypted         │  │                    │
remote tftate backend │  │   tfstate          │
   - S3               │  │   (cleartext)      │
   - Azure Blob       │  │                    │
                      │  └────────────────────┘
                      │

There is a 3rd method, where each user must encrypt/decrypt secrets, only the encryption key is stored in a key manager. But it's cumbersome and requires advances users.