Skip to content

Commit

Permalink
add hcp dynamic credentials example
Browse files Browse the repository at this point in the history
  • Loading branch information
SwiftEngineer committed May 20, 2024
1 parent e9217ac commit 6ac3e3e
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 1 deletion.
2 changes: 1 addition & 1 deletion hcp/hcp.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ data "hcp_project" "hcp_project" {
#
# https://registry.terraform.io/providers/hashicorp/hcp/latest/docs/resources/service_principal
resource "hcp_service_principal" "workload_sp" {
name = "terraform-cloud"
name = "hcp-terraform"
parent = data.hcp_project.hcp_project.resource_name
}

Expand Down
22 changes: 22 additions & 0 deletions hcp/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/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/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/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/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"
}

0 comments on commit 6ac3e3e

Please sign in to comment.