Terraform#
The Terraform provider treats the release in service of an application as a resource. terraform plan shows when the version in an environment differs from the configured one, or when targets were changed outside manent; terraform apply releases it through manent, with all its rules. A data source checks a candidate environment configuration and fails the plan before another resource writes it to Consul.
What you need
Terraform 1.x · Go, to build the provider until it is published in the registry · a manent token for the identity that runs Terraform
1. Build and install the provider#
The provider is a separate Go module in integrations/terraform:
make terraform-provider # bin/terraform-provider-manent
sudo install -d /opt/terraform/providers
sudo install bin/terraform-provider-manent /opt/terraform/providers/
Until it is in the registry, point Terraform at it with dev_overrides in the CLI configuration:
provider_installation {
dev_overrides { "manent-deployer/manent" = "/opt/terraform/providers" }
direct {}
}
Terraform then prints a warning that the provider is overridden by a local build: that is expected.
2. Configure it#
terraform {
required_providers {
manent = { source = "manent-deployer/manent" }
}
}
provider "manent" {} # MANENT_SERVER and MANENT_TOKEN, or server, token, token_file, ca_file
The identity of the token needs deployment.read to plan, and deployment.submit on the environments it releases to.
3. The release in service as a resource#
variable "shop_version" { type = string }
resource "manent_deployment" "shop_prod" {
application = "shop"
environment = "prod"
descriptor = file("${path.module}/deploy/prod.yml")
version = var.shop_version
source = "https://nexus.example.com/repository/releases/shop/shop-${var.shop_version}.tgz"
timeout = "30m"
redeploy_out_of_sync = true
}
| Situation | Plan |
|---|---|
| Nothing changed | No changes. |
shop_version changed |
version: "1.3.2" -> "1.4.0": apply runs a deploy and waits for it, approvals included, up to timeout. |
| Someone released or rolled back another version outside Terraform | The difference read from the inventory; apply releases the configured one again. |
Targets changed outside manent (with reconciliation and redeploy_out_of_sync) |
"1.4.0 (targets out of sync)" -> "1.4.0": apply releases it again. |
- A failed deploy fails the apply. With automatic rollback the environment is back on the previous version, and the next plan tries again.
terraform destroydoes not touch the targets: manent does not uninstall releases, the resource just leaves the state.- An existing environment is imported with
terraform import manent_deployment.shop_prod shop/prod(payments/shop/prodfor the application of a tenant). Thetenantattribute chooses among the tenants that list the application, required only when more than one does. - The
manent_tenantsdata source lists the tenants with their applications, for example to drive afor_eachover the applications of a team.
4. Gate configuration changes in the plan#
When Terraform also writes the environment configuration to Consul, let manent check it first:
locals {
shop_prod_config = file("${path.module}/envconfig/shop/shop/prod.yml")
}
data "manent_environment_check" "shop_prod" {
application = "shop"
environment = "prod"
config = local.shop_prod_config
}
resource "consul_keys" "shop_prod" {
key {
path = "manent/shop/shop/prod"
value = data.manent_environment_check.shop_prod.valid ? local.shop_prod_config : null
}
}
An invalid configuration (a merge conflict, a forbidden parameter, a wave that selects no target, an unknown plugin parameter) fails the plan with manent's error, before Consul is touched. The data source also returns plugin, targets, stages and warnings, useful in outputs or in policy checks.
5. Read the inventory#
data "manent_inventory" "prod" { environment = "prod" }
output "prod_versions" {
value = { for e in data.manent_inventory.prod.entries : e.application => e.version }
}
What stays out of Terraform#
Permissions and YAML governance rules live in manent.yml; Rego policies and runtime freezes are managed with manent policy and manent freeze. The environment configuration stays in its system: the provider checks it, consul_keys (or your repository) writes it.
Reference: CI and infrastructure as code.