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

feat: Add iam-assumable-role-with-saml module #127

Merged
merged 5 commits into from
Mar 5, 2021
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
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,29 @@ module "iam_assumable_role_with_oidc" {
}
```

`iam-assumable-role-with-saml`:
```hcl
module "iam_assumable_role_with_saml" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-saml"
version = "~> 3.0"
create_role = true
role_name = "role-with-saml"
tags = {
Role = "role-with-saml"
}
provider_id = "arn:aws:iam::235367859851:saml-provider/idp_saml"
role_policy_arns = [
"arn:aws:iam::aws:policy/ReadOnlyAccess"
]
number_of_role_policy_arns = 1
}
```

`iam-assumable-roles`:
```hcl
module "iam_assumable_roles" {
Expand Down Expand Up @@ -255,6 +278,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-role-with-saml](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-role-with-saml) - Create individual IAM role which can be assumed by users with a SAML 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
54 changes: 54 additions & 0 deletions examples/iam-assumable-role-with-saml/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Individual IAM assumable role with SAML Identity Provider example

Configuration in this directory creates a single IAM role which can be assumed by users with a SAML Identity Provider.

# 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 -->
## Requirements

| Name | Version |
|------|---------|
| terraform | >= 0.12.6 |
| aws | >= 2.23 |

## Providers

| Name | Version |
|------|---------|
| aws | >= 2.23 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| iam_assumable_role_admin | ../../modules/iam-assumable-role-with-saml | |

## Resources

| Name |
|------|
| [aws_iam_saml_provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_saml_provider) |

## Inputs

No input.

## Outputs

| Name | Description |
|------|-------------|
| 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 -->
35 changes: 35 additions & 0 deletions examples/iam-assumable-role-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
provider "aws" {
region = "eu-west-1"
}

resource "aws_iam_saml_provider" "idp_saml" {
name = "idp_saml"
saml_metadata_document = file("saml-metadata.xml")
}

resource "aws_iam_saml_provider" "second_idp_saml" {
name = "second_idp_saml"
saml_metadata_document = file("saml-metadata.xml")
}

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

create_role = true

role_name = "role-with-saml"

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

provider_id = aws_iam_saml_provider.idp_saml.id
provider_ids = [aws_iam_saml_provider.second_idp_saml.id]

role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy",
]
}
14 changes: 14 additions & 0 deletions examples/iam-assumable-role-with-saml/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
}
14 changes: 14 additions & 0 deletions examples/iam-assumable-role-with-saml/saml-metadata.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" entityID="https://terraform-dev-ed.my.salesforce.com" validUntil="2025-09-02T18:27:19.710Z">
<md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIErDCCA5SgAwIBAgIOAU+PT8RBAAAAAHxJXEcwDQYJKoZIhvcNAQELBQAwgZAxKDAmBgNVBAMMH1NlbGZTaWduZWRDZXJ0XzAyU2VwMjAxNV8xODI2NTMxGDAWBgNVBAsMDzAwRDI0MDAwMDAwcEFvQTEXMBUGA1UECgwOU2FsZXNmb3JjZS5jb20xFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xCzAJBgNVBAgMAkNBMQwwCgYDVQQGEwNVU0EwHhcNMTUwOTAyMTgyNjUzWhcNMTcwOTAyMTIwMDAwWjCBkDEoMCYGA1UEAwwfU2VsZlNpZ25lZENlcnRfMDJTZXAyMDE1XzE4MjY1MzEYMBYGA1UECwwPMDBEMjQwMDAwMDBwQW9BMRcwFQYDVQQKDA5TYWxlc2ZvcmNlLmNvbTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzELMAkGA1UECAwCQ0ExDDAKBgNVBAYTA1VTQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJp/wTRr9n1IWJpkRTjNpep47OKJrD2E6rGbJ18TG2RxtIz+zCn2JwH2aP3TULh0r0hhcg/pecv51RRcG7O19DBBaTQ5+KuoICQyKZy07/yDXSiZontTwkEYs06ssTwTHUcRXbcwTKv16L7omt0MjIhTTGfvtLOYiPwyvKvzAHg4eNuAcli0duVM78UIBORtdmy9C9ZcMh8yRJo5aPBq85wsE3JXU58ytyZzCHTBLH+2xFQrjYnUSEW+FOEEpI7o33MVdFBvWWg1R17HkWzcve4C30lqOHqvxBzyESZ/N1mMlmSt8gPFyB+mUXY99StJDJpnytbY8DwSzMQUo/sOVB0CAwEAAaOCAQAwgf0wHQYDVR0OBBYEFByu1EQqRQS0bYQBKS9K5qwKi+6IMA8GA1UdEwEB/wQFMAMBAf8wgcoGA1UdIwSBwjCBv4AUHK7URCpFBLRthAEpL0rmrAqL7oihgZakgZMwgZAxKDAmBgNVBAMMH1NlbGZTaWduZWRDZXJ0XzAyU2VwMjAxNV8xODI2NTMxGDAWBgNVBAsMDzAwRDI0MDAwMDAwcEFvQTEXMBUGA1UECgwOU2FsZXNmb3JjZS5jb20xFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xCzAJBgNVBAgMAkNBMQwwCgYDVQQGEwNVU0GCDgFPj0/EQQAAAAB8SVxHMA0GCSqGSIb3DQEBCwUAA4IBAQA9O5o1tC71qJnkq+ABPo4A1aFKZVT/07GcBX4/wetcbYySL4Q2nR9pMgfPYYS1j+P2E3viPsQwPIWDUBwFkNsjjX5DSGEkLAioVGKRwJshRSCSynMcsVZbQkfBUiZXqhM0wzvoa/ALvGD+aSSb1m+x7lEpDYNwQKWaUW2VYcHWv9wjujMyy7dlj8E/jqM71mw7ThNl6k4+3RQ802dMa14txm8pkF0vZgfpV3tkqhBqtjBAicVCaveqr3r3iGqjvyilBgdY+0NR8szqzm7CD/Bkb22+/IgM/mXQuL9KHD/WADlSGmYKmG3SSahmcZxznYCnzcRNN9LVuXlz5cbljmBj</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://terraform-dev-ed.my.salesforce.com/idp/endpoint/HttpPost"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://terraform-dev-ed.my.salesforce.com/idp/endpoint/HttpRedirect"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
Empty file.
7 changes: 7 additions & 0 deletions examples/iam-assumable-role-with-saml/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_version = ">= 0.12.6"

