diff --git a/examples/full-setup/apps/dns/.terraform-docs.yml b/examples/full-setup/apps/dns/.terraform-docs.yml new file mode 100644 index 0000000..8391b9d --- /dev/null +++ b/examples/full-setup/apps/dns/.terraform-docs.yml @@ -0,0 +1,44 @@ +formatter: markdown table + +header-from: main.tf +footer-from: "" + +sections: +## hide: [] + show: + - data-sources + - header + - footer + - inputs + - modules + - outputs + - providers + - requirements + - resources + +output: + file: README.md + mode: inject + template: |- + + {{ .Content }} + + +## output-values: +## enabled: false +## from: "" +## +## sort: +## enabled: true +## by: name +## +## settings: +## anchor: true +## color: true +## default: true +## description: false +## escape: true +## indent: 2 +## required: true +## sensitive: true +## type: true diff --git a/examples/full-setup/apps/dns/README.md b/examples/full-setup/apps/dns/README.md new file mode 100644 index 0000000..0d006f9 --- /dev/null +++ b/examples/full-setup/apps/dns/README.md @@ -0,0 +1,55 @@ + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [aws.east\_main\_dns](#provider\_aws.east\_main\_dns) | n/a | +| [aws.west\_main\_dns](#provider\_aws.west\_main\_dns) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_route53_resolver_rule_association.all_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_resolver_rule_association) | resource | +| [aws_route53_vpc_association_authorization.east_domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_vpc_association_authorization) | resource | +| [aws_route53_vpc_association_authorization.east_ptr_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_vpc_association_authorization) | resource | +| [aws_route53_vpc_association_authorization.west_domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_vpc_association_authorization) | resource | +| [aws_route53_vpc_association_authorization.west_ptr_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_vpc_association_authorization) | resource | +| [aws_route53_zone.domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | +| [aws_route53_zone.ptr_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone) | resource | +| [aws_route53_zone_association.east_domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association) | resource | +| [aws_route53_zone_association.east_ptr_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association) | resource | +| [aws_route53_zone_association.west_domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association) | resource | +| [aws_route53_zone_association.west_ptr_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_zone_association) | resource | +| [aws_route53_resolver_rules.all_rules](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_resolver_rules) | data source | +| [aws_route53_zone.domain_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [dns\_zone\_create](#input\_dns\_zone\_create) | Flag determing to create (true) or associate (false) the main forward zone. Used for the same VPC domain name across different regions or VPCs | `bool` | `true` | no | +| [dns\_zone\_description\_prefix](#input\_dns\_zone\_description\_prefix) | Zone description with the org-project-program-environment | `string` | `""` | no | +| [main\_dns\_profile](#input\_main\_dns\_profile) | Profile name for AWS for the main DNS central account | `string` | `"107742151971-do2-govcloud"` | no | +| [main\_dns\_vpcs](#input\_main\_dns\_vpcs) | Map of region and VPC ids of the vpc1-services in us-gov-west-1 and us-gov-east-1 for centralized DNS | `map(string)` |
{
"us-gov-east-1": "vpc-099a991da7c4eb8a5",
"us-gov-west-1": "vpc-77877a12"
} | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [all\_zones](#output\_all\_zones) | DNS zone list |
+| [domain\_zone\_id](#output\_domain\_zone\_id) | DNS Zone ID |
+| [domain\_zone\_ns](#output\_domain\_zone\_ns) | DNS Zone Nameservers |
+| [ptr\_zone\_id](#output\_ptr\_zone\_id) | DNS PTR Zone IDs |
+| [ptr\_zone\_info](#output\_ptr\_zone\_info) | DNS PTR Zone Info |
+| [ptr\_zone\_ns](#output\_ptr\_zone\_ns) | DNS PTR Zone Nameservers |
+
\ No newline at end of file
diff --git a/examples/full-setup/apps/dns/associate-shared.tf b/examples/full-setup/apps/dns/associate-shared.tf
new file mode 100644
index 0000000..a36617b
--- /dev/null
+++ b/examples/full-setup/apps/dns/associate-shared.tf
@@ -0,0 +1,25 @@
+## locals {
+## reverse_zones = flatten([
+## "10.in-addr.arpa",
+## "168.192.in-addr.arpa",
+## "129.148.in-addr.arpa",
+## [for x in range(16, 32) : format("%v.172.in-addr.arpa", x)],
+## ])
+## reverse_rules = formatlist("reverse-%v", local.reverse_zones)
+## forward_rules = ["forward-all-onprem", "amazon"]
+## all_main_rules = formatlist("resolver-%v", concat(local.forward_rules, local.reverse_rules))
+## }
+
+data "aws_route53_resolver_rules" "all_rules" {
+ share_status = "SHARED_WITH_ME"
+}
+
+data "aws_route53_resolver_rules" "all_rules_me" {
+ share_status = "SHARED_BY_ME"
+}
+
+resource "aws_route53_resolver_rule_association" "all_rules" {
+ for_each = length(data.aws_route53_resolver_rules.all_rules.resolver_rule_ids) > 0 ? toset(data.aws_route53_resolver_rules.all_rules.resolver_rule_ids) : toset(data.aws_route53_resolver_rules.all_rules_me.resolver_rule_ids)
+ resolver_rule_id = each.key
+ vpc_id = local.vpc_id
+}
diff --git a/examples/full-setup/apps/dns/locals.tf b/examples/full-setup/apps/dns/locals.tf
new file mode 100644
index 0000000..6c49d21
--- /dev/null
+++ b/examples/full-setup/apps/dns/locals.tf
@@ -0,0 +1,13 @@
+locals {
+ base_tags = {
+ "boc:created_by" = "terraform"
+ }
+}
+
+locals {
+ vpc_info = data.terraform_remote_state.vpc_REGION_vpcN.outputs.vpc_info
+ vpc_id = local.vpc_info["vpc_id"]
+ domain_name = local.vpc_info["vpc_domain_name"]
+ dns_servers = local.vpc_info["vpc_dns_servers"]
+ vpc_short_name = local.vpc_info["vpc_short_name"]
+}
diff --git a/examples/full-setup/apps/dns/provider.main_dns.tf b/examples/full-setup/apps/dns/provider.main_dns.tf
new file mode 100644
index 0000000..0e693d1
--- /dev/null
+++ b/examples/full-setup/apps/dns/provider.main_dns.tf
@@ -0,0 +1,11 @@
+provider "aws" {
+ alias = "east_main_dns"
+ region = var.region_map["east"]
+ profile = var.main_dns_profile
+}
+
+provider "aws" {
+ alias = "west_main_dns"
+ region = var.region_map["west"]
+ profile = var.main_dns_profile
+}
diff --git a/examples/full-setup/apps/dns/region.tf b/examples/full-setup/apps/dns/region.tf
new file mode 100644
index 0000000..f617506
--- /dev/null
+++ b/examples/full-setup/apps/dns/region.tf
@@ -0,0 +1,3 @@
+locals {
+ region = var.region
+}
diff --git a/examples/full-setup/apps/dns/sort-ip.py b/examples/full-setup/apps/dns/sort-ip.py
new file mode 100755
index 0000000..293f723
--- /dev/null
+++ b/examples/full-setup/apps/dns/sort-ip.py
@@ -0,0 +1,19 @@
+#!/bin/env python
+
+import json
+import sys
+import ipaddress
+
+r=0
+outdata={'ip_addresses_sorted':''}
+try:
+ indata=json.load(sys.stdin)
+ ipa=indata['ip_addresses'].split(',')
+ ips=sorted(ipa,key=ipaddress.ip_address)
+ outdata['ip_addresses_sorted']=','.join(ips)
+ print(json.dumps(outdata))
+except:
+ sys.stderr.write("unable to parse input address\n")
+ r=1
+
+sys.exit(r)
diff --git a/examples/full-setup/apps/dns/tf-run.data b/examples/full-setup/apps/dns/tf-run.data
new file mode 100644
index 0000000..09e56f9
--- /dev/null
+++ b/examples/full-setup/apps/dns/tf-run.data
@@ -0,0 +1,11 @@
+VERSION 1.1.2
+REMOTE-STATE
+COMMAND tf-directory-setup.py -l none -f
+COMMAND setup-new-directory.sh
+COMMAND tf-init -upgrade
+
+# LINKTOP includes.d/ENVIRONMENT/variables.application_tags.auto.tfvars .
+LINKTOP includes.d/variables.application_tags.tf .
+
+ALL
+COMMAND tf-directory-setup.py -l s3
diff --git a/examples/full-setup/apps/dns/variables.dns.auto.tfvars b/examples/full-setup/apps/dns/variables.dns.auto.tfvars
new file mode 100644
index 0000000..649480f
--- /dev/null
+++ b/examples/full-setup/apps/dns/variables.dns.auto.tfvars
@@ -0,0 +1,2 @@
+dns_zone_description_prefix = "{project} {environment}"
+dns_zone_create = true
diff --git a/examples/full-setup/apps/dns/variables.dns.tf b/examples/full-setup/apps/dns/variables.dns.tf
new file mode 100644
index 0000000..68ed443
--- /dev/null
+++ b/examples/full-setup/apps/dns/variables.dns.tf
@@ -0,0 +1,27 @@
+variable "main_dns_vpcs" {
+ description = "Map of region and VPC ids of the vpc1-services in us-gov-west-1 and us-gov-east-1 for centralized DNS"
+ type = map(string)
+ default = {
+ "us-gov-west-1" = "vpc-77877a12"
+ "us-gov-east-1" = "vpc-099a991da7c4eb8a5"
+ }
+}
+
+variable "main_dns_profile" {
+ description = "Profile name for AWS for the main DNS central account"
+ type = string
+ default = "107742151971-do2-govcloud"
+}
+
+
+variable "dns_zone_description_prefix" {
+ description = "Zone description with the org-project-program-environment"
+ type = string
+ default = ""
+}
+
+variable "dns_zone_create" {
+ description = "Flag determing to create (true) or associate (false) the main forward zone. Used for the same VPC domain name across different regions or VPCs"
+ type = bool
+ default = true
+}
diff --git a/examples/full-setup/apps/dns/versions.tf b/examples/full-setup/apps/dns/versions.tf
new file mode 100644
index 0000000..ec1ce3c
--- /dev/null
+++ b/examples/full-setup/apps/dns/versions.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 3.0"
+ }
+ infoblox = {
+ source = "infobloxopen/infoblox"
+ version = ">= 2.1.0"
+ }
+ }
+}
diff --git a/examples/full-setup/apps/dns/zones.tf b/examples/full-setup/apps/dns/zones.tf
new file mode 100644
index 0000000..d58dcd4
--- /dev/null
+++ b/examples/full-setup/apps/dns/zones.tf
@@ -0,0 +1,209 @@
+locals {
+ # calculate set of /24 blocks for PTR subnets from cidr bock size
+ vpc_cidr_block = local.vpc_info["vpc_cidr_block"]
+ bits = tonumber(split("/", local.vpc_cidr_block)[1])
+ split_bits = 24 - local.bits
+ _ptr_zones = local.split_bits > 0 ? { for x in range(0, pow(2, local.split_bits)) : x => cidrsubnet(local.vpc_cidr_block, local.split_bits, x) } : {}
+ ptr_zones = { for x, s in local._ptr_zones : s => {
+ index = x
+ cidr = s
+ octets = split(".", split("/", s)[0])
+ bits = tonumber(split("/", s)[1])
+ ptr_zone = format("%v.in-addr.arpa", join(".", reverse(slice(split(".", split("/", s)[0]), 0, 3))))
+ }
+ }
+
+ zone_description = var.dns_zone_description_prefix == "" ? var.dns_zone_description_prefix : format("%v ", var.dns_zone_description_prefix)
+}
+
+#---
+# domain (forward) zone
+# need to pull this ando ther forward zones up to vpc/apps/dns
+#---
+data "aws_route53_zone" "domain_zone" {
+ # provider = aws.east
+ count = var.dns_zone_create ? 0 : 1
+ name = local.domain_name
+ private_zone = true
+}
+
+resource "aws_route53_zone" "domain_zone" {
+ count = var.dns_zone_create ? 1 : 0
+ name = local.domain_name
+ comment = format("%vDNS Forward Zone %v", local.zone_description, local.domain_name)
+ force_destroy = false
+
+ vpc {
+ vpc_id = local.vpc_id
+ vpc_region = local.region
+ }
+
+ lifecycle {
+ ignore_changes = [vpc]
+ }
+
+ tags = merge(
+ local.base_tags,
+ local.common_tags,
+ var.application_tags,
+ tomap({ "Name" = local.domain_name }),
+ )
+}
+
+resource "aws_route53_vpc_association_authorization" "west_domain_zone" {
+ # provider = aws.west_main_dns
+ # for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] })
+ for_each = var.dns_zone_create ? { "zone" = aws_route53_zone.domain_zone[0] } : {}
+ zone_id = each.value.zone_id
+ vpc_region = "us-gov-west-1"
+ vpc_id = var.main_dns_vpcs["us-gov-west-1"]
+}
+
+resource "aws_route53_zone_association" "west_domain_zone" {
+ provider = aws.west_main_dns
+ for_each = var.dns_zone_create ? aws_route53_vpc_association_authorization.west_domain_zone : {}
+
+ zone_id = each.value.zone_id
+ vpc_id = each.value.vpc_id
+ vpc_region = each.value.vpc_region
+}
+
+# resource "aws_route53_zone_association" "east_domain_zone" {
+# for_each = tomap({"zone" = aws_route53_zone.domain_zone[0]})
+# zone_id = each.value.zone_id
+# vpc_region = "us-gov-east-1"
+# vpc_id = var.main_dns_vpcs["us-gov-east-1"]
+# }
+
+resource "aws_route53_vpc_association_authorization" "east_domain_zone" {
+ # provider = aws.east_main_dns
+ # for_each = tomap({ "zone" = var.dns_zone_create ? aws_route53_zone.domain_zone[0] : data.aws_route53_zone.domain_zone[0] })
+ for_each = var.dns_zone_create ? { "zone" = aws_route53_zone.domain_zone[0] } : {}
+
+ zone_id = each.value.zone_id
+ vpc_region = "us-gov-east-1"
+ vpc_id = var.main_dns_vpcs["us-gov-east-1"]
+}
+
+resource "aws_route53_zone_association" "east_domain_zone" {
+ provider = aws.east_main_dns
+ for_each = var.dns_zone_create ? aws_route53_vpc_association_authorization.east_domain_zone : {}
+ zone_id = each.value.zone_id
+ vpc_id = each.value.vpc_id
+ vpc_region = each.value.vpc_region
+}
+
+output "domain_zone_id" {
+ description = "DNS Zone ID"
+ # value = aws_route53_zone.domain_zone[0].zone_id
+ value = var.dns_zone_create ? aws_route53_zone.domain_zone[0].zone_id : data.aws_route53_zone.domain_zone[0].zone_id
+}
+
+output "domain_zone_ns" {
+ description = "DNS Zone Nameservers"
+ # value = aws_route53_zone.domain_zone[0].name_servers
+ value = var.dns_zone_create ? aws_route53_zone.domain_zone[0].name_servers : data.aws_route53_zone.domain_zone[0].name_servers
+}
+
+#---
+# ptr (reverse) zones
+#---
+resource "aws_route53_zone" "ptr_zone" {
+ for_each = local.ptr_zones
+
+ name = each.value.ptr_zone
+ comment = format("%vDNS PTR Zone %v (%v)", local.zone_description, each.value.ptr_zone, each.value.cidr)
+ force_destroy = false
+
+ vpc {
+ vpc_id = local.vpc_id
+ vpc_region = local.region
+ }
+
+ lifecycle {
+ ignore_changes = [vpc]
+ }
+
+ tags = merge(
+ local.base_tags,
+ local.common_tags,
+ var.application_tags,
+ tomap({ "Name" = each.value.ptr_zone }),
+ )
+}
+
+resource "aws_route53_vpc_association_authorization" "west_ptr_zone" {
+ # provider = aws.west_main_dns
+ for_each = aws_route53_zone.ptr_zone
+
+ zone_id = each.value.zone_id
+ vpc_region = "us-gov-west-1"
+ vpc_id = var.main_dns_vpcs["us-gov-west-1"]
+}
+
+resource "aws_route53_zone_association" "west_ptr_zone" {
+ provider = aws.west_main_dns
+ for_each = aws_route53_vpc_association_authorization.west_ptr_zone
+
+ zone_id = each.value.zone_id
+ vpc_id = each.value.vpc_id
+ vpc_region = each.value.vpc_region
+}
+
+resource "aws_route53_vpc_association_authorization" "east_ptr_zone" {
+ # provider = aws.east_main_dns
+ for_each = aws_route53_zone.ptr_zone
+
+ zone_id = each.value.zone_id
+ vpc_region = "us-gov-east-1"
+ vpc_id = var.main_dns_vpcs["us-gov-east-1"]
+}
+
+resource "aws_route53_zone_association" "east_ptr_zone" {
+ provider = aws.east_main_dns
+ for_each = aws_route53_vpc_association_authorization.east_ptr_zone
+
+ zone_id = each.value.zone_id
+ vpc_id = each.value.vpc_id
+ vpc_region = each.value.vpc_region
+}
+
+## resource "aws_route53_zone_association" "west_ptr_zone" {
+## for_each = aws_route53_zone.ptr_zone
+## zone_id = each.value.zone_id
+## vpc_region = "us-gov-west-1"
+## vpc_id = var.main_dns_vpcs["us-gov-west-1"]
+## }
+##
+## resource "aws_route53_zone_association" "east_ptr_zone" {
+## for_each = aws_route53_zone.ptr_zone
+## zone_id = each.value.zone_id
+## vpc_region = "us-gov-east-1"
+## vpc_id = var.main_dns_vpcs["us-gov-east-1"]
+## }
+##
+
+output "ptr_zone_id" {
+ description = "DNS PTR Zone IDs"
+ value = { for x, s in local.ptr_zones : x => aws_route53_zone.ptr_zone[x].zone_id }
+}
+
+output "ptr_zone_ns" {
+ description = "DNS PTR Zone Nameservers"
+ value = { for x, s in local.ptr_zones : x => aws_route53_zone.ptr_zone[x].name_servers }
+}
+
+output "ptr_zone_info" {
+ description = "DNS PTR Zone Info"
+ value = { for x, s in local.ptr_zones : x => {
+ cidr = s.cidr
+ ptr_zone = s.ptr_zone
+ zone_id = aws_route53_zone.ptr_zone[x].zone_id
+ name_servers = aws_route53_zone.ptr_zone[x].name_servers
+ } }
+}
+
+output "all_zones" {
+ description = "DNS zone list"
+ value = flatten(concat([local.domain_name], [for x, s in local.ptr_zones : s.ptr_zone]))
+}