Skip to content

Commit

Permalink
feat: Allow generic assume role conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
bryantbiggs committed Dec 26, 2024
1 parent 5bc0223 commit 04fd14d
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.96.1
rev: v1.96.3
hooks:
- id: terraform_fmt
- id: terraform_wrapper_module_for_each
Expand Down
16 changes: 15 additions & 1 deletion examples/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ provider "aws" {
###############################
# IAM assumable role for admin
###############################

module "iam_assumable_role_admin" {
source = "../../modules/iam-assumable-role"

Expand Down Expand Up @@ -36,9 +37,12 @@ module "iam_assumable_role_admin" {
##########################################
# IAM assumable role with custom policies
##########################################

module "iam_assumable_role_custom" {
source = "../../modules/iam-assumable-role"

create_role = true

trusted_role_arns = [
"arn:aws:iam::307990089504:root",
]
Expand All @@ -47,7 +51,13 @@ module "iam_assumable_role_custom" {
"codedeploy.amazonaws.com"
]

create_role = true
trust_policy_conditions = [
{
test = "StringEquals"
variable = "aws:PrincipalOrgID"
values = ["o-someorgid"]
}
]

role_name_prefix = "custom-"
role_requires_mfa = false
Expand All @@ -65,6 +75,7 @@ module "iam_assumable_role_custom" {
##########################################
# IAM assumable role with inline policy
##########################################

module "iam_assumable_role_inline_policy" {
source = "../../modules/iam-assumable-role"

Expand Down Expand Up @@ -109,6 +120,7 @@ module "iam_assumable_role_inline_policy" {
####################################################
# IAM assumable role with multiple sts external ids
####################################################

module "iam_assumable_role_sts" {
source = "../../modules/iam-assumable-role"

Expand Down Expand Up @@ -141,6 +153,7 @@ module "iam_assumable_role_sts" {
#########################################
# IAM assumable role with custom trust policy
#########################################

module "iam_assumable_role_custom_trust_policy" {
source = "../../modules/iam-assumable-role"

Expand Down Expand Up @@ -180,6 +193,7 @@ data "aws_iam_policy_document" "custom_trust_policy" {
#########################################
# IAM policy
#########################################

module "iam_policy" {
source = "../../modules/iam-policy"

Expand Down
2 changes: 1 addition & 1 deletion modules/iam-assumable-role-with-oidc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ No modules.
| <a name="input_oidc_fully_qualified_audiences"></a> [oidc\_fully\_qualified\_audiences](#input\_oidc\_fully\_qualified\_audiences) | The audience to be added to the role policy. Set to sts.amazonaws.com for cross-account assumable role. Leave empty otherwise. | `set(string)` | `[]` | no |
| <a name="input_oidc_fully_qualified_subjects"></a> [oidc\_fully\_qualified\_subjects](#input\_oidc\_fully\_qualified\_subjects) | The fully qualified OIDC subjects to be added to the role policy | `set(string)` | `[]` | no |
| <a name="input_oidc_subjects_with_wildcards"></a> [oidc\_subjects\_with\_wildcards](#input\_oidc\_subjects\_with\_wildcards) | The OIDC subject using wildcards to be added to the role policy | `set(string)` | `[]` | no |
| <a name="input_provider_trust_policy_conditions"></a> [provider\_trust\_policy\_conditions](#input\_provider\_trust\_policy\_conditions) | [Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy | `any` | `[]` | no |
| <a name="input_provider_trust_policy_conditions"></a> [provider\_trust\_policy\_conditions](#input\_provider\_trust\_policy\_conditions) | [Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy | <pre>list(object({<br/> test = string<br/> variable = string<br/> values = list(string)<br/> }))</pre> | `[]` | no |
| <a name="input_provider_url"></a> [provider\_url](#input\_provider\_url) | URL of the OIDC Provider. Use provider\_urls to specify several URLs. | `string` | `""` | no |
| <a name="input_provider_urls"></a> [provider\_urls](#input\_provider\_urls) | List of URLs of the OIDC Providers | `list(string)` | `[]` | no |
| <a name="input_role_description"></a> [role\_description](#input\_role\_description) | IAM Role description | `string` | `""` | no |
Expand Down
8 changes: 6 additions & 2 deletions modules/iam-assumable-role-with-oidc/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ variable "allow_self_assume_role" {

variable "provider_trust_policy_conditions" {
description = "[Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy"
type = any
default = []
type = list(object({
test = string
variable = string
values = list(string)
}))
default = []
}
1 change: 1 addition & 0 deletions modules/iam-assumable-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ No modules.
| <a name="input_role_session_name"></a> [role\_session\_name](#input\_role\_session\_name) | role\_session\_name for roles which require this parameter when being assumed. By default, you need to set your own username as role\_session\_name | `list(string)` | <pre>[<br/> "${aws:username}"<br/>]</pre> | no |
| <a name="input_role_sts_externalid"></a> [role\_sts\_externalid](#input\_role\_sts\_externalid) | STS ExternalId condition values to use with a role (when MFA is not required) | `any` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to IAM role resources | `map(string)` | `{}` | no |
| <a name="input_trust_policy_conditions"></a> [trust\_policy\_conditions](#input\_trust\_policy\_conditions) | [Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy | <pre>list(object({<br/> test = string<br/> variable = string<br/> values = list(string)<br/> }))</pre> | `[]` | no |
| <a name="input_trusted_role_actions"></a> [trusted\_role\_actions](#input\_trusted\_role\_actions) | Additional trusted role actions | `list(string)` | <pre>[<br/> "sts:AssumeRole",<br/> "sts:TagSession"<br/>]</pre> | no |
| <a name="input_trusted_role_arns"></a> [trusted\_role\_arns](#input\_trusted\_role\_arns) | ARNs of AWS entities who can assume these roles | `list(string)` | `[]` | no |
| <a name="input_trusted_role_services"></a> [trusted\_role\_services](#input\_trusted\_role\_services) | AWS Services that can assume these roles | `list(string)` | `[]` | no |
Expand Down
26 changes: 25 additions & 1 deletion modules/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ data "aws_iam_policy_document" "assume_role" {

dynamic "condition" {
for_each = length(local.role_sts_externalid) != 0 ? [true] : []

content {
test = "StringEquals"
variable = "sts:ExternalId"
Expand All @@ -59,12 +60,23 @@ data "aws_iam_policy_document" "assume_role" {

dynamic "condition" {
for_each = var.role_requires_session_name ? [1] : []

content {
test = "StringEquals"
variable = "sts:RoleSessionName"
values = var.role_session_name
}
}

dynamic "condition" {
for_each = var.trust_policy_conditions

content {
test = condition.value.test
variable = condition.value.variable
values = condition.value.values
}
}
}
}

Expand Down Expand Up @@ -121,6 +133,7 @@ data "aws_iam_policy_document" "assume_role_with_mfa" {

dynamic "condition" {
for_each = length(local.role_sts_externalid) != 0 ? [true] : []

content {
test = "StringEquals"
variable = "sts:ExternalId"
Expand All @@ -130,12 +143,23 @@ data "aws_iam_policy_document" "assume_role_with_mfa" {

dynamic "condition" {
for_each = var.role_requires_session_name ? [1] : []

content {
test = "StringEquals"
variable = "sts:RoleSessionName"
values = var.role_session_name
}
}

dynamic "condition" {
for_each = var.trust_policy_conditions

content {
test = condition.value.test
variable = condition.value.variable
values = condition.value.values
}
}
}
}

Expand Down Expand Up @@ -255,6 +279,6 @@ resource "aws_iam_role_policy" "inline" {
count = local.create_iam_role_inline_policy ? 1 : 0

role = aws_iam_role.this[0].name
name_prefix = "${var.role_name}_inline_"
name_prefix = "${try(coalesece(var.role_name, var.role_name_prefix), "")}_inline_"
policy = data.aws_iam_policy_document.inline[0].json
}
10 changes: 10 additions & 0 deletions modules/iam-assumable-role/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ variable "trusted_role_services" {
default = []
}

variable "trust_policy_conditions" {
description = "[Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy"
type = list(object({
test = string
variable = string
values = list(string)
}))
default = []
}

variable "mfa_age" {
description = "Max age of valid MFA (in seconds) for roles which require MFA"
type = number
Expand Down
1 change: 1 addition & 0 deletions modules/iam-assumable-roles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ No modules.
| <a name="input_readonly_role_policy_arns"></a> [readonly\_role\_policy\_arns](#input\_readonly\_role\_policy\_arns) | List of policy ARNs to use for readonly role | `list(string)` | <pre>[<br/> "arn:aws:iam::aws:policy/ReadOnlyAccess"<br/>]</pre> | no |
| <a name="input_readonly_role_requires_mfa"></a> [readonly\_role\_requires\_mfa](#input\_readonly\_role\_requires\_mfa) | Whether readonly role requires MFA | `bool` | `true` | no |
| <a name="input_readonly_role_tags"></a> [readonly\_role\_tags](#input\_readonly\_role\_tags) | A map of tags to add to readonly role resource. | `map(string)` | `{}` | no |
| <a name="input_trust_policy_conditions"></a> [trust\_policy\_conditions](#input\_trust\_policy\_conditions) | [Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy | <pre>list(object({<br/> test = string<br/> variable = string<br/> values = list(string)<br/> }))</pre> | `[]` | no |
| <a name="input_trusted_role_actions"></a> [trusted\_role\_actions](#input\_trusted\_role\_actions) | Additional trusted role actions | `list(string)` | <pre>[<br/> "sts:AssumeRole",<br/> "sts:TagSession"<br/>]</pre> | no |
| <a name="input_trusted_role_arns"></a> [trusted\_role\_arns](#input\_trusted\_role\_arns) | ARNs of AWS entities who can assume these roles | `list(string)` | `[]` | no |
| <a name="input_trusted_role_services"></a> [trusted\_role\_services](#input\_trusted\_role\_services) | AWS Services that can assume these roles | `list(string)` | `[]` | no |
Expand Down
20 changes: 20 additions & 0 deletions modules/iam-assumable-roles/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ data "aws_iam_policy_document" "assume_role" {
type = "Service"
identifiers = var.trusted_role_services
}

dynamic "condition" {
for_each = var.trust_policy_conditions

content {
test = condition.value.test
variable = condition.value.variable
values = condition.value.values
}
}
}
}

Expand Down Expand Up @@ -181,6 +191,16 @@ data "aws_iam_policy_document" "assume_role_with_mfa" {
variable = "aws:MultiFactorAuthAge"
values = [var.mfa_age]
}

dynamic "condition" {
for_each = var.trust_policy_conditions

content {
test = condition.value.test
variable = condition.value.variable
values = condition.value.values
}
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions modules/iam-assumable-roles/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ variable "trusted_role_services" {
default = []
}

variable "trust_policy_conditions" {
description = "[Condition constraints](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document#condition) applied to the trust policy"
type = list(object({
test = string
variable = string
values = list(string)
}))
default = []
}

variable "mfa_age" {
description = "Max age of valid MFA (in seconds) for roles which require MFA"
type = number
Expand Down
1 change: 1 addition & 0 deletions wrappers/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ module "wrapper" {
trusted_role_actions = try(each.value.trusted_role_actions, var.defaults.trusted_role_actions, ["sts:AssumeRole", "sts:TagSession"])
trusted_role_arns = try(each.value.trusted_role_arns, var.defaults.trusted_role_arns, [])
trusted_role_services = try(each.value.trusted_role_services, var.defaults.trusted_role_services, [])
trust_policy_conditions = try(each.value.trust_policy_conditions, var.defaults.trust_policy_conditions, [])
}
1 change: 1 addition & 0 deletions wrappers/iam-assumable-roles/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ module "wrapper" {
trusted_role_actions = try(each.value.trusted_role_actions, var.defaults.trusted_role_actions, ["sts:AssumeRole", "sts:TagSession"])
trusted_role_arns = try(each.value.trusted_role_arns, var.defaults.trusted_role_arns, [])
trusted_role_services = try(each.value.trusted_role_services, var.defaults.trusted_role_services, [])
trust_policy_conditions = try(each.value.trust_policy_conditions, var.defaults.trust_policy_conditions, [])
}

0 comments on commit 04fd14d

Please sign in to comment.