required_providers {
aws = ">= 2.23"
}
}
60 changes: 60 additions & 0 deletions modules/iam-assumable-role-with-saml/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# iam-assumable-role-with-saml

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

[Creating IAM SAML Identity Providers](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html)
[Enabling SAML 2.0 Federated Users to Access the AWS Management Console](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html)

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

| Name | Version |
|------|---------|
| terraform | >= 0.12.6 |
| aws | >= 2.23 |

## Providers

| Name | Version |
|------|---------|
| aws | >= 2.23 |

## Modules

No Modules.

## Resources

| Name |
|------|
| [aws_iam_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) |
| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) |
| [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| aws\_saml\_endpoint | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no |
| create\_role | Whether to create a role | `bool` | `false` | no |
| force\_detach\_policies | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
| max\_session\_duration | Maximum CLI/API session duration in seconds between 3600 and 43200 | `number` | `3600` | no |
| number\_of\_role\_policy\_arns | Number of IAM policies to attach to IAM role | `number` | `null` | no |
| provider\_id | ID of the SAML Provider. Use provider\_ids to specify several IDs. | `string` | `""` | no |
| provider\_ids | List of SAML Provider IDs | `list(string)` | `[]` | no |
| role\_description | IAM Role description | `string` | `""` | no |
| role\_name | IAM role name | `string` | `null` | no |
| role\_name\_prefix | IAM role name prefix | `string` | `null` | 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 |
|------|-------------|
| 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 -->
48 changes: 48 additions & 0 deletions modules/iam-assumable-role-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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"

actions = ["sts:AssumeRoleWithSAML"]

principals {
type = "Federated"

identifiers = local.identifiers
}

condition {
test = "StringEquals"
variable = "SAML:aud"
values = [var.aws_saml_endpoint]
}
}
}

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

name = var.role_name
name_prefix = var.role_name_prefix
description = var.role_description
path = var.role_path
max_session_duration = var.max_session_duration

force_detach_policies = var.force_detach_policies
permissions_boundary = var.role_permissions_boundary_arn

assume_role_policy = data.aws_iam_policy_document.assume_role_with_saml.json

tags = var.tags
}

resource "aws_iam_role_policy_attachment" "custom" {
count = var.create_role ? local.number_of_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-saml/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)
}
83 changes: 83 additions & 0 deletions modules/iam-assumable-role-with-saml/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
variable "create_role" {
description = "Whether to create a role"
type = bool
default = false
}

variable "provider_id" {
description = "ID of the SAML Provider. Use provider_ids to specify several IDs."
type = string
default = ""
}

variable "provider_ids" {
description = "List of SAML Provider IDs"
type = list(string)
default = []
}

variable "aws_saml_endpoint" {
description = "AWS SAML Endpoint"
default = "https://signin.aws.amazon.com/saml"
type = string
}

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 = null
}

variable "role_name_prefix" {
description = "IAM role name prefix"
type = string
default = null
}

variable "role_description" {
description = "IAM Role description"
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 "number_of_role_policy_arns" {
description = "Number of IAM policies to attach to IAM role"
type = number
default = null
}

variable "force_detach_policies" {
description = "Whether policies should be detached from this role when destroying"
type = bool
default = false
}
7 changes: 7 additions & 0 deletions modules/iam-assumable-role-with-saml/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
terraform {
required_version = ">= 0.12.6"

required_providers {
aws = ">= 2.23"
}
}