Skip to content

Commit

Permalink
* 1.2.3 -- 2025-07-29
Browse files Browse the repository at this point in the history
  - add acmpca-iam-rolesanywhere example
  • Loading branch information
badra001 committed Jul 29, 2025
1 parent cd7dff1 commit 5cb1d26
Show file tree
Hide file tree
Showing 13 changed files with 281 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@
* 1.2.2 -- 2025-03-18
- all
- add validation of contact_email to include @ and in the census.gov domain

* 1.2.3 -- 2025-07-29
- add acmpca-iam-rolesanywhere example

2 changes: 1 addition & 1 deletion common/version.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
locals {
_module_version = "1.2.2"
_module_version = "1.2.3"
}
13 changes: 13 additions & 0 deletions examples/acmpca-iam-rolesanywhere/aws_config.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "local_file" "aws_config_file" {
filename = format("%v/%v.%v", "./certs", local.role_name, "aws_config")
file_permission = "0644"
directory_permission = "0755"
content = templatefile("aws_config.tpl", {
account_alias = var.account_alias
role_name = local.role_name
role_arn = aws_iam_role.role.arn
trust_anchor_arn = local.this_trust_arn
profile_arn = aws_rolesanywhere_profile.role.arn
region = var.region
})
}
3 changes: 3 additions & 0 deletions examples/acmpca-iam-rolesanywhere/aws_config.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[profile ${account_alias}.${role_name}]
region = ${region}
credential_process = aws_signing_helper credential-process --certificate CERTPATH/${role_name}.crt --private-key CERTPATH/${role_name}.key --trust-anchor-arn ${trust_anchor_arn} --profile-arn ${profile_arn} --role-arn ${role_arn} --region ${region}
28 changes: 28 additions & 0 deletions examples/acmpca-iam-rolesanywhere/certificate.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module "certificate" {
source = "git@github.e.it.census.gov:terraform-modules/aws-certificates//acmpca-iam-rolesanywhere"

role_name = local.role_name
contact_email = var.contact_group_email
certificate_subject_ou = local.certificate_subject_ou["x509Subject/OU"]
validity_days = var.validity_days
}

locals {
this_trust_arn = try(([for k, v in local.trust_ca[var.region] : v if v.ca_name == module.certificate.certificate_authority_name])[0].trust_arn, null)
}

## output "certificate_subject" {
## value = module.certificate.certificate_subject
## }
##
## output "certificate_details" {
## value = module.certificate.certificate_details
## }
##
## output "certificate_issuer_details" {
## value = module.certificate.certificate_issuer_details
## }
##
## output "certificate_issuer_subject" {
## value = module.certificate.certificate_issuer_subject
## }
42 changes: 42 additions & 0 deletions examples/acmpca-iam-rolesanywhere/data.ssm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
data "aws_ssm_parameters_by_path" "trust_east" {
provider = aws.east
path = "/enterprise/rolesanywhere/trustanchor/"
recursive = true
}

data "aws_ssm_parameters_by_path" "trust_west" {
provider = aws.west
path = "/enterprise/rolesanywhere/trustanchor/"
recursive = true
}

locals {
trust_east_arns = zipmap(data.aws_ssm_parameters_by_path.trust_east.names, data.aws_ssm_parameters_by_path.trust_east.arns)
trust_east_values = zipmap(data.aws_ssm_parameters_by_path.trust_east.names, nonsensitive(data.aws_ssm_parameters_by_path.trust_east.values))
_trust_east_ca = { for v in data.aws_ssm_parameters_by_path.trust_east.names : v => slice(reverse(split("/", v)), 0, 2) }
trust_east_ca = { for k, v in local._trust_east_ca : k => {
label = k
region = "us-gov-east-1"
ca_name = v[0]
ssm_parameter_name = k
ssm_paraemter_arn = local.trust_east_arns[k]
trust_arn = local.trust_east_values[k]
} }

trust_west_arns = zipmap(data.aws_ssm_parameters_by_path.trust_west.names, data.aws_ssm_parameters_by_path.trust_west.arns)
trust_west_values = zipmap(data.aws_ssm_parameters_by_path.trust_west.names, nonsensitive(data.aws_ssm_parameters_by_path.trust_west.values))
_trust_west_ca = { for v in data.aws_ssm_parameters_by_path.trust_west.names : v => slice(reverse(split("/", v)), 0, 2) }
trust_west_ca = { for k, v in local._trust_west_ca : k => {
label = k
region = "us-gov-west-1"
ca_name = v[0]
ssm_parameter_name = k
ssm_paraemter_arn = local.trust_west_arns[k]
trust_arn = local.trust_west_values[k]
} }

trust_ca = {
"us-gov-east-1" = local.trust_east_ca
"us-gov-west-1" = local.trust_west_ca
}
}
7 changes: 7 additions & 0 deletions examples/acmpca-iam-rolesanywhere/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "aws_caller_identity" "current" {}

data "aws_arn" "current" {
arn = data.aws_caller_identity.current.arn
}

