Skip to content

add hcp dynamic credentials example #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions hcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Bootstrapping trust between a TFC workspace and HCP

This directory contains example code for setting up a Terraform Cloud workspace whose runs will be automatically authenticated to HCP using Workload Identity.

The basic building blocks in `hcp.tf` will configure a workload identity pool and provider and create a service principle that is bound to a particular Terraform Cloud workspace.

The building blocks in `tfc-workspace.tf` will create that Terraform Cloud workspace and set all the configuration variables needed in order to allow runs to authenticate to HCP.

## How to use

You'll need the Terraform CLI installed, and you'll need to set the following environment variables in your local shell:

1. `TFE_TOKEN`: a Terraform Cloud user token with permission to create workspaces within your organization
2. `HCP_CLIENT_ID`: ID of the service principal to configure HCP with, requires `roles/admin` on the organization
3. `HCP_CLIENT_SECRET`: Corresponding secret to the provided HCP client ID
4. `HCP_PROJECT_ID`: ID of the HCP project to create the new service principal that Terraform Cloud will be able to assume during runs

Copy `terraform.tfvars.example` to `terraform.tfvars` and customize the required variables. You can also set values for any other variables you'd like to customize beyond the default.

Run `terraform plan` to verify your setup, and then run `terraform apply`.

Congratulations! You now have a Terraform Cloud workspace where runs will automatically authenticate to HCP when using the HCP provider.
47 changes: 47 additions & 0 deletions hcp/hcp.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

provider "hcp" {}

# Project data resource that is used to fetch information about the current HCP project
#
# https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/data-sources/project
data "hcp_project" "hcp_project" {
}

# The service principal resource manages a HCP Service Principal.
#
# https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/resources/service_principal
resource "hcp_service_principal" "workload_sp" {
name = "hcp-terraform"
parent = data.hcp_project.hcp_project.resource_name
}

# Grants the service principal the ability to provision and destroy resources in HCP
#
# https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/resources/project_iam_binding
resource "hcp_project_iam_binding" "workload_sp_binding" {
project_id = data.hcp_project.hcp_project.resource_id
principal_id = hcp_service_principal.workload_sp.resource_id
role = "roles/contributor"
}

locals {
sub_regex = "^organization:${var.organization_name}:project:${var.tfc_project_name}:workspace:${var.tfc_workspace_name}:run_phase:.*"
}

# The workload identity provider resource allows federating an external identity to an HCP Service Principal.
#
# https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/resources/iam_workload_identity_provider
resource "hcp_iam_workload_identity_provider" "tfc" {
name = "hcp-terraform-provider"
service_principal = hcp_service_principal.workload_sp.resource_name
description = "Allow HCP Terraform agents to act as the ${hcp_service_principal.workload_sp.name} service principal"

oidc = {
issuer_uri = "https://${var.tfc_hostname}"
allowed_audiences = [var.tfc_hcp_audience]
}

conditional_access = "jwt_claims.sub matches `${local.sub_regex}`"
}
2 changes: 2 additions & 0 deletions hcp/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tfc_organization_name = "my-organization"
tfc_project_name = "my project"
61 changes: 61 additions & 0 deletions hcp/tfc-workspace.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

provider "tfe" {
hostname = var.tfc_hostname
}

# Data source used to grab the project under which a workspace will be created.
#
# https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/project
data "tfe_project" "tfc_project" {
name = var.tfc_project_name
organization = var.organization_name
}

# Runs in this workspace will be automatically authenticated
# to HCP with the permissions set in the HCP policy.
#
# https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/workspace
resource "tfe_workspace" "my_workspace" {
name = var.tfc_workspace_name
organization = var.organization_name
project_id = data.tfe_project.tfc_project.id
}

# The following variables must be set to allow runs
# to authenticate to HCP.
#
# https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable
resource "tfe_variable" "enable_hcp_provider_auth" {
workspace_id = tfe_workspace.my_workspace.id

key = "TFC_HCP_PROVIDER_AUTH"
value = "true"
category = "env"

description = "Enable the Workload Identity integration for HCP."
}

# The resource name of the provider for which the external identity
# will be exchanged against using the credential file.
resource "tfe_variable" "tfc_hcp_provider_resource_name" {
workspace_id = tfe_workspace.my_workspace.id

key = "TFC_HCP_RUN_PROVIDER_RESOURCE_NAME"
value = hcp_iam_workload_identity_provider.tfc.resource_name
category = "env"

description = "The resource name of the provider for which the external identity will be exchanged against using the credential file."
}

# The value to use as the `aud` claim in run identity tokens
resource "tfe_variable" "tfc_hcp_audience" {
workspace_id = tfe_workspace.my_workspace.id

key = "TFC_HCP_WORKLOAD_IDENTITY_AUDIENCE"
value = var.tfc_hcp_audience
category = "env"

description = "The value to use as the audience claim in run identity tokens"
}
31 changes: 31 additions & 0 deletions hcp/vars.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "tfc_hcp_audience" {
type = string
default = "hcp.workload.identity"
description = "The audience value to use in run identity tokens if the default audience value is not desired."
}

variable "tfc_hostname" {
type = string
default = "app.terraform.io"
description = "The hostname of the TFC or TFE instance you'd like to use with HCP"
}

variable "organization_name" {
type = string
description = "The name of your Terraform Cloud organization"
}

variable "tfc_project_name" {
type = string
default = "Default Project"
description = "The project under which a workspace will be created"
}

variable "tfc_workspace_name" {
type = string
default = "my-hcp-workspace"
description = "The name of the workspace that you'd like to create and connect to HCP"
}