Skip to content

Commit

Permalink
Add new submodule to create single role assumable by OIDC subjects
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelaferreira committed Oct 14, 2019
1 parent fa05d3a commit 632e31a
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,28 @@ module "iam_assumable_role" {
}
```

`iam-assumable-role-with-oidc`:
```hcl
module "iam_assumable_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
version = "~> 2.0"
create_role = true
role_name = "role-with-oidc"
tags = {
Role = "role-with-oidc"
}
provider_url = "oidc.eks.eu-west-1.amazonaws.com/id/BA9E170D464AF7B92084EF72A69B9DC8"
role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
]
}
```

`iam-assumable-roles`:
```hcl
module "iam_assumable_roles" {
Expand Down Expand Up @@ -231,6 +253,7 @@ Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-i

* [iam-account](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-account) - Set AWS account alias and password policy
* [iam-assumable-role](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-role) - Create individual IAM role which can be assumed from specified ARNs (AWS accounts, IAM users, etc)
* [iam-assumable-role-with-oidc](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-role-with-oidc) - Create individual IAM role which can be assumed from specified subjects federated with a OIDC Identity Provider
* [iam-assumable-roles](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-roles) - Create several IAM roles which can be assumed from specified ARNs (AWS accounts, IAM users, etc)
* [iam-assumable-roles-with-saml](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-roles-with-saml) - Create several IAM roles which can be assumed by users with a SAML Identity Provider
* [iam-group-with-assumable-roles-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-group-with-assumable-roles-policy) - IAM group with users who are allowed to assume IAM roles in the same or in separate AWS account
Expand Down
29 changes: 29 additions & 0 deletions examples/iam-assumable-role-with-oidc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Individual IAM assumable roles example

Configuration in this directory creates several individual IAM roles which can be assumed from a defined list of [IAM ARNs](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns).

The main difference between `iam-assumable-role` and `iam-assumable-roles` examples is that the former creates just a single role.

# Usage

To run this example you need to execute:

```bash
$ terraform init
$ terraform plan
$ terraform apply
```

Run `terraform destroy` when you don't need these resources.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Outputs

| Name | Description |
|------|-------------|
| role\_requires\_mfa | Whether admin IAM role requires MFA |
| this\_iam\_role\_arn | ARN of IAM role |
| this\_iam\_role\_name | Name of IAM role |
| this\_iam\_role\_path | Path of IAM role |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
24 changes: 24 additions & 0 deletions examples/iam-assumable-role-with-oidc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
provider "aws" {
region = "eu-west-1"
}

###############################
# IAM assumable role for admin
###############################
module "iam_assumable_role_admin" {
source = "../../modules/iam-assumable-role-with-iodc"

create_role = true

role_name = "role-with-oidc"

tags = {
Role = "role-with-oidc"
}

provider_url = "oidc.eks.eu-west-1.amazonaws.com/id/BA9E170D464AF7B92084EF72A69B9DC8"

role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
]
}
14 changes: 14 additions & 0 deletions examples/iam-assumable-role-with-oidc/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "this_iam_role_arn" {
description = "ARN of IAM role"
value = module.iam_assumable_role_admin.this_iam_role_arn
}

output "this_iam_role_name" {
description = "Name of IAM role"
value = module.iam_assumable_role_admin.this_iam_role_name
}

output "this_iam_role_path" {
description = "Path of IAM role"
value = module.iam_assumable_role_admin.this_iam_role_path
}
40 changes: 40 additions & 0 deletions modules/iam-assumable-role-with-iodc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# iam-assumable-role-with-oidc

Creates single IAM role which can be assumed by trusted resources using OpenID Connect Federated Users.

[Creating IAM OIDC Identity Providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)

