Commit 3c6333c9 authored by Anton Babenko's avatar Anton Babenko Committed by GitHub

Added iam-group-with-assumable-roles-policy and iam-assumable-role (#18)

* Added iam-group-with-assumable-roles-policy and iam-assumable-role

* Minor fixes
parent fec4895c
......@@ -12,6 +12,11 @@ These types of resources are supported:
* [IAM access key](https://www.terraform.io/docs/providers/aws/r/iam_access_key.html)
* [IAM SSH public key](https://www.terraform.io/docs/providers/aws/r/iam_user_ssh_key.html)
## Features
1. **Cross-account access.** Define IAM roles using `iam_assumable_role` or `iam_assumable_roles` submodules in "resource AWS accounts (prod, staging, dev)" and IAM groups and users using `iam-group-with-assumable-roles-policy` submodule in "IAM AWS Account" to setup access controls between accounts. See [iam-group-with-assumable-roles-policy example](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-group-with-assumable-roles-policy) for more details.
1. **Individual IAM resources (users, roles, policies).** See usage snippets and [examples](https://github.com/terraform-aws-modules/terraform-aws-iam#examples) listed below.
## Usage
`iam-account`:
......@@ -27,6 +32,28 @@ module "iam_account" {
}
```
`iam-assumable-role`:
```hcl
module "iam_assumable_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
]
create_role = true
role_name = "custom"
role_requires_mfa = true
custom_role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonCognitoReadOnly",
"arn:aws:iam::aws:policy/AlexaForBusinessFullAccess",
]
}
```
`iam-assumable-roles`:
```hcl
module "iam_assumable_roles" {
......@@ -89,42 +116,55 @@ EOF
`iam-group-with-assumable-roles-policy`:
```hcl
# todo
module "iam_group_with_assumable_roles_policy" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-assumable-roles-policy"
name = "production-readonly"
assumable_roles = [
"arn:aws:iam::835367859855:role/readonly" # these roles can be created using `iam_assumable_roles` submodule
]
group_users = [
"user1",
"user2"
]
}
```
## IAM Best Practices
AWS published [IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) and this Terraform module was created to help with some of points listed there:
### Create Individual IAM Users
### 1. Create Individual IAM Users
Use [iam-user module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-user) module to manage IAM users.
### Use AWS Defined Policies to Assign Permissions Whenever Possible
### 2. Use AWS Defined Policies to Assign Permissions Whenever Possible
Use [iam-assumable-roles module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-roles) to create IAM roles with managed policies to support common tasks (admin, poweruser or readonly).
### Use Groups to Assign Permissions to IAM Users
### 3. Use Groups to Assign Permissions to IAM Users
Use [iam-group-with-assumable-roles-policy module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-group-with-assumable-roles-policy) to manage IAM groups of users who can assume roles.
### Configure a Strong Password Policy for Your Users
### 4. Configure a Strong Password Policy for Your Users
Use [iam-account module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-account) to set password policy for your IAM users.
### Enable MFA for Privileged Users
### 5. Enable MFA for Privileged Users
Terraform can't configure MFA for the user. It is only possible via [AWS Console](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa.html) and [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/iam/enable-mfa-device.html).
### Delegate by Using Roles Instead of by Sharing Credentials
### 6. Delegate by Using Roles Instead of by Sharing Credentials
[iam-assumable-roles](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-roles) and [iam-group-with-assumable-roles-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-group-with-assumable-roles-policy) modules provide complete set of functionality required for this.
[iam-assumable-role](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-role), [iam-assumable-roles](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-roles) and [iam-group-with-assumable-roles-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-group-with-assumable-roles-policy) modules provide complete set of functionality required for this.
### Use Policy Conditions for Extra Security
### 7. Use Policy Conditions for Extra Security
[iam-assumable-roles module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-roles) can be configured to require valid MFA token when different roles are assumed (for example, admin role requires MFA, but readonly - does not).
### Create IAM Policies
### 8. Create IAM Policies
Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-policy) module to manage IAM policy.
......@@ -132,8 +172,10 @@ Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-i
* [complete](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/complete) - Create all required resources to allow one group of users to assume privileged role, while another group of users can only assume readonly role.
* [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-roles](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-roles) - Create IAM roles which can be assumed from specified ARNs (AWS accounts, IAM users, etc)
* [iam-user](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-user) - Add IAM user, login profile and access keys
* [iam-assumable-role](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-assumable-roles) - Create individual IAM role which can be assumed from specified ARNs (AWS accounts, IAM users, etc)
* [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-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
* [iam-user](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-user) - Add IAM user, login profile and access keys (with PGP enabled or disabled)
* [iam-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-policy) - Create IAM policy
## Authors
......
# 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 -->
provider "aws" {
region = "eu-west-1"
}
###############################
# IAM assumable role for admin
###############################
module "iam_assumable_role_admin" {
source = "../../modules/iam-assumable-role"
trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
]
create_role = true
role_name = "admin"
role_requires_mfa = true
attach_admin_policy = true
}
##########################################
# IAM assumable role with custom policies
##########################################
module "iam_assumable_role_custom" {
source = "../../modules/iam-assumable-role"
trusted_role_arns = [
"arn:aws:iam::307990089504:root",
]
create_role = true
role_name = "custom"
role_requires_mfa = true
custom_role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonCognitoReadOnly",
"arn:aws:iam::aws:policy/AlexaForBusinessFullAccess",
]
}
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}"
}
output "role_requires_mfa" {
description = "Whether admin IAM role requires MFA"
value = "${module.iam_assumable_role_admin.role_requires_mfa}"
}
# IAM group with assumable roles policy example
Configuration in this directory creates IAM group with users who are allowed to assume IAM roles.
# 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 |
|------|-------------|
| iam\_account\_id | IAM AWS account id (this code is managing resources in this account) |
| production\_account\_id | Production AWS account id |
| this\_assumable\_roles | List of ARNs of IAM roles which members of IAM group can assume |
| this\_group\_users | List of IAM users in IAM group |
| this\_policy\_arn | Assume role policy ARN for IAM group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" {
region = "eu-west-1"
}
provider "aws" {
region = "eu-west-1"
assume_role {
role_arn = "arn:aws:iam::835367859851:role/anton-demo"
}
alias = "production"
}
data "aws_caller_identity" "iam" {}
data "aws_caller_identity" "production" {
provider = "aws.production"
}
############
# IAM users
############
module "iam_user1" {
source = "../../modules/iam-user"
name = "user1"
create_iam_user_login_profile = false
create_iam_access_key = false
}
module "iam_user2" {
source = "../../modules/iam-user"
name = "user2"
create_iam_user_login_profile = false
create_iam_access_key = false
}
#####################################################################################
# Several IAM assumable roles (admin, poweruser, readonly) in production AWS account
# Note: Anyone from IAM account can assume them.
#####################################################################################
module "iam_assumable_roles_in_prod" {
source = "../../modules/iam-assumable-roles"
trusted_role_arns = [
"arn:aws:iam::${data.aws_caller_identity.iam.account_id}:root",
]
create_admin_role = true
create_poweruser_role = true
create_readonly_role = true
readonly_role_requires_mfa = false
providers = {
aws = "aws.production"
}
}
module "iam_assumable_role_custom" {
source = "../../modules/iam-assumable-role"
trusted_role_arns = [
"arn:aws:iam::${data.aws_caller_identity.iam.account_id}:root",
]
create_role = true
role_name = "custom"
role_requires_mfa = true
custom_role_policy_arns = [
"arn:aws:iam::aws:policy/AmazonCognitoReadOnly",
"arn:aws:iam::aws:policy/AlexaForBusinessFullAccess",
]
providers = {
aws = "aws.production"
}
}
################################################################################################
# IAM group where user1 and user2 are allowed to assume readonly role in production AWS account
# Note: IAM AWS account is default, so there is no need to specify it here.
################################################################################################
module "iam_group_with_assumable_roles_policy_production_readonly" {
source = "../../modules/iam-group-with-assumable-roles-policy"
name = "production-readonly"
assumable_roles = ["${module.iam_assumable_roles_in_prod.readonly_iam_role_arn}"]
group_users = [
"${module.iam_user1.this_iam_user_name}",
"${module.iam_user2.this_iam_user_name}",
]
}
################################################################################################
# IAM group where user1 is allowed to assume admin role in production AWS account
# Note: IAM AWS account is default, so there is no need to specify it here.
################################################################################################
module "iam_group_with_assumable_roles_policy_production_admin" {
source = "../../modules/iam-group-with-assumable-roles-policy"
name = "production-admin"
assumable_roles = ["${module.iam_assumable_roles_in_prod.admin_iam_role_arn}"]
group_users = [
"${module.iam_user1.this_iam_user_name}",
]
}
################################################################################################
# IAM group where user2 is allowed to assume custom role in production AWS account
# Note: IAM AWS account is default, so there is no need to specify it here.
################################################################################################
module "iam_group_with_assumable_roles_policy_production_custom" {
source = "../../modules/iam-group-with-assumable-roles-policy"
name = "production-custom"
assumable_roles = ["${module.iam_assumable_role_custom.this_iam_role_arn}"]
group_users = [
"${module.iam_user2.this_iam_user_name}",
]
}
output "iam_account_id" {
description = "IAM AWS account id (this code is managing resources in this account)"
value = "${data.aws_caller_identity.iam.account_id}"
}
output "production_account_id" {
description = "Production AWS account id"
value = "${data.aws_caller_identity.production.account_id}"
}
output "this_group_users" {
description = "List of IAM users in IAM group"
value = ["${module.iam_group_with_assumable_roles_policy_production_readonly.this_group_users}"]
}
output "this_assumable_roles" {
description = "List of ARNs of IAM roles which members of IAM group can assume"
value = ["${module.iam_group_with_assumable_roles_policy_production_readonly.this_assumable_roles}"]
}
output "this_policy_arn" {
description = "Assume role policy ARN for IAM group"
value = "${module.iam_group_with_assumable_roles_policy_production_readonly.this_policy_arn}"
}
......@@ -28,6 +28,7 @@ Run `terraform destroy` when you don't need these resources.
| this\_iam\_access\_key\_encrypted\_secret | The encrypted secret, base64 encoded |
| this\_iam\_access\_key\_id | The access key ID |
| this\_iam\_access\_key\_key\_fingerprint | The fingerprint of the PGP key used to encrypt the secret |
| this\_iam\_access\_key\_secret | The access key secret |
| this\_iam\_access\_key\_ses\_smtp\_password | The secret access key converted into an SES SMTP password |
| this\_iam\_access\_key\_status | Active or Inactive. Keys are initially active, but can be made inactive by other means. |
| this\_iam\_user\_arn | The ARN assigned by AWS for this user |
......
......@@ -21,3 +21,15 @@ module "iam_user" {
ssh_public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0sUjdTEcOWYgQ7ESnHsSkvPUO2tEvZxxQHUZYh9j6BPZgfn13iYhfAP2cfZznzrV+2VMamMtfiAiWR39LKo/bMN932HOp2Qx2la14IbiZ91666FD+yZ4+vhR2IVhZMe4D+g8FmhCfw1+zZhgl8vQBgsRZIcYqpYux59FcPv0lP1EhYahoRsUt1SEU2Gj+jvgyZpe15lnWk2VzfIpIsZ++AeUqyHoJHV0RVOK4MLRssqGHye6XkA3A+dMm2Mjgi8hxoL5uuwtkIsAll0kSfL5O2G26nsxm/Fpcl+SKSO4gs01d9V83xiOwviyOxmoXzwKy4qaUGtgq1hWncDNIVG/aQ=="
}
###################################################################
# IAM user without pgp_key (IAM access secret will be unencrypted)
###################################################################
module "iam_user2" {
source = "../../modules/iam-user"
name = "vasya.pupkin4"
create_iam_user_login_profile = false
create_iam_access_key = true
}
......@@ -38,6 +38,11 @@ output "this_iam_access_key_encrypted_secret" {
value = "${module.iam_user.this_iam_access_key_encrypted_secret}"
}
output "this_iam_access_key_secret" {
description = "The access key secret"
value = "${module.iam_user.this_iam_access_key_secret}"
}
output "this_iam_access_key_ses_smtp_password" {
description = "The secret access key converted into an SES SMTP password"
value = "${module.iam_user.this_iam_access_key_ses_smtp_password}"
......
# iam-assumable-roles
Creates single IAM role which can be assumed by trusted resources.
Trusted resources can be any [IAM ARNs](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns) - typically, AWS accounts and users.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| admin\_role\_policy\_arn | Policy ARN to use for admin role | string | `"arn:aws:iam::aws:policy/AdministratorAccess"` | no |
| attach\_admin\_policy | Whether to attach an admin policy to a role | string | `"false"` | no |
| attach\_poweruser\_policy | Whether to attach a poweruser policy to a role | string | `"false"` | no |
| attach\_readonly\_policy | Whether to attach a readonly policy to a role | string | `"false"` | no |
| create\_role | Whether to create a role | string | `"false"` | no |
| custom\_role\_policy\_arns | List of ARNs of IAM policies to attach to IAM role | list | `[]` | no |
| max\_session\_duration | Maximum CLI/API session duration in seconds between 3600 and 43200 | string | `"3600"` | no |
| mfa\_age | Max age of valid MFA (in seconds) for roles which require MFA | string | `"86400"` | no |
| poweruser\_role\_policy\_arn | Policy ARN to use for poweruser role | string | `"arn:aws:iam::aws:policy/PowerUserAccess"` | no |
| readonly\_role\_policy\_arn | Policy ARN to use for readonly role | string | `"arn:aws:iam::aws:policy/ReadOnlyAccess"` | no |
| 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\_requires\_mfa | Whether role requires MFA | string | `"true"` | no |
| trusted\_role\_arns | ARNs of AWS entities who can assume these roles | list | `[]` | no |
## Outputs
| Name | Description |
|------|-------------|
| role\_requires\_mfa | Whether 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 -->
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = ["${var.trusted_role_arns}"]
}
}
}
data "aws_iam_policy_document" "assume_role_with_mfa" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = ["${var.trusted_role_arns}"]
}
condition {
test = "Bool"
variable = "aws:MultiFactorAuthPresent"
values = ["true"]
}
condition {
test = "NumericLessThan"
variable = "aws:MultiFactorAuthAge"
values = ["${var.mfa_age}"]
}
}
}
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 = "${var.role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json}"
}
resource "aws_iam_role_policy_attachment" "custom" {
count = "${var.create_role && length(var.custom_role_policy_arns) > 0 ? length(var.custom_role_policy_arns) : 0}"
role = "${aws_iam_role.this.name}"
policy_arn = "${element(var.custom_role_policy_arns, count.index)}"
}
resource "aws_iam_role_policy_attachment" "admin" {
count = "${var.create_role && var.attach_admin_policy ? 1 : 0}"
role = "${aws_iam_role.this.name}"
policy_arn = "${var.admin_role_policy_arn}"
}
resource "aws_iam_role_policy_attachment" "poweruser" {
count = "${var.create_role && var.attach_poweruser_policy ? 1 : 0}"
role = "${aws_iam_role.this.name}"
policy_arn = "${var.poweruser_role_policy_arn}"
}
resource "aws_iam_role_policy_attachment" "readonly" {
count = "${var.create_role && var.attach_readonly_policy ? 1 : 0}"
role = "${aws_iam_role.this.name}"
policy_arn = "${var.readonly_role_policy_arn}"
}
output "this_iam_role_arn" {
description = "ARN of IAM role"
value = "${element(concat(aws_iam_role.this.*.arn, list("")), 0)}"
}
output "this_iam_role_name" {
description = "Name of IAM role"
value = "${element(concat(aws_iam_role.this.*.name, list("")), 0)}"
}
output "this_iam_role_path" {
description = "Path of IAM role"
value = "${element(concat(aws_iam_role.this.*.path, list("")), 0)}"
}
output "role_requires_mfa" {
description = "Whether IAM role requires MFA"
value = "${var.role_requires_mfa}"
}
variable "trusted_role_arns" {
description = "ARNs of AWS entities who can assume these roles"
default = []
}
variable "mfa_age" {
description = "Max age of valid MFA (in seconds) for roles which require MFA"
default = 86400
}
variable "max_session_duration" {
description = "Maximum CLI/API session duration in seconds between 3600 and 43200"
default = 3600
}
variable "create_role" {
description = "Whether to create a role"
default = false
}
variable "role_name" {
description = "IAM role name"
default = ""
}
variable "role_path" {
description = "Path of IAM role"
default = "/"
}
variable "role_requires_mfa" {
description = "Whether role requires MFA"
default = true
}
variable "role_permissions_boundary_arn" {
description = "Permissions boundary ARN to use for IAM role"
default = ""
}
variable "custom_role_policy_arns" {
description = "List of ARNs of IAM policies to attach to IAM role"
default = []
}
# Pre-defined policies
variable "admin_role_policy_arn" {
description = "Policy ARN to use for admin role"
default = "arn:aws:iam::aws:policy/AdministratorAccess"
}
variable "poweruser_role_policy_arn" {
description = "Policy ARN to use for poweruser role"
default = "arn:aws:iam::aws:policy/PowerUserAccess"
}
variable "readonly_role_policy_arn" {
description = "Policy ARN to use for readonly role"
default = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
variable "attach_admin_policy" {
description = "Whether to attach an admin policy to a role"
default = false
}
variable "attach_poweruser_policy" {
description = "Whether to attach a poweruser policy to a role"
default = false
}
variable "attach_readonly_policy" {
description = "Whether to attach a readonly policy to a role"
default = false
}
......@@ -21,12 +21,12 @@ Trusted resources can be any [IAM ARNs](https://docs.aws.amazon.com/IAM/latest/U
| mfa\_age | Max age of valid MFA (in seconds) for roles which require MFA | string | `"86400"` | no |
| poweruser\_role\_name | IAM role with poweruser access | string | `"poweruser"` | no |
| poweruser\_role\_path | Path of poweruser IAM role | string | `"/"` | no |
| poweruser\_role\_permissions\_boundary\_arn | Permissions boundary ARN to use for admin role | string | `""` | no |
| poweruser\_role\_policy\_arn | Policy ARN to use for admin role | string | `"arn:aws:iam::aws:policy/PowerUserAccess"` | no |
| poweruser\_role\_permissions\_boundary\_arn | Permissions boundary ARN to use for poweruser role | string | `""` | no |
| poweruser\_role\_policy\_arn | Policy ARN to use for poweruser role | string | `"arn:aws:iam::aws:policy/PowerUserAccess"` | no |
| poweruser\_role\_requires\_mfa | Whether poweruser role requires MFA | string | `"true"` | no |
| readonly\_role\_name | IAM role with readonly access | string | `"readonly"` | no |
| readonly\_role\_path | Path of readonly IAM role | string | `"/"` | no |
| readonly\_role\_permissions\_boundary\_arn | Permissions boundary ARN to use for admin role | string | `""` | no |
| readonly\_role\_permissions\_boundary\_arn | Permissions boundary ARN to use for readonly role | string | `""` | no |
| readonly\_role\_policy\_arn | Policy ARN to use for readonly role | string | `"arn:aws:iam::aws:policy/ReadOnlyAccess"` | no |
| readonly\_role\_requires\_mfa | Whether readonly role requires MFA | string | `"true"` | no |
| trusted\_role\_arns | ARNs of AWS entities who can assume these roles | list | `[]` | no |
......
......@@ -61,12 +61,12 @@ variable "poweruser_role_requires_mfa" {
}
variable "poweruser_role_policy_arn" {
description = "Policy ARN to use for admin role"
description = "Policy ARN to use for poweruser role"
default = "arn:aws:iam::aws:policy/PowerUserAccess"
}
variable "poweruser_role_permissions_boundary_arn" {
description = "Permissions boundary ARN to use for admin role"
description = "Permissions boundary ARN to use for poweruser role"
default = ""
}
......@@ -97,7 +97,7 @@ variable "readonly_role_policy_arn" {
}
variable "readonly_role_permissions_boundary_arn" {
description = "Permissions boundary ARN to use for admin role"
description = "Permissions boundary ARN to use for readonly role"
default = ""
}
......
# iam-group-with-assumable-roles-policy
Creates IAM group with users who are allowed to assume IAM roles. This is typically done in resource AWS account where IAM users can jump into from IAM AWS account.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| assumable\_roles | List of IAM roles ARNs which can be assumed by the group | list | `[]` | no |
| group\_users | List of IAM users to have in an IAM group which can assume the role | list | `[]` | no |
| name | Name of IAM policy and IAM group | string | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| this\_assumable\_roles | List of ARNs of IAM roles which members of IAM group can assume |
| this\_group\_users | List of IAM users in IAM group |
| this\_policy\_arn | Assume role policy ARN of IAM group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
resources = ["${var.assumable_roles}"]
}
}
resource "aws_iam_policy" "this" {
name = "${var.name}"
description = "Allows to assume role in another AWS account"
policy = "${data.aws_iam_policy_document.assume_role.json}"
}
resource "aws_iam_group" "this" {
name = "${var.name}"
}
resource "aws_iam_group_policy_attachment" "this" {
group = "${aws_iam_group.this.id}"
policy_arn = "${aws_iam_policy.this.id}"
}
resource "aws_iam_group_membership" "this" {
count = "${length(var.group_users) > 0 ? 1 : 0}"
group = "${aws_iam_group.this.id}"
name = "${var.name}"
users = ["${var.group_users}"]
}
output "this_group_users" {
description = "List of IAM users in IAM group"
value = ["${split(",", join(",", flatten(aws_iam_group_membership.this.*.users)))}"]
}
output "this_assumable_roles" {
description = "List of ARNs of IAM roles which members of IAM group can assume"
value = ["${var.assumable_roles}"]
}
output "this_policy_arn" {
description = "Assume role policy ARN of IAM group"
value = "${aws_iam_policy.this.arn}"
}
variable "name" {
description = "Name of IAM policy and IAM group"
}
variable "assumable_roles" {
description = "List of IAM roles ARNs which can be assumed by the group"
default = []
}
variable "group_users" {
description = "List of IAM users to have in an IAM group which can assume the role"
default = []
}
......@@ -49,6 +49,7 @@ This module outputs commands and PGP messages which can be decrypted either usin
| this\_iam\_access\_key\_encrypted\_secret | The encrypted secret, base64 encoded |
| this\_iam\_access\_key\_id | The access key ID |
| this\_iam\_access\_key\_key\_fingerprint | The fingerprint of the PGP key used to encrypt the secret |
| this\_iam\_access\_key\_secret | The access key secret |
| this\_iam\_access\_key\_ses\_smtp\_password | The secret access key converted into an SES SMTP password |
| this\_iam\_access\_key\_status | Active or Inactive. Keys are initially active, but can be made inactive by other means. |
| this\_iam\_user\_arn | The ARN assigned by AWS for this user |
......
resource "aws_iam_user" "this" {
count = "${var.create_user}"
count = "${var.create_user ? 1 : 0}"
name = "${var.name}"
path = "${var.path}"
......@@ -17,12 +17,18 @@ resource "aws_iam_user_login_profile" "this" {
}
resource "aws_iam_access_key" "this" {
count = "${var.create_user && var.create_iam_access_key ? 1 : 0}"
count = "${var.create_user && var.create_iam_access_key && var.pgp_key != "" ? 1 : 0}"
user = "${aws_iam_user.this.name}"
pgp_key = "${var.pgp_key}"
}
resource "aws_iam_access_key" "this_no_pgp" {
count = "${var.create_user && var.create_iam_access_key && var.pgp_key == "" ? 1 : 0}"
user = "${aws_iam_user.this.name}"
}
resource "aws_iam_user_ssh_key" "this" {
count = "${var.create_user && var.upload_iam_user_ssh_key ? 1 : 0}"
......
......@@ -25,7 +25,12 @@ output "this_iam_user_login_profile_encrypted_password" {
output "this_iam_access_key_id" {
description = "The access key ID"
value = "${element(concat(aws_iam_access_key.this.*.id, list("")), 0)}"
value = "${element(concat(aws_iam_access_key.this.*.id, aws_iam_access_key.this_no_pgp.*.id, list("")), 0)}"
}
output "this_iam_access_key_secret" {
description = "The access key secret"
value = "${element(concat(aws_iam_access_key.this_no_pgp.*.secret, list("")), 0)}"
}
output "this_iam_access_key_key_fingerprint" {
......@@ -40,12 +45,12 @@ output "this_iam_access_key_encrypted_secret" {
output "this_iam_access_key_ses_smtp_password" {
description = "The secret access key converted into an SES SMTP password"
value = "${element(concat(aws_iam_access_key.this.*.ses_smtp_password, list("")), 0)}"
value = "${element(concat(aws_iam_access_key.this.*.ses_smtp_password, aws_iam_access_key.this_no_pgp.*.ses_smtp_password, list("")), 0)}"
}
output "this_iam_access_key_status" {
description = "Active or Inactive. Keys are initially active, but can be made inactive by other means."
value = "${element(concat(aws_iam_access_key.this.*.status, list("")), 0)}"
value = "${element(concat(aws_iam_access_key.this.*.status, aws_iam_access_key.this_no_pgp.*.status, list("")), 0)}"
}
output "pgp_key" {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment