Skip to content

Commit

Permalink
feat: Added iam-read-only-policy module (#174)
Browse files Browse the repository at this point in the history
Co-authored-by: Anton Babenko <anton@antonbabenko.com>
  • Loading branch information
Andrey9kin and antonbabenko committed Jan 3, 2022
1 parent 9278e6f commit 392756f
Show file tree
Hide file tree
Showing 12 changed files with 448 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.58.0
rev: v1.62.3
hooks:
- id: terraform_fmt
- id: terraform_validate
Expand All @@ -23,6 +23,6 @@ repos:
- '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote'
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.1.0
hooks:
- id: check-merge-conflict
38 changes: 28 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
```hcl
module "iam_account" {
source = "terraform-aws-modules/iam/aws//modules/iam-account"
version = "~> 4.3"
version = "~> 4"
account_alias = "awesome-company"
Expand All @@ -26,7 +26,7 @@ module "iam_account" {
```hcl
module "iam_assumable_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
version = "~> 4.3"
version = "~> 4"
trusted_role_arns = [
"arn:aws:iam::307990089504:root",
Expand All @@ -51,7 +51,7 @@ module "iam_assumable_role" {
```hcl
module "iam_assumable_role_with_oidc" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
version = "~> 4.3"
version = "~> 4"
create_role = true
Expand All @@ -75,7 +75,7 @@ module "iam_assumable_role_with_oidc" {
```hcl
module "iam_assumable_role_with_saml" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-saml"
version = "~> 4.3"
version = "~> 4"
create_role = true
Expand All @@ -99,7 +99,7 @@ module "iam_assumable_role_with_saml" {
```hcl
module "iam_assumable_roles" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-roles"
version = "~> 4.3"
version = "~> 4"
trusted_role_arns = [
"arn:aws:iam::307990089504:root",
Expand All @@ -121,7 +121,7 @@ module "iam_assumable_roles" {
```hcl
module "iam_assumable_roles_with_saml" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-roles-with-saml"
version = "~> 4.3"
version = "~> 4"
create_admin_role = true
Expand All @@ -139,7 +139,7 @@ module "iam_assumable_roles_with_saml" {
```hcl
module "iam_user" {
source = "terraform-aws-modules/iam/aws//modules/iam-user"
version = "~> 4.3"
version = "~> 4"
name = "vasya.pupkin"
force_destroy = true
Expand All @@ -155,7 +155,7 @@ module "iam_user" {
```hcl
module "iam_policy" {
source = "terraform-aws-modules/iam/aws//modules/iam-policy"
version = "~> 4.3"
version = "~> 4"
name = "example"
path = "/"
Expand All @@ -178,12 +178,27 @@ EOF
}
```

`iam-read-only-policy`:

```hcl
module "iam_read_only_policy" {
source = "terraform-aws-modules/iam/aws//modules/iam-read-only-policy"
version = "~> 4"
name = "example"
path = "/"
description = "My example read-only policy"
allowed_services = ["rds", "dynamo", "health"]
}
```

`iam-group-with-assumable-roles-policy`:

```hcl
module "iam_group_with_assumable_roles_policy" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-assumable-roles-policy"
version = "~> 4.3"
version = "~> 4"
name = "production-readonly"
Expand All @@ -203,7 +218,7 @@ module "iam_group_with_assumable_roles_policy" {
```hcl
module "iam_group_with_policies" {
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
version = "~> 4.3"
version = "~> 4"
name = "superadmins"
Expand Down Expand Up @@ -265,6 +280,8 @@ Terraform can't configure MFA for the user. It is only possible via [AWS Console

Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-policy) module to manage IAM policy.

Use [iam-read-only-policy module](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/modules/iam-read-only-policy) module to manage IAM read-only policies.

## Examples

- [iam-account](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-account) - Set AWS account alias and password policy
Expand All @@ -278,6 +295,7 @@ Use [iam-policy module](https://github.com/terraform-aws-modules/terraform-aws-i
- [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-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-policy) - Create IAM policy
- [iam-read-only-policy](https://github.com/terraform-aws-modules/terraform-aws-iam/tree/master/examples/iam-read-only-policy) - Create IAM read-only policy

## Authors

Expand Down
59 changes: 59 additions & 0 deletions examples/iam-read-only-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# IAM read-only policy example

Configuration in this directory creates read-only IAM policy and attaches it to AWS SSO.

# 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 |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.23 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.23 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_read_only_iam_policy"></a> [read\_only\_iam\_policy](#module\_read\_only\_iam\_policy) | ../../modules/iam-read-only-policy | n/a |
| <a name="module_read_only_iam_policy_doc"></a> [read\_only\_iam\_policy\_doc](#module\_read\_only\_iam\_policy\_doc) | ../../modules/iam-read-only-policy | n/a |

## Resources

| Name | Type |
|------|------|
| [aws_ssoadmin_permission_set.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set) | resource |
| [aws_ssoadmin_permission_set_inline_policy.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set_inline_policy) | resource |

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN assigned by AWS to this policy |
| <a name="output_description"></a> [description](#output\_description) | The description of the policy |
| <a name="output_id"></a> [id](#output\_id) | The policy ID |
| <a name="output_name"></a> [name](#output\_name) | The name of the policy |
| <a name="output_path"></a> [path](#output\_path) | The path of the policy in IAM |
| <a name="output_policy"></a> [policy](#output\_policy) | The policy document |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
66 changes: 66 additions & 0 deletions examples/iam-read-only-policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
provider "aws" {
region = "eu-west-1"
}

locals {
allowed_services_compute = ["ec2", "ecr", "eks", "ecs", "lambda", "autoscaling", "elasticloadbalancing"]
allowed_services_networking = ["vpc", "route53", "route53domains", "route53resolver", "servicediscovery"]
allowed_services_storage = ["s3", "backup", "dynamo", "dms", "elasticfilesystem"]
allowed_services_databases = ["rds", "dynamo", "elasticache"]
allowed_services_management = ["cloudwatch", "events", "logs", "servicequotas", "ssm"]
allowed_services_analytics = ["es", "firehose", "kinesis", "kinesisanalytics", "redshift"]
allowed_services_application = ["ses", "sns", "sqs", "xray", "applicationinsights", "application-autoscaling"]
allowed_services_security = ["iam", "acm", "kms", "secretsmanager"]

allowed_services = concat(
local.allowed_services_compute,
local.allowed_services_networking,
local.allowed_services_storage,
local.allowed_services_databases,
local.allowed_services_management,
local.allowed_services_analytics,
local.allowed_services_application,
local.allowed_services_security
)
}

module "read_only_iam_policy" {
source = "../../modules/iam-read-only-policy"

name = "example"
path = "/"
description = "My read only example policy"

allowed_services = local.allowed_services

tags = {
PolicyDescription = "My read only example policy"
}
}

module "read_only_iam_policy_doc" {
source = "../../modules/iam-read-only-policy"

name = "only-doc-example"
path = "/"
description = "My read only example policy"

create_policy = false

allowed_services = local.allowed_services

tags = {
PolicyDescription = "My read only example policy"
}
}

resource "aws_ssoadmin_permission_set" "example" {
name = "Example"
instance_arn = "arn:aws:sso:::instance/example"
}

resource "aws_ssoadmin_permission_set_inline_policy" "example" {
inline_policy = module.read_only_iam_policy_doc.policy_json
instance_arn = aws_ssoadmin_permission_set.example.instance_arn
permission_set_arn = aws_ssoadmin_permission_set.example.arn
}
29 changes: 29 additions & 0 deletions examples/iam-read-only-policy/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
output "id" {
description = "The policy ID"
value = module.read_only_iam_policy.id
}

output "arn" {
description = "The ARN assigned by AWS to this policy"
value = module.read_only_iam_policy.arn
}

output "description" {
description = "The description of the policy"
value = module.read_only_iam_policy.description
}

output "name" {
description = "The name of the policy"
value = module.read_only_iam_policy.name
}

output "path" {
description = "The path of the policy in IAM"
value = module.read_only_iam_policy.path
}

output "policy" {
description = "The policy document"
value = module.read_only_iam_policy.policy
}
Empty file.
7 changes: 7 additions & 0 deletions examples/iam-read-only-policy/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"
}
}
62 changes: 62 additions & 0 deletions modules/iam-read-only-policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# iam-read-only-policy

Creates IAM read-only policy for specified services. Default AWS read-only policies (arn:aws:iam::aws:policy/job-function/ViewOnlyAccess, arn:aws:iam::aws:policy/ReadOnlyAccess), being a one-size-fits-all type of policies, have a lot of things missing as well as something that you might not need. Also, AWS default policies are known for having [security issues](https://securityboulevard.com/2020/12/the-aws-managed-policies-trap/)
Thus this module is an attempt to build a better base for a customizable usable read-only policy.

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

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.23 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.23 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_iam_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy_document.allowed_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.console_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.logs_query](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.sts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_additional_policy_json"></a> [additional\_policy\_json](#input\_additional\_policy\_json) | JSON policy document if you want to add custom actions | `string` | `"{}"` | no |
| <a name="input_allow_cloudwatch_logs_query"></a> [allow\_cloudwatch\_logs\_query](#input\_allow\_cloudwatch\_logs\_query) | Allows StartQuery/StopQuery/FilterLogEvents CloudWatch actions | `bool` | `true` | no |
| <a name="input_allow_predefined_sts_actions"></a> [allow\_predefined\_sts\_actions](#input\_allow\_predefined\_sts\_actions) | Allows GetCallerIdentity/GetSessionToken/GetAccessKeyInfo sts actions | `bool` | `true` | no |
| <a name="input_allow_web_console_services"></a> [allow\_web\_console\_services](#input\_allow\_web\_console\_services) | Allows List/Get/Describe/View actions for services used when browsing AWS console (e.g. resource-groups, tag, health services) | `bool` | `true` | no |
| <a name="input_allowed_services"></a> [allowed\_services](#input\_allowed\_services) | List of services to allow Get/List/Describe/View options. Service name should be the same as corresponding service IAM prefix. See what it is for each service here https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html | `list(string)` | n/a | yes |
| <a name="input_create_policy"></a> [create\_policy](#input\_create\_policy) | Whether to create the IAM policy | `bool` | `true` | no |
| <a name="input_description"></a> [description](#input\_description) | The description of the policy | `string` | `"IAM Policy"` | no |
| <a name="input_name"></a> [name](#input\_name) | The name of the policy | `string` | `""` | no |
| <a name="input_path"></a> [path](#input\_path) | The path of the policy in IAM | `string` | `"/"` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no |
| <a name="input_web_console_services"></a> [web\_console\_services](#input\_web\_console\_services) | List of web console services to allow | `list(string)` | <pre>[<br> "resource-groups",<br> "tag",<br> "health"<br>]</pre> | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN assigned by AWS to this policy |
| <a name="output_description"></a> [description](#output\_description) | The description of the policy |
| <a name="output_id"></a> [id](#output\_id) | The policy's ID |
| <a name="output_name"></a> [name](#output\_name) | The name of the policy |
| <a name="output_path"></a> [path](#output\_path) | The path of the policy in IAM |
| <a name="output_policy"></a> [policy](#output\_policy) | The policy document |
| <a name="output_policy_json"></a> [policy\_json](#output\_policy\_json) | Policy document as json. Useful if you need document but do not want to create IAM policy itself. For example for SSO Permission Set inline policies |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

0 comments on commit 392756f

Please sign in to comment.