This module supports IAM Roles for kubernetes service accounts as described in the [EKS documentation](https://docs.aws.amazon.com/en_pv/eks/latest/userguide/iam-roles-for-service-accounts.html).

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| aws\_account\_id | The AWS account ID where the OIDC provider lives, leave empty to use the account fo the AWS provider | string | `""` | no |
| create\_role | Whether to create a role | bool | `"false"` | no |
| max\_session\_duration | Maximum CLI/API session duration in seconds between 3600 and 43200 | number | `"3600"` | no |
| oidc\_fully\_qualified\_subjects | The fully qualified OIDC subjects to be added to the role policy | list(string) | `[]` | no |
| oidc\_subjects\_with\_wildcards | The OIDC subject using wildcards to be added to the role policy | list(string) | `[]` | no |
| provider\_url | URL of the OIDC Provider | string | n/a | yes |
| role\_name | IAM role name | string | `""` | no |
| role\_path | Path of IAM role | string | `"/"` | no |
| role\_permissions\_boundary\_arn | Permissions boundary ARN to use for IAM role | string | `""` | no |
| role\_policy\_arns | List of ARNs of IAM policies to attach to IAM role | list(string) | `[]` | no |
| tags | A map of tags to add to IAM role resources | map(string) | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| admin\_iam\_role\_arn | ARN of admin IAM role |
| admin\_iam\_role\_name | Name of admin IAM role |
| admin\_iam\_role\_path | Path of admin IAM role |
| poweruser\_iam\_role\_arn | ARN of poweruser IAM role |
| poweruser\_iam\_role\_name | Name of poweruser IAM role |
| poweruser\_iam\_role\_path | Path of poweruser IAM role |
| readonly\_iam\_role\_arn | ARN of readonly IAM role |
| readonly\_iam\_role\_name | Name of readonly IAM role |
| readonly\_iam\_role\_path | Path of readonly IAM role |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
62 changes: 62 additions & 0 deletions modules/iam-assumable-role-with-iodc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
locals {
aws_account_id = var.aws_account_id != "" ? var.aws_account_id : data.aws_caller_identity.current.account_id
}

data "aws_caller_identity" "current" {}

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

statement {
effect = "Allow"

actions = ["sts:AssumeRoleWithWebIdentity"]

principals {
type = "Federated"

identifiers = [
"arn:aws:iam::${local.aws_account_id}:oidc-provider/${var.provider_url}"
]
}

dynamic "condition" {
for_each = var.oidc_fully_qualified_subjects
content {
test = "StringEquals"
variable = "${var.provider_url}:sub"
values = [condition.value]
}
}

dynamic "condition" {
for_each = var.oidc_subjects_with_wildcards
content {
test = "StringLike"
variable = "${var.provider_url}:sub"
values = [condition.value]
}
}
}
}

resource "aws_iam_role" "this" {
count = var.create_role ? 1 : 0

name = var.role_name
path = var.role_path
max_session_duration = var.max_session_duration

permissions_boundary = var.role_permissions_boundary_arn

assume_role_policy = join("", data.aws_iam_policy_document.assume_role_with_oidc.*.json)

tags = var.tags
}

resource "aws_iam_role_policy_attachment" "custom" {
count = var.create_role && length(var.role_policy_arns) > 0 ? length(var.role_policy_arns) : 0

role = join("", aws_iam_role.this.*.name)
policy_arn = var.role_policy_arns[count.index]
}
14 changes: 14 additions & 0 deletions modules/iam-assumable-role-with-iodc/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "this_iam_role_arn" {
description = "ARN of IAM role"
value = element(concat(aws_iam_role.this.*.arn, [""]), 0)
}

output "this_iam_role_name" {
description = "Name of IAM role"
value = element(concat(aws_iam_role.this.*.name, [""]), 0)
}

output "this_iam_role_path" {
description = "Path of IAM role"
value = element(concat(aws_iam_role.this.*.path, [""]), 0)
}
65 changes: 65 additions & 0 deletions modules/iam-assumable-role-with-iodc/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
variable "create_role" {
description = "Whether to create a role"
type = bool
default = false
}

variable "provider_url" {
description = "URL of the OIDC Provider"
type = string
}

variable "aws_account_id" {
description = "The AWS account ID where the OIDC provider lives, leave empty to use the account fo the AWS provider"
type = string
default = ""
}

variable "tags" {
description = "A map of tags to add to IAM role resources"
type = map(string)
default = {}
}

variable "role_name" {
description = "IAM role name"
type = string
default = ""
}

variable "role_path" {
description = "Path of IAM role"
type = string
default = "/"
}

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

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

variable "role_policy_arns" {
description = "List of ARNs of IAM policies to attach to IAM role"
type = list(string)
default = []
}

variable "oidc_fully_qualified_subjects" {
description = "The fully qualified OIDC subjects to be added to the role policy"
type = list(string)
default = []
}

variable "oidc_subjects_with_wildcards" {
description = "The OIDC subject using wildcards to be added to the role policy"
type = list(string)
default = []
}

0 comments on commit 632e31a

Please sign in to comment.