From 1b074d9ec543ffe06d092260bd3b31ef0d67a988 Mon Sep 17 00:00:00 2001 From: badra001 Date: Tue, 4 Apr 2023 08:45:58 -0400 Subject: [PATCH] - route53-zone-association/terraform-role - created to be applied in an account where a PHZ is maintained but shared to other accounts and VPCs. This allows a terraform provider using an assume role configuration (to r-inf-terraform-route53) - must be done after addition to organization - route53-zone-association/lambda-role - created to be applied in an account where a PHZ is maintained but shared to other accounts and VPCs. This will be used by the dynamic route53 lambda to assume this role to enter the route53 records - must be done after addition to organization --- CHANGELOG.md | 10 +++ common/version.tf | 46 +++++----- route53-zone-association/lambda-role/data.tf | 1 + .../lambda-role/defaults.tf | 1 + route53-zone-association/lambda-role/main.tf | 80 ++++++++++++++++++ .../lambda-role/module_name.tf | 3 + .../lambda-role/prefixes.tf | 1 + .../lambda-role/variables.common.tf | 1 + .../lambda-role/variables.tf | 11 +++ .../lambda-role/version.tf | 1 + .../lambda-role/versions.tf | 9 ++ .../terraform-role/data.tf | 1 + .../terraform-role/defaults.tf | 1 + .../terraform-role/main.tf | 84 +++++++++++++++++++ .../terraform-role/module_name.tf | 3 + .../terraform-role/prefixes.tf | 1 + .../terraform-role/variables.common.tf | 1 + .../terraform-role/variables.tf | 11 +++ .../terraform-role/version.tf | 1 + .../terraform-role/versions.tf | 9 ++ 20 files changed, 254 insertions(+), 22 deletions(-) create mode 120000 route53-zone-association/lambda-role/data.tf create mode 120000 route53-zone-association/lambda-role/defaults.tf create mode 100644 route53-zone-association/lambda-role/main.tf create mode 100644 route53-zone-association/lambda-role/module_name.tf create mode 120000 route53-zone-association/lambda-role/prefixes.tf create mode 120000 route53-zone-association/lambda-role/variables.common.tf create mode 100644 route53-zone-association/lambda-role/variables.tf create mode 120000 route53-zone-association/lambda-role/version.tf create mode 100644 route53-zone-association/lambda-role/versions.tf create mode 120000 route53-zone-association/terraform-role/data.tf create mode 120000 route53-zone-association/terraform-role/defaults.tf create mode 100644 route53-zone-association/terraform-role/main.tf create mode 100644 route53-zone-association/terraform-role/module_name.tf create mode 120000 route53-zone-association/terraform-role/prefixes.tf create mode 120000 route53-zone-association/terraform-role/variables.common.tf create mode 100644 route53-zone-association/terraform-role/variables.tf create mode 120000 route53-zone-association/terraform-role/version.tf create mode 100644 route53-zone-association/terraform-role/versions.tf diff --git a/CHANGELOG.md b/CHANGELOG.md index be3ddf0..601f25f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -273,3 +273,13 @@ - route53-zone-association new module - vpc: associate vpc with peer zone(s) - zone: associate zone(s) with peer vpc + +* 2.8.0 -- 2023-04-04 + - route53-zone-association/terraform-role + - created to be applied in an account where a PHZ is maintained but shared to other accounts and VPCs. This allows a terraform + provider using an assume role configuration (to r-inf-terraform-route53) + - must be done after addition to organization + - route53-zone-association/lambda-role + - created to be applied in an account where a PHZ is maintained but shared to other accounts and VPCs. This will be used by + the dynamic route53 lambda to assume this role to enter the route53 records + - must be done after addition to organization diff --git a/common/version.tf b/common/version.tf index a85d9a7..46e4a2f 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,28 +1,30 @@ locals { - _module_version = "2.7.0" + _module_version = "2.8.0" _module_names = { "_main_" = "aws-vpc-setup" - "flowlogs" = "aws-vpc-setup/flowlogs" - "flowlogs-transit-gateway" = "aws-vpc-setup/flowlogs-transit-gateway" - "flowlogs-role" = "aws-vpc-setup/flowlogs-role" - "nacl-rules" = "aws-vpc-setup/nacl-rules" - "nacls" = "aws-vpc-setup/nacls" - "peer" = "aws-vpc-setup/peer" - "routing" = "aws-vpc-setup/routing" - "route53-zone-assoication/vpc" = "aws-vpc/setup/route53-zone-association/vpc" - "route53-zone-assoication/zone" = "aws-vpc/setup/route53-zone-association/zone" - "security-groups" = "aws-vpc-setup/security-groups" - "share-resources" = "aws-vpc-setup/share-resources" - "subnets" = "aws-vpc-setup/subnets" - "tag-shared-vpc-resources" = "aws-vpc-setup/tag-shared-vpc-resources" - "vpc" = "aws-vpc-setup/vpc" - "vpc-interface-endpoint" = "aws-vpc-setup/vpc-interface-endpoint" - "vpn" = "aws-vpc-setup/vpn" - "vpn-transit-gateway" = "aws-vpc-setup/vpn-transit-gateway" - "vpn-transit-gateway" = "aws-vpc-setup/vpn-transit-gateway" - "vpc-transit-gateway-association/data" = "aws-vpc-setup/vpc-transit-gateway-association/data" - "vpc-transit-gateway-association/self" = "aws-vpc-setup/vpc-transit-gateway-association/self" - "vpc-transit-gateway-association/peer" = "aws-vpc-setup/vpc-transit-gateway-association/peer" + "flowlogs" = "aws-vpc-setup/flowlogs" + "flowlogs-transit-gateway" = "aws-vpc-setup/flowlogs-transit-gateway" + "flowlogs-role" = "aws-vpc-setup/flowlogs-role" + "nacl-rules" = "aws-vpc-setup/nacl-rules" + "nacls" = "aws-vpc-setup/nacls" + "peer" = "aws-vpc-setup/peer" + "routing" = "aws-vpc-setup/routing" + "route53-zone-assoication/vpc" = "aws-vpc/setup/route53-zone-association/vpc" + "route53-zone-assoication/zone" = "aws-vpc/setup/route53-zone-association/zone" + "route53-zone-assoication/terraform-role" = "aws-vpc/setup/route53-zone-association/terraform-role" + "route53-zone-assoication/lambda-role" = "aws-vpc/setup/route53-zone-association/lambda-role" + "security-groups" = "aws-vpc-setup/security-groups" + "share-resources" = "aws-vpc-setup/share-resources" + "subnets" = "aws-vpc-setup/subnets" + "tag-shared-vpc-resources" = "aws-vpc-setup/tag-shared-vpc-resources" + "vpc" = "aws-vpc-setup/vpc" + "vpc-interface-endpoint" = "aws-vpc-setup/vpc-interface-endpoint" + "vpn" = "aws-vpc-setup/vpn" + "vpn-transit-gateway" = "aws-vpc-setup/vpn-transit-gateway" + "vpn-transit-gateway" = "aws-vpc-setup/vpn-transit-gateway" + "vpc-transit-gateway-association/data" = "aws-vpc-setup/vpc-transit-gateway-association/data" + "vpc-transit-gateway-association/self" = "aws-vpc-setup/vpc-transit-gateway-association/self" + "vpc-transit-gateway-association/peer" = "aws-vpc-setup/vpc-transit-gateway-association/peer" } } diff --git a/route53-zone-association/lambda-role/data.tf b/route53-zone-association/lambda-role/data.tf new file mode 120000 index 0000000..37fff16 --- /dev/null +++ b/route53-zone-association/lambda-role/data.tf @@ -0,0 +1 @@ +../../common/data.tf \ No newline at end of file diff --git a/route53-zone-association/lambda-role/defaults.tf b/route53-zone-association/lambda-role/defaults.tf new file mode 120000 index 0000000..1227df3 --- /dev/null +++ b/route53-zone-association/lambda-role/defaults.tf @@ -0,0 +1 @@ +../../common/defaults.tf \ No newline at end of file diff --git a/route53-zone-association/lambda-role/main.tf b/route53-zone-association/lambda-role/main.tf new file mode 100644 index 0000000..beb5362 --- /dev/null +++ b/route53-zone-association/lambda-role/main.tf @@ -0,0 +1,80 @@ +/* +* # About aws-vpc-setup :: route53-zone-assoication :: terraform-role +* +* Role to be assumed from terraform in a remote account (or local account) to allow for associating the VPC to the PHZ +* and for updating route53 entries. This fails if not a member of an organization. +*/ + +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_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" = lookup(local._module_names, local._module_name, local._module_names["_main_"]) + "boc:created_by" = "terraform" + } + + role_name = format("%v%v", lookup(local._prefixes, "role", ""), var.role_name) + role_description = var.role_description == "" ? format("Role for %v", var.role_name) : var.role_description +} + +data "aws_organizations_organization" "org" {} + +# allow assume role from org +data "aws_iam_policy_document" "assume_role" { + statement { + sid = "STSAssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + principals { + type = "AWS" + identifiers = ["*"] + } + condition { + test = "StringEquals" + variable = "aws:PrincipalOrgID" + values = [data.aws_organizations_organization.org.id] + } + } +} + +data "aws_iam_policy_document" "policy" { + statement { + sid = "TFRemoteRoute53Actions" + effect = "Allow" + actions = [ + "route53:Get*", + "route53:List*", + "route53:TestDNSAnswer", + "route53:ChangeResourceRecordSets", + ] + resources = ["*"] + } +} + +resource "aws_iam_role" "role" { + name = local.role_name + description = local.role_description + force_detach_policies = local._defaults["force_detach_policies"] + max_session_duration = local._defaults["max_session_duration"] + assume_role_policy = data.aws_iam_policy_document.assume_role.json + + inline_policy { + name = "remote-route53" + policy = data.aws_iam_policy_document.policy.json + } + + lifecycle { + ignore_changes = [tags["boc:tf_module_version"]] + } + + tags = merge( + local.base_tags, + var.tags, + lookup(var.component_tags, "role", {}), + { Name = local.role_name }, + ) +} diff --git a/route53-zone-association/lambda-role/module_name.tf b/route53-zone-association/lambda-role/module_name.tf new file mode 100644 index 0000000..6672b31 --- /dev/null +++ b/route53-zone-association/lambda-role/module_name.tf @@ -0,0 +1,3 @@ +locals { + _module_name = "route53-zone-assoication/lambda-role" +} diff --git a/route53-zone-association/lambda-role/prefixes.tf b/route53-zone-association/lambda-role/prefixes.tf new file mode 120000 index 0000000..5bc256c --- /dev/null +++ b/route53-zone-association/lambda-role/prefixes.tf @@ -0,0 +1 @@ +../../common/prefixes.tf \ No newline at end of file diff --git a/route53-zone-association/lambda-role/variables.common.tf b/route53-zone-association/lambda-role/variables.common.tf new file mode 120000 index 0000000..e01226c --- /dev/null +++ b/route53-zone-association/lambda-role/variables.common.tf @@ -0,0 +1 @@ +../../common/variables.common.tf \ No newline at end of file diff --git a/route53-zone-association/lambda-role/variables.tf b/route53-zone-association/lambda-role/variables.tf new file mode 100644 index 0000000..cd9a1f1 --- /dev/null +++ b/route53-zone-association/lambda-role/variables.tf @@ -0,0 +1,11 @@ +variable "role_name" { + description = "IAM Role name (without prefix)" + type = string + default = "inf-dynamic-route53-actions" +} + +variable "role_description" { + description = "IAM Role description" + type = string + default = "INF Lambda Assume Role for Dynamic Route53 actions" +} diff --git a/route53-zone-association/lambda-role/version.tf b/route53-zone-association/lambda-role/version.tf new file mode 120000 index 0000000..4950c91 --- /dev/null +++ b/route53-zone-association/lambda-role/version.tf @@ -0,0 +1 @@ +../../common/version.tf \ No newline at end of file diff --git a/route53-zone-association/lambda-role/versions.tf b/route53-zone-association/lambda-role/versions.tf new file mode 100644 index 0000000..2aa1770 --- /dev/null +++ b/route53-zone-association/lambda-role/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0.0" + } + } +} diff --git a/route53-zone-association/terraform-role/data.tf b/route53-zone-association/terraform-role/data.tf new file mode 120000 index 0000000..37fff16 --- /dev/null +++ b/route53-zone-association/terraform-role/data.tf @@ -0,0 +1 @@ +../../common/data.tf \ No newline at end of file diff --git a/route53-zone-association/terraform-role/defaults.tf b/route53-zone-association/terraform-role/defaults.tf new file mode 120000 index 0000000..1227df3 --- /dev/null +++ b/route53-zone-association/terraform-role/defaults.tf @@ -0,0 +1 @@ +../../common/defaults.tf \ No newline at end of file diff --git a/route53-zone-association/terraform-role/main.tf b/route53-zone-association/terraform-role/main.tf new file mode 100644 index 0000000..101c5f1 --- /dev/null +++ b/route53-zone-association/terraform-role/main.tf @@ -0,0 +1,84 @@ +/* +* # About aws-vpc-setup :: route53-zone-assoication :: terraform-role +* +* Role to be assumed from terraform in a remote account (or local account) to allow for associating the VPC to the PHZ +* and for updating route53 entries. This fails if not a member of an organization. +*/ + +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_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" = lookup(local._module_names, local._module_name, local._module_names["_main_"]) + "boc:created_by" = "terraform" + } + + role_name = format("%v%v", lookup(local._prefixes, "role", ""), var.role_name) + role_description = var.role_description == "" ? format("Role for %v", var.role_name) : var.role_description +} + +data "aws_organizations_organization" "org" {} + +# allow assume role from org +data "aws_iam_policy_document" "assume_role" { + statement { + sid = "STSAssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + principals { + type = "AWS" + identifiers = ["*"] + } + condition { + test = "StringEquals" + variable = "aws:PrincipalOrgID" + values = [data.aws_organizations_organization.org.id] + } + } +} + +data "aws_iam_policy_document" "policy" { + statement { + sid = "TFRemoteRoute53Actions" + effect = "Allow" + actions = [ + "route53:Get*", + "route53:List*", + "route53:AssociateVPCWithHostedZone", + "route53:DisassociateVPCFromHostedZone", + "route53:CreateVPCAssociationAuthorization", + "route53:DeleteVPCAssociationAuthorization", + "route53:TestDNSAnswer", + "route53:ChangeResourceRecordSets", + ] + resources = ["*"] + } +} + +resource "aws_iam_role" "role" { + name = local.role_name + description = local.role_description + force_detach_policies = local._defaults["force_detach_policies"] + max_session_duration = local._defaults["max_session_duration"] + assume_role_policy = data.aws_iam_policy_document.assume_role.json + + inline_policy { + name = "remote-route53" + policy = data.aws_iam_policy_document.policy.json + } + + lifecycle { + ignore_changes = [tags["boc:tf_module_version"]] + } + + tags = merge( + local.base_tags, + var.tags, + lookup(var.component_tags, "role", {}), + { Name = local.role_name }, + ) +} diff --git a/route53-zone-association/terraform-role/module_name.tf b/route53-zone-association/terraform-role/module_name.tf new file mode 100644 index 0000000..9317a12 --- /dev/null +++ b/route53-zone-association/terraform-role/module_name.tf @@ -0,0 +1,3 @@ +locals { + _module_name = "route53-zone-assoication/terraform-role" +} diff --git a/route53-zone-association/terraform-role/prefixes.tf b/route53-zone-association/terraform-role/prefixes.tf new file mode 120000 index 0000000..5bc256c --- /dev/null +++ b/route53-zone-association/terraform-role/prefixes.tf @@ -0,0 +1 @@ +../../common/prefixes.tf \ No newline at end of file diff --git a/route53-zone-association/terraform-role/variables.common.tf b/route53-zone-association/terraform-role/variables.common.tf new file mode 120000 index 0000000..e01226c --- /dev/null +++ b/route53-zone-association/terraform-role/variables.common.tf @@ -0,0 +1 @@ +../../common/variables.common.tf \ No newline at end of file diff --git a/route53-zone-association/terraform-role/variables.tf b/route53-zone-association/terraform-role/variables.tf new file mode 100644 index 0000000..6ecc207 --- /dev/null +++ b/route53-zone-association/terraform-role/variables.tf @@ -0,0 +1,11 @@ +variable "role_name" { + description = "IAM Role name (without prefix)" + type = string + default = "inf-terraform-route53" +} + +variable "role_description" { + description = "IAM Role description" + type = string + default = "INF Terraform Role for Route53 actions" +} diff --git a/route53-zone-association/terraform-role/version.tf b/route53-zone-association/terraform-role/version.tf new file mode 120000 index 0000000..4950c91 --- /dev/null +++ b/route53-zone-association/terraform-role/version.tf @@ -0,0 +1 @@ +../../common/version.tf \ No newline at end of file diff --git a/route53-zone-association/terraform-role/versions.tf b/route53-zone-association/terraform-role/versions.tf new file mode 100644 index 0000000..2aa1770 --- /dev/null +++ b/route53-zone-association/terraform-role/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.0.0" + } + } +}