Skip to content

Commit

Permalink
feat: Add support for roles created to explicitly assume their own ro…
Browse files Browse the repository at this point in the history
…le if desired (terraform-aws-modules#281)
  • Loading branch information
bryantbiggs authored Sep 27, 2022
1 parent 7c96f1f commit 3d29d26
Show file tree
Hide file tree
Showing 23 changed files with 232 additions and 35 deletions.
13 changes: 3 additions & 10 deletions examples/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ provider "aws" {
module "iam_assumable_role_admin" {
source = "../../modules/iam-assumable-role"

# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
allow_self_assume_role = true

trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
Expand Down Expand Up @@ -127,16 +130,6 @@ data "aws_iam_policy_document" "custom_trust_policy" {
identifiers = ["*"]
}
}

statement {
effect = "Deny"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::111111111111:root"]
}
}
}

#########################################
Expand Down
1 change: 1 addition & 0 deletions modules/iam-assumable-role-with-oidc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS account ID where the OIDC provider lives, leave empty to use the account for the AWS provider | `string` | `""` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `false` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
20 changes: 17 additions & 3 deletions modules/iam-assumable-role-with-oidc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,32 @@ locals {
}

data "aws_caller_identity" "current" {}

data "aws_partition" "current" {}

data "aws_iam_policy_document" "assume_role_with_oidc" {
count = var.create_role ? 1 : 0

dynamic "statement" {
for_each = local.urls
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
effect = "Allow"
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

dynamic "statement" {
for_each = local.urls

content {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role-with-oidc/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,9 @@ variable "force_detach_policies" {
type = bool
default = false
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-role-with-saml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ No modules.
|------|------|
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role_with_saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_saml_endpoint"></a> [aws\_saml\_endpoint](#input\_aws\_saml\_endpoint) | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `false` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
22 changes: 20 additions & 2 deletions modules/iam-assumable-role-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
identifiers = compact(distinct(concat(var.provider_ids, [var.provider_id])))
number_of_role_policy_arns = coalesce(var.number_of_role_policy_arns, length(var.role_policy_arns))
}

data "aws_iam_policy_document" "assume_role_with_saml" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithSAML"]

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role-with-saml/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,9 @@ variable "force_detach_policies" {
type = bool
default = false
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ No modules.
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.assume_role_with_mfa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_admin_role_policy_arn"></a> [admin\_role\_policy\_arn](#input\_admin\_role\_policy\_arn) | Policy ARN to use for admin role | `string` | `"arn:aws:iam::aws:policy/AdministratorAccess"` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_attach_admin_policy"></a> [attach\_admin\_policy](#input\_attach\_admin\_policy) | Whether to attach an admin policy to a role | `bool` | `false` | no |
| <a name="input_attach_poweruser_policy"></a> [attach\_poweruser\_policy](#input\_attach\_poweruser\_policy) | Whether to attach a poweruser policy to a role | `bool` | `false` | no |
| <a name="input_attach_readonly_policy"></a> [attach\_readonly\_policy](#input\_attach\_readonly\_policy) | Whether to attach a readonly policy to a role | `bool` | `false` | no |
Expand Down
41 changes: 37 additions & 4 deletions modules/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
role_sts_externalid = flatten([var.role_sts_externalid])
}

data "aws_iam_policy_document" "assume_role" {
count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 0 : 1

statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = var.trusted_role_actions

principals {
Expand All @@ -34,9 +52,24 @@ data "aws_iam_policy_document" "assume_role" {
data "aws_iam_policy_document" "assume_role_with_mfa" {
count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 1 : 0

statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = var.trusted_role_actions

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,9 @@ variable "role_sts_externalid" {
type = any
default = []
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-roles-with-saml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ No modules.
| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role_with_saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

Expand All @@ -45,6 +47,7 @@ No modules.
| <a name="input_admin_role_permissions_boundary_arn"></a> [admin\_role\_permissions\_boundary\_arn](#input\_admin\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for admin role | `string` | `""` | no |
| <a name="input_admin_role_policy_arns"></a> [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` | <pre>[<br> "arn:aws:iam::aws:policy/AdministratorAccess"<br>]</pre> | no |
| <a name="input_admin_role_tags"></a> [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_saml_endpoint"></a> [aws\_saml\_endpoint](#input\_aws\_saml\_endpoint) | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no |
| <a name="input_create_admin_role"></a> [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no |
| <a name="input_create_poweruser_role"></a> [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no |
Expand Down
19 changes: 19 additions & 0 deletions modules/iam-assumable-roles-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
identifiers = compact(distinct(concat(var.provider_ids, [var.provider_id])))
}

data "aws_iam_policy_document" "assume_role_with_saml" {
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"

Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-roles-with-saml/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ variable "aws_saml_endpoint" {
type = string
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}

# Admin
variable "create_admin_role" {
description = "Whether to create admin role"
Expand Down
3 changes: 3 additions & 0 deletions modules/iam-assumable-roles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ No modules.
| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.assume_role_with_mfa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

Expand All @@ -45,6 +47,7 @@ No modules.
| <a name="input_admin_role_policy_arns"></a> [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` | <pre>[<br> "arn:aws:iam::aws:policy/AdministratorAccess"<br>]</pre> | no |
| <a name="input_admin_role_requires_mfa"></a> [admin\_role\_requires\_mfa](#input\_admin\_role\_requires\_mfa) | Whether admin role requires MFA | `bool` | `true` | no |
| <a name="input_admin_role_tags"></a> [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_create_admin_role"></a> [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no |
| <a name="input_create_poweruser_role"></a> [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no |
| <a name="input_create_readonly_role"></a> [create\_readonly\_role](#input\_create\_readonly\_role) | Whether to create readonly role | `bool` | `false` | no |
Expand Down
41 changes: 37 additions & 4 deletions modules/iam-assumable-roles/main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
Expand All @@ -17,9 +35,24 @@ data "aws_iam_policy_document" "assume_role" {
}

data "aws_iam_policy_document" "assume_role_with_mfa" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

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

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}

# Admin
variable "create_admin_role" {
description = "Whether to create admin role"
Expand Down
1 change: 1 addition & 0 deletions modules/iam-eks-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_cluster_service_accounts"></a> [cluster\_service\_accounts](#input\_cluster\_service\_accounts) | EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details | `map(list(string))` | `{}` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
Loading

0 comments on commit 3d29d26

Please sign in to comment.