Skip to content

Commit 8f3c3c4

Browse files
committed
feat: Add permission-sets sub module
1 parent 6e46b12 commit 8f3c3c4

File tree

7 files changed

+215
-0
lines changed

7 files changed

+215
-0
lines changed

modules/permission_sets/.header.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Terraform AWS Organizations Permission-Sets Module
2+
A Terraform module for creating and managing AWS SSO (Single Sign-On) Permission Sets within AWS Organizations

modules/permission_sets/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Terraform AWS Organizations Permission-Sets Module
2+
A Terraform module for creating and managing AWS SSO (Single Sign-On) Permission Sets within AWS Organizations
3+
4+
## Requirements
5+
6+
| Name | Version |
7+
|------|---------|
8+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.4.6 |
9+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.65.0 |
10+
11+
## Providers
12+
13+
| Name | Version |
14+
|------|---------|
15+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.57.0 |
16+
17+
## Modules
18+
19+
No modules.
20+
21+
## Resources
22+
23+
| Name | Type |
24+
|------|------|
25+
| [aws_ssoadmin_customer_managed_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_customer_managed_policy_attachment) | resource |
26+
| [aws_ssoadmin_managed_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_managed_policy_attachment) | resource |
27+
| [aws_ssoadmin_permission_set.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set) | resource |
28+
| [aws_ssoadmin_permission_set_inline_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssoadmin_permission_set_inline_policy) | resource |
29+
| [aws_ssoadmin_instances.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssoadmin_instances) | data source |
30+
31+
## Inputs
32+
33+
| Name | Description | Type | Default | Required |
34+
|------|-------------|------|---------|:--------:|
35+
| <a name="input_permission_sets"></a> [permission\_sets](#input\_permission\_sets) | n/a | <pre>list(object({<br> name = string<br> description = string<br> session_duration = optional(string, "PT1H")<br> tags = optional(map(string), null)<br> inline_policy = optional(string, null) # Inline policy in JSON format <br> managed_policies = optional(list(string), []) # list of ARN's of managed policies<br> customer_managed_policies = optional(list(object({<br> name = string<br> path = optional(string, "/") # list of customer-managed policies with their names and paths to be attached to each.<br> })), [])<br> }))</pre> | `[]` | no |
36+
| <a name="input_tags"></a> [tags](#input\_tags) | (Optional) Key-value map of resource tags. | `map(string)` | `null` | no |
37+
38+
## Outputs
39+
40+
| Name | Description |
41+
|------|-------------|
42+
| <a name="output_permission_sets"></a> [permission\_sets](#output\_permission\_sets) | A map of the permission sets that were created. Each key is the name of the permission set, and the value contains the details of the created permission set. |

modules/permission_sets/main.tf

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
locals {
2+
sso_instance_arn = tolist(data.aws_ssoadmin_instances.this.arns)[0]
3+
permission_set_map = { for ps in var.permission_sets : ps.name => ps }
4+
inline_policies_map = { for ps in var.permission_sets : ps.name => ps.inline_policy if ps.inline_policy != null }
5+
managed_policy_map = { for ps in var.permission_sets : ps.name => ps.managed_policies if length(ps.managed_policies) > 0 }
6+
managed_policy_attachments = flatten([
7+
for ps_name, policy_list in local.managed_policy_map : [
8+
for policy_arn in policy_list : {
9+
permission_set = ps_name
10+
policy_arn = policy_arn
11+
}
12+
]
13+
])
14+
managed_policy_attachments_map = {
15+
for policy in local.managed_policy_attachments : "${policy.permission_set}.${policy.policy_arn}" => policy
16+
}
17+
customer_managed_policy_map = { for ps in var.permission_sets : ps.name => ps.customer_managed_policies if length(ps.customer_managed_policies) > 0 }
18+
customer_managed_policy_attachments = flatten([
19+
for ps_name, policy_list in local.customer_managed_policy_map : [
20+
for policy in policy_list : {
21+
permission_set = ps_name
22+
policy_name = policy.name
23+
policy_path = policy.path
24+
}
25+
]
26+
])
27+
customer_managed_policy_attachments_map = {
28+
for policy in local.customer_managed_policy_attachments : "${policy.permission_set}.${policy.policy_path}${policy.policy_name}" => policy
29+
}
30+
}
31+
32+
data "aws_ssoadmin_instances" "this" {}
33+
34+
# CREATE THE PERMISSION SETS
35+
resource "aws_ssoadmin_permission_set" "this" {
36+
for_each = local.permission_set_map
37+
38+
name = each.key
39+
description = each.value.description
40+
instance_arn = local.sso_instance_arn
41+
session_duration = each.value.session_duration
42+
tags = merge(each.value.tags, var.tags)
43+
}
44+
45+
# ATTACH INLINE POLICIES
46+
resource "aws_ssoadmin_permission_set_inline_policy" "this" {
47+
for_each = local.inline_policies_map
48+
49+
inline_policy = each.value
50+
instance_arn = local.sso_instance_arn
51+
permission_set_arn = aws_ssoadmin_permission_set.this[each.key].arn
52+
depends_on = [aws_ssoadmin_permission_set_inline_policy.this]
53+
}
54+
55+
# ATTACH MANAGED POLICIES
56+
resource "aws_ssoadmin_managed_policy_attachment" "this" {
57+
for_each = local.managed_policy_attachments_map
58+
59+
instance_arn = local.sso_instance_arn
60+
managed_policy_arn = each.value.policy_arn
61+
permission_set_arn = aws_ssoadmin_permission_set.this[each.value.policy_set].arn
62+
depends_on = [aws_ssoadmin_permission_set_inline_policy.this]
63+
}
64+
65+
# ATTACH CUSTOMER MANAGED POLICIES
66+
resource "aws_ssoadmin_customer_managed_policy_attachment" "this" {
67+
for_each = local.customer_managed_policy_attachments_map
68+
instance_arn = local.sso_instance_arn
69+
permission_set_arn = aws_ssoadmin_permission_set.this[each.value.policy_set].arn
70+
customer_managed_policy_reference {
71+
name = each.value.policy_name
72+
path = each.value.policy_path
73+
}
74+
depends_on = [aws_ssoadmin_permission_set_inline_policy.this]
75+
}
76+

modules/permission_sets/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "permission_sets" {
2+
description = "A map of the permission sets that were created. Each key is the name of the permission set, and the value contains the details of the created permission set."
3+
value = aws_ssoadmin_permission_set.this
4+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
variable "permission_sets" {
2+
type = list(object({
3+
name = string
4+
description = string
5+
session_duration = optional(string, "PT1H")
6+
tags = optional(map(string), null)
7+
inline_policy = optional(string, null) # Inline policy in JSON format
8+
managed_policies = optional(list(string), []) # list of ARN's of managed policies
9+
customer_managed_policies = optional(list(object({
10+
name = string
11+
path = optional(string, "/") # list of customer-managed policies with their names and paths to be attached to each.
12+
})), [])
13+
}))
14+
default = []
15+
}
16+
17+
variable "tags" {
18+
description = "(Optional) Key-value map of resource tags."
19+
type = map(string)
20+
default = null
21+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.4.6"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 4.65.0"
8+
}
9+
}
10+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Attribute validations for permission_sets sub module
2+
run "check_permission_set_creation" {
3+
module {
4+
source = "./modules/permission_sets"
5+
}
6+
variables {
7+
permission_sets = [
8+
{
9+
name = "dummy"
10+
description = "This is only used for testing purpose"
11+
}
12+
]
13+
}
14+
command = plan
15+
16+
assert {
17+
condition = length(aws_ssoadmin_permission_set.this) == 1
18+
error_message = "Permission set `dummy` was not created"
19+
}
20+
}
21+
22+
run "validate_permission_set_name" {
23+
module {
24+
source = "./modules/permission_sets"
25+
}
26+
variables {
27+
permission_sets = [
28+
{
29+
name = "dummy"
30+
description = "This is only used for testing purpose"
31+
}
32+
]
33+
}
34+
command = plan
35+
36+
assert {
37+
condition = aws_ssoadmin_permission_set.this[var.permission_sets[0].name].name == var.permission_sets[0].name
38+
error_message = "Invalid permission set name"
39+
}
40+
}
41+
42+
run "validate_permission_set_description" {
43+
module {
44+
source = "./modules/permission_sets"
45+
}
46+
variables {
47+
permission_sets = [
48+
{
49+
name = "dummy"
50+
description = "This is only used for testing purpose"
51+
}
52+
]
53+
}
54+
command = plan
55+
56+
assert {
57+
condition = aws_ssoadmin_permission_set.this[var.permission_sets[0].name].description == var.permission_sets[0].description
58+
error_message = "Invalid permission set name"
59+
}
60+
}

0 commit comments

Comments
 (0)