Understanding DevOps and Cloud Maturity Models: A Guide to Elevating Your IT Strategy
In today’s fast-paced technological landscape, DevOps and Cloud practices are integral to accelerating software delivery and optimizing cloud resources. But as
The problem domain of secrets distribution is a common one. You have a secret, you want to distribute it to a service, and you want to implement this action in a secure way. The secret could be a password, an API key, a TLS certificate, or anything else that you want to keep secret.
Also a common problem within secrets distribution is the need to rotate secrets. This is a security best practice, and it's often required by compliance standards. Rotating secrets can be a complex process, especially when you must do it across multiple services.
And finally, you might also be aware of the problem that distributed secrets can be hard to manage. You might have secrets stored in multiple places, and it can be hard to keep track of where they are and who has access to them.
HashiCorp Vault is a secrets management tool that can help you solve these problems. Vault can store secrets, distribute them to services, and rotate them. It can also help you manage access to secrets, so you can manage access permissions effectively.
You can configure Terraform HCP or Terraform Enterprise to authenticate against HashiCorp Vault to retrieve necessary secrets without duplication of data. This way you can store your secrets in a central place and fetch them from your services in a secure way.
HashiCorp provides multiple setups to authenticate clients, e.g. AppRole as authentication if you have no other credential data available. Terraform Enterprise but also Terraform HCP can authenticate against HashiCorp Vault by the JWT authentication method. This method allows you to authenticate with Vault using a signed JWT token.
1resource "vault_jwt_auth_backend" "tfc_jwt_vault" {
2 description = "Hashicorp tfc auth backend"
3 path = "tfc_jwt_vault"
4 oidc_discovery_url = "https://app.terraform.io"
5 bound_issuer = "https://app.terraform.io"
6 default_role = "tfc_vault_config"
7}
Initially you must define a JWT auth backend and a role. The role defines the policies and claims that are required to authenticate against Vault. The role is bound to the JWT auth backend.
1resource "vault_jwt_auth_backend_role" "tfc_vault_config" {
2
3 backend = "tfc_vault_config"
4
5 role_name = "tfc_jwt_all_projects"
6 token_policies = [ "tfc_all_projects" ]
7 user_claim = "terraform_full_workspace"
8 role_type = "jwt"
9 bound_audiences = ["vault.workload.identity"]
10 bound_claims_type = "glob"
11 token_ttl = 20 * 60
12
13 bound_claims = {
14 sub = "organization:MyOrganization:project:*:workspace:*:run_phase:*"
15 }
16}
By defining the role, you can specify the policies and claims that are required to authenticate against Vault. The bound_claims
attribute specifies the claims that are required to authenticate against Vault. So, in this example the sub
claim must match the given value, otherwise the authentication will fail. In this example this role can be used over all projects in the organization MyOrganization
for all workspaces and run phases.
1resource "vault_jwt_auth_backend_role" "tfc_jwt_my_project" {
2
3 backend = "tfc_jwt_vault"
4
5 role_name = "tfc_jwt_my_project"
6 token_policies = [ "tfc_all_projects" ]
7 user_claim = "terraform_full_workspace"
8 role_type = "jwt"
9 bound_audiences = ["vault.workload.identity"]
10 bound_claims_type = "glob"
11 token_ttl = 20 * 60
12
13 bound_claims = {
14 sub = "organization:MyOrganization:project:MyProject:workspace:*:run_phase:*"
15 }
16}
If you need to restrict the access to a specific project, you can define a role for this project. In this example the role tfc_jwt_my_project
can only be used for the project MyProject
in the organization MyOrganization
, but all workspaces and run phases within this project.
When having to define an authentication against HashiCorp Vault in combination with AppRole authentication, you must find a solution to request the SecretID and pass this informaition to the client location. When using JWT based authentication you just need to define the Vault JWT auth backend and the role in your Terraform configuration. Terraform Cloud will handle the rest.
1variable "tfc_vault_dynamic_credentials" {
2 description = "Object containing Vault dynamic credentials configuration"
3 type = object({
4 default = object({
5 token_filename = string
6 address = string
7 namespace = string
8 ca_cert_file = string
9 })
10 aliases = map(object({
11 token_filename = string
12 address = string
13 namespace = string
14 ca_cert_file = string
15 }))
16 })
17}
18
19provider "vault" {
20 skip_child_token = true
21 address = var.tfc_vault_dynamic_credentials.default.address
22 namespace = var.tfc_vault_dynamic_credentials.default.namespace
23
24 auth_login_token_file {
25 filename = var.tfc_vault_dynamic_credentials.default.token_filename
26 }
27}
This block defines the Vault provider in Terraform. The skip_child_token
attribute must be set to true
as Terraform HCP manages the token lifecycle. The address
and namespace
attributes are set to the values from the tfc_vault_dynamic_credentials
variable. The auth_login_token_file
block specifies the token file that is used to authenticate against Vault. This token file is managed by Terraform HCP. On every run Terraform HCP will authenticate against Vault using the JWT token and fetch the secrets that are required for the run.
Finally you need to define following environment variables in your Terraform configuration - this might be done in the workspace settings in Terraform HCP by using Variable Sets
: TFC_VAULT_ADDR
, TFC_VAULT_AUTH_PATH
, TFC_VAULT_NAMESPACE
, TFC_VAULT_PROVIDER_AUTH
. The last variable is a boolean flag that must be set to true
to enable the Vault provider as needed in Terraform. All other variables are defined/created by the previous Terraform configuration.
Have fun trying it yourself!
You are interested in our courses or you simply have a question that needs answering? You can contact us at anytime! We will do our best to answer all your questions.
Contact us