Skip to content

Commit 392756f

Browse files
feat: Added iam-read-only-policy module (#174)
Co-authored-by: Anton Babenko <[email protected]>
1 parent 9278e6f commit 392756f

File tree

12 files changed

+448
-12
lines changed

12 files changed

+448
-12
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/antonbabenko/pre-commit-terraform
3-
rev: v1.58.0
3+
rev: v1.62.3
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_validate
@@ -23,6 +23,6 @@ repos:
2323
- '--args=--only=terraform_standard_module_structure'
2424
- '--args=--only=terraform_workspace_remote'
2525
- repo: https://github.com/pre-commit/pre-commit-hooks
26-
rev: v4.0.1
26+
rev: v4.1.0
2727
hooks:
2828
- id: check-merge-conflict

README.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
```hcl
1313
module "iam_account" {
1414
source = "terraform-aws-modules/iam/aws//modules/iam-account"
15-
version = "~> 4.3"
15+
version = "~> 4"
1616
1717
account_alias = "awesome-company"
1818
@@ -26,7 +26,7 @@ module "iam_account" {
2626
```hcl
2727
module "iam_assumable_role" {
2828
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
29-
version = "~> 4.3"
29+
version = "~> 4"
3030
3131
trusted_role_arns = [
3232
"arn:aws:iam::307990089504:root",
@@ -51,7 +51,7 @@ module "iam_assumable_role" {
5151
```hcl
5252
module "iam_assumable_role_with_oidc" {
5353
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
54-
version = "~> 4.3"
54+
version = "~> 4"
5555
5656
create_role = true
5757
@@ -75,7 +75,7 @@ module "iam_assumable_role_with_oidc" {
7575
```hcl
7676
module "iam_assumable_role_with_saml" {
7777
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-saml"
78-
version = "~> 4.3"
78+
version = "~> 4"
7979
8080
create_role = true
8181
@@ -99,7 +99,7 @@ module "iam_assumable_role_with_saml" {
9999
```hcl
100100
module "iam_assumable_roles" {
101101
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-roles"
102-
version = "~> 4.3"
102+
version = "~> 4"
103103
104104
trusted_role_arns = [
105105
"arn:aws:iam::307990089504:root",
@@ -121,7 +121,7 @@ module "iam_assumable_roles" {
121121
```hcl
122122
module "iam_assumable_roles_with_saml" {
123123
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-roles-with-saml"
124-
version = "~> 4.3"
124+
version = "~> 4"
125125
126126
create_admin_role = true
127127
@@ -139,7 +139,7 @@ module "iam_assumable_roles_with_saml" {
139139
```hcl
140140
module "iam_user" {
141141
source = "terraform-aws-modules/iam/aws//modules/iam-user"
142-
version = "~> 4.3"
142+
version = "~> 4"
143143
144144
name = "vasya.pupkin"
145145
force_destroy = true
@@ -155,7 +155,7 @@ module "iam_user" {
155155
```hcl
156156
module "iam_policy" {
157157
source = "terraform-aws-modules/iam/aws//modules/iam-policy"
158-
version = "~> 4.3"
158+
version = "~> 4"
159159
160160
name = "example"
161161
path = "/"
@@ -178,12 +178,27 @@ EOF
178178
}
179179
```
180180

181+
`iam-read-only-policy`:
182+
183+
```hcl
184+
module "iam_read_only_policy" {
185+
source = "terraform-aws-modules/iam/aws//modules/iam-read-only-policy"
186+
version = "~> 4"
187+
188+
name = "example"
189+
path = "/"
190+
description = "My example read-only policy"
191+
192+
allowed_services = ["rds", "dynamo", "health"]
193+
}
194+
```
195+
181196
`iam-group-with-assumable-roles-policy`:
182197

183198
```hcl
184199
module "iam_group_with_assumable_roles_policy" {
185200
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-assumable-roles-policy"
186-
version = "~> 4.3"
201+
version = "~> 4"
187202
188203
name = "production-readonly"
189204
@@ -203,7 +218,7 @@ module "iam_group_with_assumable_roles_policy" {
203218
```hcl
204219
module "iam_group_with_policies" {
205220
source = "terraform-aws-modules/iam/aws//modules/iam-group-with-policies"
206-
version = "~> 4.3"
221+
version = "~> 4"
207222
208223
name = "superadmins"
209224
@@ -265,6 +280,8 @@ Terraform can't configure MFA for the user. It is only possible via [AWS Console
265280

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

283+
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.
284+
268285
## Examples
269286

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

282300
## Authors
283301

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# IAM read-only policy example
2+
3+
Configuration in this directory creates read-only IAM policy and attaches it to AWS SSO.
4+
5+
# Usage
6+
7+
To run this example you need to execute:
8+
9+
```bash
10+
$ terraform init
11+
$ terraform plan
12+
$ terraform apply
13+
```
14+
15+
Run `terraform destroy` when you don't need these resources.
16+
17+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
18+
## Requirements
19+
20+
| Name | Version |
21+
|------|---------|
22+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
23+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.23 |
24+
25+
## Providers
26+
27+
| Name | Version |
28+
|------|---------|
29+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.23 |
30+
31+
## Modules
32+
33+
| Name | Source | Version |
34+
|------|--------|---------|
35+
| <a name="module_read_only_iam_policy"></a> [read\_only\_iam\_policy](#module\_read\_only\_iam\_policy) | ../../modules/iam-read-only-policy | n/a |
36+
| <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 |
37+
38+
## Resources
39+
40+
| Name | Type |
41+
|------|------|
42+
| [aws_ssoadmin_permission_set.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set) | resource |
43+
| [aws_ssoadmin_permission_set_inline_policy.example](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set_inline_policy) | resource |
44+
45+
## Inputs
46+
47+
No inputs.
48+
49+
## Outputs
50+
51+
| Name | Description |
52+
|------|-------------|
53+
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN assigned by AWS to this policy |
54+
| <a name="output_description"></a> [description](#output\_description) | The description of the policy |
55+
| <a name="output_id"></a> [id](#output\_id) | The policy ID |
56+
| <a name="output_name"></a> [name](#output\_name) | The name of the policy |
57+
| <a name="output_path"></a> [path](#output\_path) | The path of the policy in IAM |
58+
| <a name="output_policy"></a> [policy](#output\_policy) | The policy document |
59+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/iam-read-only-policy/main.tf

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
provider "aws" {
2+
region = "eu-west-1"
3+
}
4+
5+
locals {
6+
allowed_services_compute = ["ec2", "ecr", "eks", "ecs", "lambda", "autoscaling", "elasticloadbalancing"]
7+
allowed_services_networking = ["vpc", "route53", "route53domains", "route53resolver", "servicediscovery"]
8+
allowed_services_storage = ["s3", "backup", "dynamo", "dms", "elasticfilesystem"]
9+
allowed_services_databases = ["rds", "dynamo", "elasticache"]
10+
allowed_services_management = ["cloudwatch", "events", "logs", "servicequotas", "ssm"]
11+
allowed_services_analytics = ["es", "firehose", "kinesis", "kinesisanalytics", "redshift"]
12+
allowed_services_application = ["ses", "sns", "sqs", "xray", "applicationinsights", "application-autoscaling"]
13+
allowed_services_security = ["iam", "acm", "kms", "secretsmanager"]
14+
15+
allowed_services = concat(
16+
local.allowed_services_compute,
17+
local.allowed_services_networking,
18+
local.allowed_services_storage,
19+
local.allowed_services_databases,
20+
local.allowed_services_management,
21+
local.allowed_services_analytics,
22+
local.allowed_services_application,
23+
local.allowed_services_security
24+
)
25+
}
26+
27+
module "read_only_iam_policy" {
28+
source = "../../modules/iam-read-only-policy"
29+
30+
name = "example"
31+
path = "/"
32+
description = "My read only example policy"
33+
34+
allowed_services = local.allowed_services
35+
36+
tags = {
37+
PolicyDescription = "My read only example policy"
38+
}
39+
}
40+
41+
module "read_only_iam_policy_doc" {
42+
source = "../../modules/iam-read-only-policy"
43+
44+
name = "only-doc-example"
45+
path = "/"
46+
description = "My read only example policy"
47+
48+
create_policy = false
49+
50+
allowed_services = local.allowed_services
51+
52+
tags = {
53+
PolicyDescription = "My read only example policy"
54+
}
55+
}
56+
57+
resource "aws_ssoadmin_permission_set" "example" {
58+
name = "Example"
59+
instance_arn = "arn:aws:sso:::instance/example"
60+
}
61+
62+
resource "aws_ssoadmin_permission_set_inline_policy" "example" {
63+
inline_policy = module.read_only_iam_policy_doc.policy_json
64+
instance_arn = aws_ssoadmin_permission_set.example.instance_arn
65+
permission_set_arn = aws_ssoadmin_permission_set.example.arn
66+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
output "id" {
2+
description = "The policy ID"
3+
value = module.read_only_iam_policy.id
4+
}
5+
6+
output "arn" {
7+
description = "The ARN assigned by AWS to this policy"
8+
value = module.read_only_iam_policy.arn
9+
}
10+
11+
output "description" {
12+
description = "The description of the policy"
13+
value = module.read_only_iam_policy.description
14+
}
15+
16+
output "name" {
17+
description = "The name of the policy"
18+
value = module.read_only_iam_policy.name
19+
}
20+
21+
output "path" {
22+
description = "The path of the policy in IAM"
23+
value = module.read_only_iam_policy.path
24+
}
25+
26+
output "policy" {
27+
description = "The policy document"
28+
value = module.read_only_iam_policy.policy
29+
}

examples/iam-read-only-policy/variables.tf

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
terraform {
2+
required_version = ">= 0.12.6"
3+
4+
required_providers {
5+
aws = ">= 2.23"
6+
}
7+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# iam-read-only-policy
2+
3+
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/)
4+
Thus this module is an attempt to build a better base for a customizable usable read-only policy.
5+
6+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
7+
## Requirements
8+
9+
| Name | Version |
10+
|------|---------|
11+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
12+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.23 |
13+
14+
## Providers
15+
16+
| Name | Version |
17+
|------|---------|
18+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.23 |
19+
20+
## Modules
21+
22+
No modules.
23+
24+
## Resources
25+
26+
| Name | Type |
27+
|------|------|
28+
| [aws_iam_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
29+
| [aws_iam_policy_document.allowed_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
30+
| [aws_iam_policy_document.combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
31+
| [aws_iam_policy_document.console_services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
32+
| [aws_iam_policy_document.logs_query](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
33+
| [aws_iam_policy_document.sts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
34+
35+
## Inputs
36+
37+
| Name | Description | Type | Default | Required |
38+
|------|-------------|------|---------|:--------:|
39+
| <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 |
40+
| <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 |
41+
| <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 |
42+
| <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 |
43+
| <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 |
44+
| <a name="input_create_policy"></a> [create\_policy](#input\_create\_policy) | Whether to create the IAM policy | `bool` | `true` | no |
45+
| <a name="input_description"></a> [description](#input\_description) | The description of the policy | `string` | `"IAM Policy"` | no |
46+
| <a name="input_name"></a> [name](#input\_name) | The name of the policy | `string` | `""` | no |
47+
| <a name="input_path"></a> [path](#input\_path) | The path of the policy in IAM | `string` | `"/"` | no |
48+
| <a name="input_tags"></a> [tags](#input\_tags) | A map of tags to add to all resources. | `map(string)` | `{}` | no |
49+
| <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 |
50+
51+
## Outputs
52+
53+
| Name | Description |
54+
|------|-------------|
55+
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN assigned by AWS to this policy |
56+
| <a name="output_description"></a> [description](#output\_description) | The description of the policy |
57+
| <a name="output_id"></a> [id](#output\_id) | The policy's ID |
58+
| <a name="output_name"></a> [name](#output\_name) | The name of the policy |
59+
| <a name="output_path"></a> [path](#output\_path) | The path of the policy in IAM |
60+
| <a name="output_policy"></a> [policy](#output\_policy) | The policy document |
61+
| <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 |
62+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

0 commit comments

Comments
 (0)