data "aws_region" "current" {}
5 changes: 5 additions & 0 deletions examples/acmpca-iam-rolesanywhere/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
locals {
base_tags = {
"boc:created_by" = "terraform"
}
}
3 changes: 3 additions & 0 deletions examples/acmpca-iam-rolesanywhere/region.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
locals {
region = var.region
}
83 changes: 83 additions & 0 deletions examples/acmpca-iam-rolesanywhere/role.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
locals {
role_name = format("r-%v", var.role_name)
certificate_subject_ou = { "x509Subject/OU" = lookup(var.certificate_conditions, "x509Subject/OU", format("IAM RolesAnywhere %v", data.aws_caller_identity.current.account_id)) }
certificate_conditions = merge(
local.certificate_subject_ou,
var.certificate_conditions,
{ "x509Subject/CN" = local.role_name },
)
}

resource "aws_rolesanywhere_profile" "role" {
name = local.role_name
enabled = true
role_arns = [aws_iam_role.role.arn]

tags = merge(
local.base_tags,
# var.account_tags,
# var.infrastructure_tags,
# var.application_tags,
{ Name = local.role_name },
)
}

resource "aws_iam_role" "role" {
name = local.role_name
assume_role_policy = data.aws_iam_policy_document.role_anywhere_assume.json
managed_policy_arns = []
# add policies as needed

tags = merge(
local.base_tags,
# var.account_tags,
# var.infrastructure_tags,
# var.application_tags,
{ Name = local.role_name },
)
}


data "aws_iam_policy_document" "role_anywhere_assume" {
statement {
sid = "RolesAnywhereTrust"
effect = "Allow"
actions = [
"sts:AssumeRole",
"sts:TagSession",
"sts:SetSourceIdentity",
]
principals {
type = "Service"
identifiers = ["rolesanywhere.amazonaws.com"]
}
condition {
test = "ForAnyValue:StringEquals"
variable = "aws:SourceArn"
values = concat(nonsensitive(data.aws_ssm_parameters_by_path.trust_east.values), nonsensitive(data.aws_ssm_parameters_by_path.trust_west.values))
}
# include condition for certificate
dynamic "condition" {
for_each = local.certificate_conditions
iterator = c
content {
test = "StringEquals"
variable = format("aws:PrincipalTag/%v", c.key)
values = [c.value]
}
}
}
}


## "Condition": {
## "StringEquals": {
## "aws:PrincipalTag/x509Subject/CN": "onpremsrv01",
## "aws:PrincipalTag/x509Subject/OU": "SecOps"
## }
## }
# https://aws.amazon.com/blogs/security/extend-aws-iam-roles-to-workloads-outside-of-aws-with-iam-roles-anywhere/
# https://docs.aws.amazon.com/rolesanywhere/latest/userguide/workload-identities.html

# https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html

27 changes: 27 additions & 0 deletions examples/acmpca-iam-rolesanywhere/tf-run.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
VERSION 2.1.1
TAG setup
REMOTE-STATE
COMMAND tf-directory-setup.py -l none -f
COMMAND setup-new-directory.sh

TAG links
LINKTOP includes.d/variables.account_tags.tf
LINKTOP includes.d/variables.account_tags.auto.tfvars
LINKTOP includes.d/variables.infrastructure_tags.tf
LINKTOP includes.d/variables.infrastructure_tags.auto.tfvars
LINKTOP includes.d/variables.application_tags.tf
LINKTOP includes.d/variables.application_tags.auto.tfvars
# LINKTOP provider_configs.d/provider.ldap_new.auto.tfvars
# LINKTOP provider_configs.d/provider.ldap_new.tf
# LINKTOP provider_configs.d/provider.ldap_new.variables.tf
COMMAND rm -f provider.ldap.*

TAG init
COMMAND tf-init

TAG start
#POLICY
ALL

TAG state-link
COMMAND tf-directory-setup.py -l s3
32 changes: 32 additions & 0 deletions examples/acmpca-iam-rolesanywhere/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
variable "role_name" {
description = "Role Name (without r- prefix)"
type = string
}

variable "certificate_conditions" {
description = "Map of certificate conditions to be merged with x509Subject/CN={role_name}"
type = map(string)
default = {}
}

variable "contact_group_email" {
description = "Email of contact group"
type = string
}

variable "contact_users" {
description = "Username of contact(s)"
type = list(string)
default = []
}

variable "validity_days" {
description = "Number of days for which the certificate is valid (default: 365, max: 365)"
type = number
default = 365

validation {
condition = var.validity_days > 0 && var.validity_days <= 365
error_message = "validity_days must be between 1 and 365"
}
}
33 changes: 33 additions & 0 deletions examples/acmpca-iam-rolesanywhere/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.0"
}
# ldap = {
# source = "trevex/ldap"
# version = ">= 0.5.4"
# }
# external = {
# source = "hashicorp/external"
# version = ">= 1.0"
# }
# null = {
# source = "hashicorp/null"
# version = ">= 1.0"
# }
# random = {
# source = "hashicorp/random"
# version = ">= 1.0"
# }
# template = {
# source = "hashicorp/template"
# version = ">= 1.0"
# }
# infoblox = {
# source = "infobloxopen/infoblox"
# version = ">= 2.1.0"
# }
}
}

0 comments on commit 5cb1d26

Please sign in to comment.