Commit e8c695d3 authored by Anton Babenko's avatar Anton Babenko

Added iam-group-with-policies and iam-group-complete

parent 3c6333c9
...@@ -20,7 +20,6 @@ These types of resources are supported: ...@@ -20,7 +20,6 @@ These types of resources are supported:
## Usage ## Usage
`iam-account`: `iam-account`:
```hcl ```hcl
module "iam_account" { module "iam_account" {
source = "terraform-aws-modules/iam/aws//modules/iam-account" source = "terraform-aws-modules/iam/aws//modules/iam-account"
...@@ -132,6 +131,33 @@ module "iam_group_with_assumable_roles_policy" { ...@@ -132,6 +131,33 @@ module "iam_group_with_assumable_roles_policy" {
} }
``` ```
`iam-group-with-policies`:
```hcl
module "iam_group_with_policies" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
name = "superadmins"
group_users = [
"user1",
"user2"
]
attach_iam_self_management_policy = true
custom_group_policy_arns = [
"arn:aws:iam::aws:policy/AdministratorAccess",
]
custom_group_policies = [
{
name = "AllowS3Listing"
policy = "${data.aws_iam_policy_document.sample.json}"
}
]
}
```
## IAM Best Practices ## 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: 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:
...@@ -148,6 +174,8 @@ Use [iam-assumable-roles module](https://github.com/terraform-aws-modules/terraf ...@@ -148,6 +174,8 @@ Use [iam-assumable-roles module](https://github.com/terraform-aws-modules/terraf
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. 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.
Use [iam-group-with-policies module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-group-with-policies) to manage IAM groups of users where specified IAM policies are allowed.
### 4. 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. 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.
...@@ -175,6 +203,8 @@ Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-i ...@@ -175,6 +203,8 @@ Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-i
* [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-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-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-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-group-with-policies](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-group-with-policies) - IAM group with users who are allowed specified IAM policies (eg, "manage their own IAM user")
* [iam-group-complete](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-group-complete) - IAM group with users who are allowed to assume IAM roles in another AWS account and have access to specified IAM policies
* [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-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 * [iam-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-policy) - Create IAM policy
......
# Complete IAM group example
Configuration in this directory creates IAM group with users who are allowed to assume IAM roles and extended with IAM policies.
This is a combination of `iam-group-with-assumable-roles-policy` and `iam-group-with-policies` exampled.
# 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 |
|------|-------------|
| 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 -->
############
# 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
}
#############################################################################################
# IAM group where user1 and user2 are allowed to assume admin role in production AWS account
#############################################################################################
module "iam_group_complete" {
source = "../../modules/iam-group-with-assumable-roles-policy"
name = "production-admins"
assumable_roles = ["arn:aws:iam::111111111111:role/admin"]
group_users = [
"${module.iam_user1.this_iam_user_name}",
"${module.iam_user2.this_iam_user_name}",
]
}
####################################################
# Extending policies of IAM group production-admins
####################################################
module "iam_group_complete_with_custom_policy" {
source = "../../modules/iam-group-with-policies"
name = "${module.iam_group_complete.group_name}"
create_group = false
custom_group_policy_arns = [
"arn:aws:iam::aws:policy/AmazonS3FullAccess",
]
}
output "this_group_users" {
description = "List of IAM users in IAM group"
value = ["${module.iam_group_complete.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_complete.this_assumable_roles}"]
}
output "this_policy_arn" {
description = "Assume role policy ARN for IAM group"
value = "${module.iam_group_complete.this_policy_arn}"
}
# IAM group with policies example
Configuration in this directory creates IAM group with users who has specified IAM policies.
# 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\_group\_name | IAM group name |
| this\_group\_users | List of IAM users in IAM group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
############
# 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
}
#####################################################################################
# IAM group for superadmins with full Administrator access
#####################################################################################
module "iam_group_superadmins" {
source = "../../modules/iam-group-with-policies"
name = "superadmins"
group_users = [
"${module.iam_user1.this_iam_user_name}",
"${module.iam_user2.this_iam_user_name}",
]
custom_group_policy_arns = [
"arn:aws:iam::aws:policy/AdministratorAccess",
]
}
#####################################################################################
# IAM group for users with custom access
#####################################################################################
module "iam_group_with_custom_policies" {
source = "../../modules/iam-group-with-policies"
name = "custom"
group_users = [
"${module.iam_user1.this_iam_user_name}",
"${module.iam_user2.this_iam_user_name}",
]
custom_group_policy_arns = [
"arn:aws:iam::aws:policy/AmazonCognitoReadOnly",
"arn:aws:iam::aws:policy/AlexaForBusinessFullAccess",
]
custom_group_policies = [
{
name = "AllowS3Listing"
policy = "${data.aws_iam_policy_document.sample.json}"
},
]
}
######################
# IAM policy (sample)
######################
data "aws_iam_policy_document" "sample" {
statement {
actions = [
"s3:ListBuckets",
]
resources = ["*"]
}
}
output "iam_account_id" {
description = "IAM AWS account id"
value = "${module.iam_group_superadmins.aws_account_id}"
}
output "this_group_users" {
description = "List of IAM users in IAM group"
value = ["${module.iam_group_superadmins.this_group_users}"]
}
output "this_group_name" {
description = "IAM group name"
value = "${module.iam_group_superadmins.this_group_name}"
}
...@@ -15,6 +15,7 @@ Creates IAM group with users who are allowed to assume IAM roles. This is typica ...@@ -15,6 +15,7 @@ Creates IAM group with users who are allowed to assume IAM roles. This is typica
| Name | Description | | Name | Description |
|------|-------------| |------|-------------|
| group\_name | IAM group name |
| this\_assumable\_roles | List of ARNs of IAM roles which members of IAM group can assume | | 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\_group\_users | List of IAM users in IAM group |
| this\_policy\_arn | Assume role policy ARN of IAM group | | this\_policy\_arn | Assume role policy ARN of IAM group |
......
...@@ -12,3 +12,8 @@ output "this_policy_arn" { ...@@ -12,3 +12,8 @@ output "this_policy_arn" {
description = "Assume role policy ARN of IAM group" description = "Assume role policy ARN of IAM group"
value = "${aws_iam_policy.this.arn}" value = "${aws_iam_policy.this.arn}"
} }
output "group_name" {
description = "IAM group name"
value = "${aws_iam_group.this.name}"
}
# iam-group-with-policies
Creates IAM group with specified IAM policies, and add users into a group.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| attach\_iam\_self\_management\_policy | Whether to attach IAM policy which allows IAM users to manage their credentials and MFA | string | `"true"` | no |
| aws\_account\_id | AWS account id to use inside IAM policies. If empty, current AWS account ID will be used. | string | `""` | no |
| create\_group | Whether to create IAM group | string | `"true"` | no |
| custom\_group\_policies | List of maps of inline IAM policies to attach to IAM group. Should have `name` and `policy` keys in each element. | list | `[]` | no |
| custom\_group\_policy\_arns | List of IAM policies ARNs to attach to IAM group | list | `[]` | no |
| group\_users | List of IAM users to have in an IAM group which can assume the role | list | `[]` | no |
| iam\_self\_management\_policy\_name\_prefix | Name prefix for IAM policy to create with IAM self-management permissions | string | `"IAMSelfManagement-"` | no |
| name | Name of IAM group | string | `""` | no |
## Outputs
| Name | Description |
|------|-------------|
| aws\_account\_id | IAM AWS account id |
| this\_group\_name | IAM group name |
| this\_group\_users | List of IAM users in IAM group |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
locals {
group_name = "${element(concat(aws_iam_group.this.*.id, list(var.name)), 0)}"
}
resource "aws_iam_group" "this" {
count = "${var.create_group ? 1 : 0}"
name = "${var.name}"
}
resource "aws_iam_group_membership" "this" {
count = "${length(var.group_users) > 0 ? 1 : 0}"
group = "${local.group_name}"
name = "${var.name}"
users = ["${var.group_users}"]
}
################################
# IAM group policy attachements
################################
resource "aws_iam_group_policy_attachment" "iam_self_management" {
count = "${var.attach_iam_self_management_policy ? 1 : 0}"
group = "${local.group_name}"
policy_arn = "${aws_iam_policy.iam_self_management.arn}"
}
resource "aws_iam_group_policy_attachment" "custom_arns" {
count = "${length(var.custom_group_policy_arns) > 0 ? length(var.custom_group_policy_arns) : 0}"
group = "${local.group_name}"
policy_arn = "${element(var.custom_group_policy_arns, count.index)}"
}
resource "aws_iam_group_policy_attachment" "custom" {
count = "${length(var.custom_group_policies) > 0 ? length(var.custom_group_policies) : 0}"
group = "${local.group_name}"
policy_arn = "${element(aws_iam_policy.custom.*.arn, count.index)}"
}
###############
# IAM policies
###############
resource "aws_iam_policy" "iam_self_management" {
count = "${var.attach_iam_self_management_policy ? 1 : 0}"
name_prefix = "${var.iam_self_management_policy_name_prefix}"
policy = "${data.aws_iam_policy_document.iam_self_management.json}"
}
resource "aws_iam_policy" "custom" {
count = "${length(var.custom_group_policies) > 0 ? length(var.custom_group_policies) : 0}"
name = "${lookup(var.custom_group_policies[count.index], "name")}"
policy = "${lookup(var.custom_group_policies[count.index], "policy")}"
}
output "aws_account_id" {
description = "IAM AWS account id"
value = "${local.aws_account_id}"
}
output "this_group_users" {
description = "List of IAM users in IAM group"
value = ["${split(",", join(",", flatten(aws_iam_group_membership.this.*.users)))}"]
}
output "this_group_name" {
description = "IAM group name"
value = "${element(concat(aws_iam_group.this.*.name, list(var.name)), 0)}"
}
data "aws_caller_identity" "current" {
count = "${var.aws_account_id == "" ? 1 : 0}"
}
locals {
aws_account_id = "${element(concat(data.aws_caller_identity.current.*.account_id, list(var.aws_account_id)), 0)}"
}
data "aws_iam_policy_document" "iam_self_management" {
statement {
sid = "AllowSelfManagement"
effect = "Allow"
actions = [
"iam:ChangePassword",
"iam:CreateAccessKey",
"iam:CreateLoginProfile",
"iam:CreateVirtualMFADevice",
"iam:DeleteAccessKey",
"iam:DeleteLoginProfile",
"iam:DeleteVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GenerateCredentialReport",
"iam:GenerateServiceLastAccessedDetails",
"iam:Get*",
"iam:List*",
"iam:ResyncMFADevice",
"iam:UpdateAccessKey",
"iam:UpdateLoginProfile",
"iam:UpdateUser",
"iam:UploadSigningCertificate",
"iam:UploadSSHPublicKey",
]
# Allow for both users with "path" and without it
resources = [
"arn:aws:iam::${local.aws_account_id}:user/*/$${aws:username}",
"arn:aws:iam::${local.aws_account_id}:user/$${aws:username}",
"arn:aws:iam::${local.aws_account_id}:mfa/$${aws:username}",
]
}
statement {
sid = "AllowIAMReadOnly"
actions = [
"iam:Get*",
"iam:List*",
]
resources = ["*"]
effect = "Allow"
}
# Allow to deactivate MFA only when logging in with MFA
statement {
sid = "AllowDeactivateMFADevice"
effect = "Allow"
actions = [
"iam:DeactivateMFADevice",
]
# Allow for both users with "path" and without it
resources = [
"arn:aws:iam::${local.aws_account_id}:user/*/$${aws:username}",
"arn:aws:iam::${local.aws_account_id}:user/$${aws:username}",
"arn:aws:iam::${local.aws_account_id}:mfa/$${aws:username}",
]
condition = {
test = "Bool"
variable = "aws:MultiFactorAuthPresent"
values = ["true"]
}
condition = {
test = "NumericLessThan"
variable = "aws:MultiFactorAuthAge"
values = ["3600"]
}
}
}
variable "create_group" {
description = "Whether to create IAM group"
default = true
}
variable "name" {
description = "Name of IAM group"
default = ""
}
variable "group_users" {
description = "List of IAM users to have in an IAM group which can assume the role"
default = []
}
variable "custom_group_policy_arns" {
description = "List of IAM policies ARNs to attach to IAM group"
default = []
}
variable "custom_group_policies" {
description = "List of maps of inline IAM policies to attach to IAM group. Should have `name` and `policy` keys in each element."
default = []
}
variable "attach_iam_self_management_policy" {
description = "Whether to attach IAM policy which allows IAM users to manage their credentials and MFA"
default = true
}
variable "iam_self_management_policy_name_prefix" {
description = "Name prefix for IAM policy to create with IAM self-management permissions"
default = "IAMSelfManagement-"
}
variable "aws_account_id" {
description = "AWS account id to use inside IAM policies. If empty, current AWS account ID will be used."
default = ""
}
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