Skip to content
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

Initial commit #1

Merged
merged 2 commits into from
Sep 9, 2022
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ jobs:
ci:
uses: SPHTech-Platform/reusable-workflows/.github/workflows/terraform.yaml@main
with:
upload_sarif: false
upload_sarif: true
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
# Terraform Modules Template
# TFC Workload Identity for AWS

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.0 |
| <a name="provider_tls"></a> [tls](#provider\_tls) | n/a |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_tfc_workload_identity_role"></a> [tfc\_workload\_identity\_role](#module\_tfc\_workload\_identity\_role) | terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc | ~> 5.3.0 |

## Resources

| Name | Type |
|------|------|
| [aws_iam_openid_connect_provider.tfc_provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_openid_connect_provider) | resource |
| [tls_certificate.tfc_certificate](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/data-sources/certificate) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_create_tfc_oidc_provider"></a> [create\_tfc\_oidc\_provider](#input\_create\_tfc\_oidc\_provider) | Create TFC OIDC Provider. Only one can exist in an account | `bool` | `true` | no |
| <a name="input_create_tfc_workload_identity_role"></a> [create\_tfc\_workload\_identity\_role](#input\_create\_tfc\_workload\_identity\_role) | Create IAM Role for TFC Workload Identity | `bool` | `true` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | List of tags for resources | `map(string)` | `{}` | no |
| <a name="input_tfc_oidc_provider_audiences"></a> [tfc\_oidc\_provider\_audiences](#input\_tfc\_oidc\_provider\_audiences) | List of TFC OIDC Provider audiences. This is part of the security configuration between TFC and your AWS account | `list(string)` | `[]` | no |
| <a name="input_tfc_workload_identity_role"></a> [tfc\_workload\_identity\_role](#input\_tfc\_workload\_identity\_role) | Name of the IAM Role for TFC | `string` | `"TfcWorkloadIdentity"` | no |
| <a name="input_tfc_workload_identity_role_audiences"></a> [tfc\_workload\_identity\_role\_audiences](#input\_tfc\_workload\_identity\_role\_audiences) | List of allowed audiences for the IAM Role. Defaults to the one for the OIDC provider if unspecified. | `list(string)` | `[]` | no |
| <a name="input_tfc_workload_identity_role_description"></a> [tfc\_workload\_identity\_role\_description](#input\_tfc\_workload\_identity\_role\_description) | Description of the IAM Role for TFC | `string` | `"Terraform Cloud Workload Identity"` | no |
| <a name="input_tfc_workload_identity_role_max_session_duration"></a> [tfc\_workload\_identity\_role\_max\_session\_duration](#input\_tfc\_workload\_identity\_role\_max\_session\_duration) | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `3600` | no |
| <a name="input_tfc_workload_identity_role_permissions_boundary_arn"></a> [tfc\_workload\_identity\_role\_permissions\_boundary\_arn](#input\_tfc\_workload\_identity\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for IAM role for TFC | `string` | `""` | no |
| <a name="input_tfc_workload_identity_role_policy_arns"></a> [tfc\_workload\_identity\_role\_policy\_arns](#input\_tfc\_workload\_identity\_role\_policy\_arns) | List of ARN to attach the IAM Role for TFC | `list(string)` | `[]` | no |
| <a name="input_tfc_workload_identity_workspaces"></a> [tfc\_workload\_identity\_workspaces](#input\_tfc\_workload\_identity\_workspaces) | Workspaces to allow access to the workload identity for this account | `map(list(string))` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_tfc_workload_identity_audience"></a> [tfc\_workload\_identity\_audience](#output\_tfc\_workload\_identity\_audience) | Audience value for TFC workload identity |
| <a name="output_tfc_workload_identity_role_arn"></a> [tfc\_workload\_identity\_role\_arn](#output\_tfc\_workload\_identity\_role\_arn) | IAM Role ARN for TFC Workload Identity |
| <a name="output_tfc_workload_identity_workspaces"></a> [tfc\_workload\_identity\_workspaces](#output\_tfc\_workload\_identity\_workspaces) | Workspaces allowed to assume the Workload Identity IAM Role |
<!-- END_TF_DOCS -->
21 changes: 21 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
locals {
tfc_workload_identity_workspaces_exact = flatten([
for org, workspaces in var.tfc_workload_identity_workspaces : [
for workspace in workspaces : [
"organization:${org}:workspace:${workspace}:run_phase:plan",
"organization:${org}:workspace:${workspace}:run_phase:apply",
] if !can(regex("\\*+", workspace))
]
])
tfc_workload_identity_workspaces_wildcard = flatten([
for org, workspaces in var.tfc_workload_identity_workspaces : [
for workspace in workspaces : "organization:${org}:workspace:${workspace}:run_phase:*" if can(regex("\\*+", workspace))
]
])

oidc_provider_url = "https://app.terraform.io"
}

data "tls_certificate" "tfc_certificate" {
url = "https://app.terraform.io"
}
37 changes: 37 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
resource "aws_iam_openid_connect_provider" "tfc_provider" {
count = var.create_tfc_oidc_provider ? 1 : 0

url = local.oidc_provider_url
client_id_list = var.tfc_oidc_provider_audiences
thumbprint_list = [
data.tls_certificate.tfc_certificate.certificates.0.sha1_fingerprint,
]
}

module "tfc_workload_identity_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 5.3.0"

# Role must not be created if no workspaces are listed. Otherwise, anyone on TFC with the right
# audience can assume this role.
create_role = var.create_tfc_workload_identity_role && (
length(local.tfc_workload_identity_workspaces_exact) + length(local.tfc_workload_identity_workspaces_wildcard) > 0
)

role_name = var.tfc_workload_identity_role
role_description = var.tfc_workload_identity_role_description

role_policy_arns = var.tfc_workload_identity_role_policy_arns
role_permissions_boundary_arn = var.tfc_workload_identity_role_permissions_boundary_arn
force_detach_policies = true

max_session_duration = var.tfc_workload_identity_role_max_session_duration

provider_url = var.create_tfc_oidc_provider ? aws_iam_openid_connect_provider.tfc_provider[0].url : local.oidc_provider_url

oidc_fully_qualified_subjects = local.tfc_workload_identity_workspaces_exact
oidc_subjects_with_wildcards = local.tfc_workload_identity_workspaces_wildcard
oidc_fully_qualified_audiences = coalescelist(var.tfc_workload_identity_role_audiences, aws_iam_openid_connect_provider.tfc_provider[0].client_id_list)

tags = var.tags
}
17 changes: 17 additions & 0 deletions output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
output "tfc_workload_identity_role_arn" {
description = "IAM Role ARN for TFC Workload Identity"
value = module.tfc_workload_identity_role.iam_role_arn
}

output "tfc_workload_identity_audience" {
description = "Audience value for TFC workload identity"
value = var.create_tfc_oidc_provider ? aws_iam_openid_connect_provider.tfc_provider[0].client_id_list : []
}

output "tfc_workload_identity_workspaces" {
description = "Workspaces allowed to assume the Workload Identity IAM Role"
value = concat(
local.tfc_workload_identity_workspaces_exact,
local.tfc_workload_identity_workspaces_wildcard,
)
}
65 changes: 65 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
variable "tags" {
description = "List of tags for resources"
type = map(string)
default = {}
}

variable "create_tfc_oidc_provider" {
description = "Create TFC OIDC Provider. Only one can exist in an account"
type = bool
default = true
}

variable "tfc_oidc_provider_audiences" {
description = "List of TFC OIDC Provider audiences. This is part of the security configuration between TFC and your AWS account"
type = list(string)
default = []
}

variable "create_tfc_workload_identity_role" {
description = "Create IAM Role for TFC Workload Identity"
type = bool
default = true
}

variable "tfc_workload_identity_role" {
description = "Name of the IAM Role for TFC"
type = string
default = "TfcWorkloadIdentity"
}

variable "tfc_workload_identity_role_description" {
description = "Description of the IAM Role for TFC"
type = string
default = "Terraform Cloud Workload Identity"
}

variable "tfc_workload_identity_role_max_session_duration" {
description = "Maximum CLI/API session duration in seconds between 3600 and 43200"
type = number
default = 3600
}

variable "tfc_workload_identity_role_policy_arns" {
description = "List of ARN to attach the IAM Role for TFC"
type = list(string)
default = []
}

variable "tfc_workload_identity_role_permissions_boundary_arn" {
description = "Permissions boundary ARN to use for IAM role for TFC"
type = string
default = ""
}

variable "tfc_workload_identity_workspaces" {
description = "Workspaces to allow access to the workload identity for this account"
type = map(list(string)) # Key is the organization, values are the list of workspaces
default = {}
}

variable "tfc_workload_identity_role_audiences" {
description = "List of allowed audiences for the IAM Role. Defaults to the one for the OIDC provider if unspecified."
type = list(string)
default = []
}
9 changes: 9 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}