diff --git a/CHANGELOG.md b/CHANGELOG.md index 33db3e8..97ce29f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,3 +53,12 @@ * 1.3.2 -- 2025-02-14 - group-assignment - make ldap_group happen after idc group + +* 1.4.0 -- 2026-01-16 + - change AWS provider to >= 6 + - change region from name to region in locals + - require TF 1.12+ + - policies + - create new central policies to be used for permissionsets so they can be consistent across orgs + - created policies + - policies/sc-servicecatalog-t1 diff --git a/common/version.tf b/common/version.tf index 5ec2ece..37ff20f 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.3.2" + _module_version = "1.4.0" } diff --git a/common/versions.tf b/common/versions.tf index 34eb3b9..3b04f30 100644 --- a/common/versions.tf +++ b/common/versions.tf @@ -1,9 +1,9 @@ terraform { + required_version = ">= 1.12" required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.66.0" + version = ">= 6.0" } } - # required_version = ">= 0.13" } diff --git a/group-assignment/accounts.tf b/group-assignment/accounts.tf index 1f8b3e0..a0de8c1 100644 --- a/group-assignment/accounts.tf +++ b/group-assignment/accounts.tf @@ -9,14 +9,14 @@ locals { active_accounts_map = { for account in data.aws_organizations_organizational_unit_descendant_accounts.accounts.accounts : account.name => account if account.status == "ACTIVE" } active_accounts = { for k, v in local.active_accounts_map : k => v.id } - _id_1 = ! local.org_all && length(local.org_account_names) > 0 ? [for k in local.org_account_names : lookup(local.active_accounts, k, null)] : [] - _id_2 = ! local.org_all && length(local.org_account_ids) > 0 ? [for k in local.org_account_ids : k if contains(values(local.active_accounts), k)] : [] + _id_1 = !local.org_all && length(local.org_account_names) > 0 ? [for k in local.org_account_names : lookup(local.active_accounts, k, null)] : [] + _id_2 = !local.org_all && length(local.org_account_ids) > 0 ? [for k in local.org_account_ids : k if contains(values(local.active_accounts), k)] : [] organizational_unit_hierarchy = length(var.organizational_unit_hierarchy) > 0 ? { for k, v in var.organizational_unit_hierarchy : k => v.self_id } : {} # _ou_1 = ! local.org_all && length(local.organizational_unit_names) > 0 && length(var.organizational_unit_hierarchy) > 0 ? [for k, v in local.organizational_unit_names : lookup(local.organizational_unit_hierarchy, k, null)] : [] - _ou_1 = ! local.org_all && length(local.organizational_unit_names) > 0 && length(var.organizational_unit_hierarchy) > 0 ? { for k, v in local.organizational_unit_hierarchy : k => v if contains(local.organizational_unit_names, k) } : {} - _ou_2 = ! local.org_all && length(var.organizational_unit_ids) > 0 && length(var.organizational_unit_hierarchy) > 0 ? { for k in var.organizational_unit_ids : k => k } : {} + _ou_1 = !local.org_all && length(local.organizational_unit_names) > 0 && length(var.organizational_unit_hierarchy) > 0 ? { for k, v in local.organizational_unit_hierarchy : k => v if contains(local.organizational_unit_names, k) } : {} + _ou_2 = !local.org_all && length(var.organizational_unit_ids) > 0 && length(var.organizational_unit_hierarchy) > 0 ? { for k in var.organizational_unit_ids : k => k } : {} # organizational_units = distinct(compact(concat(local._ou_1, local._ou_2))) organizational_units = merge(local._ou_1, local._ou_2) diff --git a/group-assignment/locals.tf b/group-assignment/locals.tf index 5cba936..6aa29cd 100644 --- a/group-assignment/locals.tf +++ b/group-assignment/locals.tf @@ -1,7 +1,7 @@ locals { account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" - region = data.aws_region.current.name + region = data.aws_region.current.region region_short = join("", [for c in split("-", local.region) : substr(c, 0, 1)]) base_tags = { diff --git a/group-assignment/outputs.tf b/group-assignment/outputs.tf index 3cb0848..e0cb291 100644 --- a/group-assignment/outputs.tf +++ b/group-assignment/outputs.tf @@ -20,6 +20,6 @@ output "users" { value = { users = local.users valid_ldap_users = { for k, v in local.ldap_user_attributes : k => v.mail if can(v.mail) } - invalid_ldap_users = [for k, v in local.ldap_user_attributes : k if ! can(v.mail)] + invalid_ldap_users = [for k, v in local.ldap_user_attributes : k if !can(v.mail)] } } diff --git a/group-assignment/users.tf b/group-assignment/users.tf index cea9c08..2ce676a 100644 --- a/group-assignment/users.tf +++ b/group-assignment/users.tf @@ -32,7 +32,7 @@ data "aws_identitystore_user" "users" { locals { ldap_groups_base_dn = "o=U.S. Census Bureau,c=US" - ldap_groups_members = distinct(flatten([for k, v in data.ldap_object.ldap_groups : [for m in jsondecode(lookup(v.attributes_json, "memberUid", "")) : m if ! startswith(m, "p-") && (m != "[DynamicDN]")]])) + ldap_groups_members = distinct(flatten([for k, v in data.ldap_object.ldap_groups : [for m in jsondecode(lookup(v.attributes_json, "memberUid", "")) : m if !startswith(m, "p-") && (m != "[DynamicDN]")]])) } data "ldap_object" "ldap_groups" { diff --git a/permissionset/README.md b/permissionset/README.md index a119f96..ac843a7 100644 --- a/permissionset/README.md +++ b/permissionset/README.md @@ -2,13 +2,14 @@ | Name | Version | |------|---------| -| [aws](#requirement\_aws) | >= 3.66.0 | +| [terraform](#requirement\_terraform) | >= 1.12 | +| [aws](#requirement\_aws) | >= 6.0 | ## Providers | Name | Version | |------|---------| -| [aws](#provider\_aws) | >= 3.66.0 | +| [aws](#provider\_aws) | >= 6.0 | ## Modules diff --git a/permissionset/locals.tf b/permissionset/locals.tf index 5cba936..6aa29cd 100644 --- a/permissionset/locals.tf +++ b/permissionset/locals.tf @@ -1,7 +1,7 @@ locals { account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" - region = data.aws_region.current.name + region = data.aws_region.current.region region_short = join("", [for c in split("-", local.region) : substr(c, 0, 1)]) base_tags = { diff --git a/policies/sc-servicecatalog-t1/README.md b/policies/sc-servicecatalog-t1/README.md new file mode 100644 index 0000000..33cb3c2 --- /dev/null +++ b/policies/sc-servicecatalog-t1/README.md @@ -0,0 +1,44 @@ +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.12 | +| [aws](#requirement\_aws) | >= 6.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 6.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.inline](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [account\_alias](#input\_account\_alias) | AWS Account Alias | `string` | `""` | no | +| [account\_id](#input\_account\_id) | AWS Account ID (default will pull from current user) | `string` | `""` | no | +| [override\_prefixes](#input\_override\_prefixes) | Override built-in prefixes by component. This should be used primarily for common infrastructure things | `map(string)` | `{}` | no | +| [tags](#input\_tags) | AWS Tags to apply to appropriate resources | `map(string)` | `{}` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [customer\_managed\_policy\_names](#output\_customer\_managed\_policy\_names) | Map of policy name to permission boundary of Customer Managed Policy to attach to the permissionset | +| [inline\_policy](#output\_inline\_policy) | AWS Policy document for the single allowed inline policy (use .json to get policy) | +| [managed\_policy\_names](#output\_managed\_policy\_names) | Names of AWS Managed Policy to attach to the permissionset | +| [name](#output\_name) | Permission Set Name for which all settings apply | +| [relay\_state](#output\_relay\_state) | Relay State to pass along to permissionset | diff --git a/policies/sc-servicecatalog-t1/data.tf b/policies/sc-servicecatalog-t1/data.tf new file mode 120000 index 0000000..37fff16 --- /dev/null +++ b/policies/sc-servicecatalog-t1/data.tf @@ -0,0 +1 @@ +../../common/data.tf \ No newline at end of file diff --git a/policies/sc-servicecatalog-t1/defaults.tf b/policies/sc-servicecatalog-t1/defaults.tf new file mode 120000 index 0000000..1227df3 --- /dev/null +++ b/policies/sc-servicecatalog-t1/defaults.tf @@ -0,0 +1 @@ +../../common/defaults.tf \ No newline at end of file diff --git a/policies/sc-servicecatalog-t1/locals.tf b/policies/sc-servicecatalog-t1/locals.tf new file mode 100644 index 0000000..6aa29cd --- /dev/null +++ b/policies/sc-servicecatalog-t1/locals.tf @@ -0,0 +1,12 @@ +locals { + account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" + region = data.aws_region.current.region + region_short = join("", [for c in split("-", local.region) : substr(c, 0, 1)]) + + base_tags = { + "boc:tf_module_version" = local._module_version + "boc:tf_module_name" = local._module_name + "boc:created_by" = "terraform" + } +} diff --git a/policies/sc-servicecatalog-t1/main.tf b/policies/sc-servicecatalog-t1/main.tf new file mode 100644 index 0000000..3c91f4a --- /dev/null +++ b/policies/sc-servicecatalog-t1/main.tf @@ -0,0 +1,2 @@ +/* +*/ diff --git a/policies/sc-servicecatalog-t1/module_name.tf b/policies/sc-servicecatalog-t1/module_name.tf new file mode 100644 index 0000000..4240482 --- /dev/null +++ b/policies/sc-servicecatalog-t1/module_name.tf @@ -0,0 +1,3 @@ +locals { + _module_name = "aws-sso/policies/sc-servicecatalog-t1" +} diff --git a/policies/sc-servicecatalog-t1/outputs.tf b/policies/sc-servicecatalog-t1/outputs.tf new file mode 100644 index 0000000..776869b --- /dev/null +++ b/policies/sc-servicecatalog-t1/outputs.tf @@ -0,0 +1,24 @@ +output "name" { + description = "Permission Set Name for which all settings apply" + value = local.name +} + +output "managed_policy_names" { + description = "Names of AWS Managed Policy to attach to the permissionset" + value = local.managed_policy_names +} + +output "customer_managed_policy_names" { + description = "Map of policy name to permission boundary of Customer Managed Policy to attach to the permissionset" + value = local.customer_managed_policy_names +} + +output "inline_policy" { + description = "AWS Policy document for the single allowed inline policy (use .json to get policy)" + value = local.inline_policy +} + +output "relay_state" { + description = "Relay State to pass along to permissionset" + value = local.relay_state +} diff --git a/policies/sc-servicecatalog-t1/policy.tf b/policies/sc-servicecatalog-t1/policy.tf new file mode 100644 index 0000000..425ab7f --- /dev/null +++ b/policies/sc-servicecatalog-t1/policy.tf @@ -0,0 +1,13 @@ +data "aws_iam_policy_document" "inline" { + statement { + sid = "OnlyReadOperationsOnOrganizations" + effect = "Allow" + actions = [ + "organizations:Describe*", + "organizations:List*", + "account:Get*", + "account:List*" + ] + resources = ["*"] + } +} diff --git a/policies/sc-servicecatalog-t1/prefixes.tf b/policies/sc-servicecatalog-t1/prefixes.tf new file mode 120000 index 0000000..5bc256c --- /dev/null +++ b/policies/sc-servicecatalog-t1/prefixes.tf @@ -0,0 +1 @@ +../../common/prefixes.tf \ No newline at end of file diff --git a/policies/sc-servicecatalog-t1/settings.tf b/policies/sc-servicecatalog-t1/settings.tf new file mode 100644 index 0000000..5b3585f --- /dev/null +++ b/policies/sc-servicecatalog-t1/settings.tf @@ -0,0 +1,10 @@ +locals { + name = "servicecatalog-t1" + managed_policy_names = [ + "ReadOnlyAccess", + "AWSServiceCatalogEndUserFullAccess" + ] + customer_managed_policy_names = {} + relay_state = data.aws_arn.current.partition == "aws-us-gov" ? "https://console.amazonaws-us-gov.com/servicecatalog/home" : "https://console.aws.amazon.com/servicecatalog/home" + inline_policy = data.aws_iam_policy_document.inline +} diff --git a/policies/sc-servicecatalog-t1/variables.common.tf b/policies/sc-servicecatalog-t1/variables.common.tf new file mode 120000 index 0000000..e01226c --- /dev/null +++ b/policies/sc-servicecatalog-t1/variables.common.tf @@ -0,0 +1 @@ +../../common/variables.common.tf \ No newline at end of file diff --git a/policies/sc-servicecatalog-t1/variables.tf.unused b/policies/sc-servicecatalog-t1/variables.tf.unused new file mode 100644 index 0000000..53d6bf1 --- /dev/null +++ b/policies/sc-servicecatalog-t1/variables.tf.unused @@ -0,0 +1,29 @@ +variable "name" { + description = "Permission Set Name for which all settings apply" + type = string + default = null +} + +variable "managed_policy_names" { + description = "Names of AWS Managed Policy to attach to the permissionset" + type = list(string) + default = [] +} + +variable "customer_managed_policy_names" { + description = "Map of policy name to permission boundary of Customer Managed Policy to attach to the permissionset" + type = map(string) + default = {} +} + +# variable "inline_policy" { +# description = "AWS Policy document for the single allowed inline policy" +# type = string +# default = null +# } + +variable "relay_state" { + description = "Relay State to pass along to permissionset" + type = string + default = null +} diff --git a/policies/sc-servicecatalog-t1/version.tf b/policies/sc-servicecatalog-t1/version.tf new file mode 120000 index 0000000..4950c91 --- /dev/null +++ b/policies/sc-servicecatalog-t1/version.tf @@ -0,0 +1 @@ +../../common/version.tf \ No newline at end of file diff --git a/policies/sc-servicecatalog-t1/versions.tf b/policies/sc-servicecatalog-t1/versions.tf new file mode 120000 index 0000000..cbeda73 --- /dev/null +++ b/policies/sc-servicecatalog-t1/versions.tf @@ -0,0 +1 @@ +../../common/versions.tf \ No newline at end of file