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

Added iam-assumable-roles #2

Merged
merged 2 commits into from
Feb 12, 2018
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
111 changes: 103 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,103 @@
# terraform-aws-iam
Terraform module which creates IAM resources on AWS

- [ ] IAM account
- [ ] IAM groups
- [ ] IAM users
- [ ] IAM assumable roles
- [ ] IAM group with assumable roles policy
# AWS Identity and Access Management (IAM) Terraform module

These types of resources are supported:

* [IAM account alias](https://www.terraform.io/docs/providers/aws/r/iam_account_alias.html)
* [IAM password policy](https://www.terraform.io/docs/providers/aws/r/iam_account_password_policy.html)
* [IAM user](https://www.terraform.io/docs/providers/aws/r/iam_user.html)
* [IAM user login profile](https://www.terraform.io/docs/providers/aws/r/iam_user_login_profile.html)
* [IAM group](https://www.terraform.io/docs/providers/aws/r/iam_group.html)
* [IAM role](https://www.terraform.io/docs/providers/aws/r/iam_role.html)

## Usage

`iam-account`:

```hcl
module "iam_account" {
source = "terraform-aws-modules/iam/aws//modules/iam-account"

account_alias = "awesome-company"

minimum_password_length = 37
require_numbers = false
}
```

`iam-assumable-roles`:
```hcl
module "iam_assumable_roles" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-roles"

trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
]

create_admin_role = true

create_poweruser_role = true
poweruser_role_name = "developer"

create_readonly_role = true
readonly_role_requires_mfa = false
}
```

`iam-user`:
```hcl
# todo
```

`iam-group-with-assumable-roles-policy`:
```hcl
# todo
```

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

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

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

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

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

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

[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

[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).


## Examples

* [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/modules/iam-account) - Set AWS account alias and password policy
* [iam-assumable-roles](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-assumable-roles) - Create IAM roles which can be assumed from specified ARNs (AWS accounts, IAM users, etc)


## Authors

Module managed by [Anton Babenko](https://github.com/antonbabenko).

## License

Apache 2 Licensed. See LICENSE for full details.
12 changes: 4 additions & 8 deletions examples/iam-account/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
HTTP Security Group example
===========================
# IAM account example

Configuration in this directory creates set of Security Group and Security Group Rules resources in various combination.
Configuration in this directory sets [AWS account alias](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html) (also known as Console Account alias) and configures password policy.

Data sources are used to discover existing VPC resources (VPC and default security group).

Usage
=====
# Usage

To run this example you need to execute:

Expand All @@ -16,4 +12,4 @@ $ terraform plan
$ terraform apply
```

Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
Run `terraform destroy` when you don't need these resources.
15 changes: 15 additions & 0 deletions examples/iam-assumable-roles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# IAM assumable roles example

Configuration in this directory creates several 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).

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

######################
# IAM assumable roles
######################
module "iam_assumable_roles" {
source = "../../modules/iam-assumable-roles"

trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
]

create_admin_role = true

create_poweruser_role = true
poweruser_role_name = "developer"

create_readonly_role = true
readonly_role_requires_mfa = false
}
62 changes: 62 additions & 0 deletions examples/iam-assumable-roles/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Admin
output "admin_iam_role_arn" {
description = "ARN of admin IAM role"
value = "${module.iam_assumable_roles.admin_iam_role_arn}"
}

output "admin_iam_role_name" {
description = "Name of admin IAM role"
value = "${module.iam_assumable_roles.admin_iam_role_name}"
}

output "admin_iam_role_requires_mfa" {
description = "Whether admin IAM role requires MFA"
value = "${module.iam_assumable_roles.admin_iam_role_requires_mfa}"
}

output "admin_iam_role_path" {
description = "Path of admin IAM role"
value = "${module.iam_assumable_roles.admin_iam_role_path}"
}

# Poweruser
output "poweruser_iam_role_arn" {
description = "ARN of poweruser IAM role"
value = "${module.iam_assumable_roles.poweruser_iam_role_arn}"
}

output "poweruser_iam_role_name" {
description = "Name of poweruser IAM role"
value = "${module.iam_assumable_roles.poweruser_iam_role_name}"
}

output "poweruser_iam_role_requires_mfa" {
description = "Whether poweruser IAM role requires MFA"
value = "${module.iam_assumable_roles.poweruser_iam_role_requires_mfa}"
}

output "poweruser_iam_role_path" {
description = "Path of poweruser IAM role"
value = "${module.iam_assumable_roles.poweruser_iam_role_path}"
}

# Readonly
output "readonly_iam_role_arn" {
description = "ARN of readonly IAM role"
value = "${module.iam_assumable_roles.readonly_iam_role_arn}"
}

output "readonly_iam_role_name" {
description = "Name of readonly IAM role"
value = "${module.iam_assumable_roles.readonly_iam_role_name}"
}

output "readonly_iam_role_path" {
description = "Path of readonly IAM role"
value = "${module.iam_assumable_roles.readonly_iam_role_path}"
}

output "readonly_iam_role_requires_mfa" {
description = "Whether readonly IAM role requires MFA"
value = "${module.iam_assumable_roles.readonly_iam_role_requires_mfa}"
}
5 changes: 5 additions & 0 deletions modules/iam-assumable-roles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# iam-assumable-roles

Creates predefined IAM roles (admin, poweruser and readonly) 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.
76 changes: 76 additions & 0 deletions modules/iam-assumable-roles/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
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}"]
}
}
}

# Admin
resource "aws_iam_role" "admin" {
name = "${var.admin_role_name}"
path = "${var.admin_role_path}"

assume_role_policy = "${var.admin_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" "admin" {
role = "${aws_iam_role.admin.name}"
policy_arn = "${var.admin_role_policy_arn}"
}

# Poweruser
resource "aws_iam_role_policy_attachment" "poweruser" {
role = "${aws_iam_role.poweruser.name}"
policy_arn = "${var.poweruser_role_policy_arn}"
}

resource "aws_iam_role" "poweruser" {
name = "${var.poweruser_role_name}"
path = "${var.poweruser_role_path}"

assume_role_policy = "${var.poweruser_role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json}"
}

# Readonly
resource "aws_iam_role_policy_attachment" "readonly" {
role = "${aws_iam_role.readonly.name}"
policy_arn = "${var.readonly_role_policy_arn}"
}

resource "aws_iam_role" "readonly" {
name = "${var.readonly_role_name}"
path = "${var.readonly_role_path}"

assume_role_policy = "${var.readonly_role_requires_mfa ? data.aws_iam_policy_document.assume_role_with_mfa.json : data.aws_iam_policy_document.assume_role.json}"
}
62 changes: 62 additions & 0 deletions modules/iam-assumable-roles/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#Admin
output "admin_iam_role_arn" {
description = "ARN of admin IAM role"
value = "${element(concat(aws_iam_role.admin.*.arn, list()), 0)}"
}

output "admin_iam_role_name" {
description = "Name of admin IAM role"
value = "${element(concat(aws_iam_role.admin.*.name, list()), 0)}"
}

output "admin_iam_role_path" {
description = "Path of admin IAM role"
value = "${element(concat(aws_iam_role.admin.*.path, list()), 0)}"
}

output "admin_iam_role_requires_mfa" {
description = "Whether admin IAM role requires MFA"
value = "${var.admin_role_requires_mfa}"
}

# Poweruser
output "poweruser_iam_role_arn" {
description = "ARN of poweruser IAM role"
value = "${element(concat(aws_iam_role.poweruser.*.arn, list()), 0)}"
}

output "poweruser_iam_role_name" {
description = "Name of poweruser IAM role"
value = "${element(concat(aws_iam_role.poweruser.*.name, list()), 0)}"
}

output "poweruser_iam_role_path" {
description = "Path of poweruser IAM role"
value = "${element(concat(aws_iam_role.poweruser.*.path, list()), 0)}"
}

output "poweruser_iam_role_requires_mfa" {
description = "Whether poweruser IAM role requires MFA"
value = "${var.poweruser_role_requires_mfa}"
}

# Readonly
output "readonly_iam_role_arn" {
description = "ARN of readonly IAM role"
value = "${element(concat(aws_iam_role.readonly.*.arn, list()), 0)}"
}

output "readonly_iam_role_name" {
description = "Name of readonly IAM role"
value = "${element(concat(aws_iam_role.readonly.*.name, list()), 0)}"
}

output "readonly_iam_role_path" {
description = "Path of readonly IAM role"
value = "${element(concat(aws_iam_role.readonly.*.path, list()), 0)}"
}

output "readonly_iam_role_requires_mfa" {
description = "Whether readonly IAM role requires MFA"
value = "${var.readonly_role_requires_mfa}"
}
Loading