Skip to content

Latest commit

 

History

History
354 lines (266 loc) · 16 KB

File metadata and controls

354 lines (266 loc) · 16 KB

Network Spoke Account with Terraform

Overview

This example demonstrates a matching spoke VPC that is consistent, cost efficient and automatable to join to the example hub account to consume centralised network services.

  • Consistent: allows reasoning about all of your AWS organization's network state
  • Cost efficient: Removes requirement for per-VPC NAT Gateway and VPC Endpoints
  • Automatable: Simple VPC deployment can be tied in to other processes such as account creation automation.

The following resources will be deployed by this example:

  • a VPC with a CIDR assigned by AWS VPC IP Address Manager
  • 3 Endpoint Subnets
  • 3 Private Subnets
  • Local VPC Endpoints
  • TGW Attachment, Association and Propagation
  • Route 53 Resolver Rule Association
  • Private Hosted Zone

The resources deployed and the architectural pattern they follow are provided for demonstration and testing purposes but are based on and inspired by AWS best practice and articles.

Table of Contents

Diagrams

Solution Diagram diagram

Transit Gateway tgw

VPC Endpoints vpc_endpoints

Network Firewall nfw

Route 53 Resolver dns

Useful Links


Prerequisites

Tooling

  • Terraform ~> 1.1
    • AWS provider ~> 3.0
  • AWS CLI
  • Git CLI

Infrastructure

  • AWS Organization
    • RAM enabled to Org
    • IPAM delegated to network hub account
  • Centralised network account with Hub Solution deployed
  • Spoke account to deploy into
  • IAM role with required permissions
    • Tag all roles with automation = true

iam_tag

Customisation If you do not define a remote backend Terraform will use the local directory to store the local backend files including tfstate. Examples of how to customise the Terraform backend are included but commented out.

backend

Example GitLab HTTP backend for use with GitLab CI.

http_backend

Update network hub account ID in config.auto.tfvars per environment.

aws_region                = "eu-west-2"
vpc_endpoints             = ["s3"]
centralised_vpc_endpoints = ["ec2", "rds", "sqs", "sns", "ssm", "logs", "ssmmessages", "ec2messages", "autoscaling", "ecs", "athena"]

env_config = {
 dev = {
   network_hub_account_number = "<Network_Hub_Account_ID>"
   tgw_route_tables           = ["shared", "dev"]
   root_domain                = "network-dev.internal."
 }
 test = {
   network_hub_account_number = "<Network_Hub_Account_ID>"
   tgw_route_tables           = ["shared", "dev"]
   root_domain                = "network-test.internal."
 }
 preprod = {
   network_hub_account_number = "<Network_Hub_Account_ID>"
   tgw_route_tables           = ["shared", "dev"]
   root_domain                = "network-preprod.internal."
 }
 prod = {
   network_hub_account_number = "<Network_Hub_Account_ID>"
   tgw_route_tables           = ["shared", "prod"]
   root_domain                = "network-prod.internal."
 }
}

Quick Start

Deploy from client machine

When deploying from your local machine having configured the TF Backend in the code you need to ensure you have access to read and write to the backend - possible backends include HTTP, Consul, Postgres, Artifactory, S3 or S3 + DynamoDB. We initialise the Terraform, complete the validate and format. Review the plan and then apply.

  • terraform init
  • terraform validate
  • set environment for deployment
    • export TF_VAR_environment=" **ENV** "
    • Set-Item -Path env:TF_VAR_environment -Value “ **ENV** “ (Possible Env values * dev, test, preprod, prod)
  • terraform plan
  • terraform apply or terraform apply --auto-approve

Tagging

Tags are added to all AWS resources through use of the tag configuration of the AWS Provider.

As not all AWS resources support default tags passed from the provider (EC2 Auto-Scaling Group + Launch Template) We pass the tags as a variable (Map(string) - these are defined in the root locals.tf file.

provider

Example Tags - locals.tf

tags = {
  Product    = "Network_Automation"
  Owner      = "GitHub"
  Project_ID = "12345"
}

Clean Up

Remember to clean up after your work is complete. You can do that by doing terraform destroy.

Note that this command will delete all the resources previously created by Terraform.

Terraform Docs

Requirements

Name Version
terraform ~> 1.1
aws ~> 3.0

Providers

Name Version
aws ~> 3.0
aws.network_hub ~> 3.0

Modules

Name Source Version
dns ./modules/dns n/a
network ./modules/network n/a

Resources

Name Type
aws_availability_zones.available data source
aws_ec2_transit_gateway.org_env data source
aws_ec2_transit_gateway_route_table.associate data source
aws_ec2_transit_gateway_route_table.org_env data source

Inputs

Name Description Type Default Required
aws_region AWS region being deployed to string n/a yes
az_count Number of availability zones number 2 no
centralised_vpc_endpoints Which centralised VPC endpoints to consume list(string) n/a yes
env_config Map of objects for per environment configuration
map(object({
network_hub_account_number = string
tgw_route_tables = list(string)
root_domain = string
}))
n/a yes
environment Deployment environment passed as argument or environment variable string n/a yes
tags Default tags to apply to all resources map(string) n/a yes
vpc_endpoints Which local VPC endpoints to deploy list(string) n/a yes
vpc_name Name of the VPC string "spoke" no

Outputs

Name Description
vpc_id VPC ID used for other modules

Requirements

Name Version
terraform ~> 1.1
aws ~> 3.0

Providers

Name Version
aws ~> 3.0
aws.network_hub ~> 3.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_log_group.flow_logs resource
aws_default_security_group.default resource
aws_ec2_transit_gateway_route_table_association.env resource
aws_ec2_transit_gateway_route_table_propagation.org resource
aws_ec2_transit_gateway_vpc_attachment.vpc_endpoint resource
aws_egress_only_internet_gateway.spoke_vpc resource
aws_flow_log.vpc resource
aws_iam_role.flow_logs resource
aws_iam_role_policy.flow_logs resource
aws_kms_key.log_key resource
aws_route.default_route resource
aws_route.default_route_ipv6 resource
aws_route53_record.dev-ns resource
aws_route53_zone.interface_phz resource
aws_route_table.spoke_vpc resource
aws_route_table_association.app_subnet resource
aws_route_table_association.endpoint_subnet resource
aws_security_group.allow_vpc_endpoint resource
aws_security_group_rule.local_cidr resource
aws_subnet.app_subnet resource
aws_subnet.endpoint_subnet resource
aws_vpc.spoke_vpc resource
aws_vpc_dhcp_options.spoke_vpc resource
aws_vpc_dhcp_options_association.spoke_vpc resource
aws_vpc_endpoint.interface resource
aws_caller_identity.current data source
aws_iam_policy_document.policy_kms_logs_document data source
aws_ssm_parameter.ipam_pool data source

Inputs

Name Description Type Default Required
aws_region AWS region being deployed to string n/a yes
az_names A list of the Availability Zone names available to the account list(string) n/a yes
environment Deployment environment passed as argument or environment variable string n/a yes
interface_endpoints Object representing the region and services to create interface endpoints for map(string) n/a yes
network_hub_account_number Network Hub account ID string n/a yes
tgw TGW ID for VPC attachments string n/a yes
tgw_association TGW route table to associate to string n/a yes
tgw_route_table TGW route tables for VPC association and propagation map(string) n/a yes
vpc_name Name of the VPC string "spoke" no

Outputs

Name Description
vpc_id VPC ID used for other modules

Requirements

Name Version
terraform ~> 1.1
aws ~> 3.0

Providers

Name Version
aws ~> 3.0
aws.network_hub ~> 3.0

Modules

No modules.

Resources

Name Type
aws_route53_record.ns_record resource
aws_route53_resolver_rule_association.root_domain resource
aws_route53_vpc_association_authorization.delegated_private resource
aws_route53_vpc_association_authorization.endpoint_phz resource
aws_route53_zone.delegated_private resource
aws_route53_zone_association.delegated_private resource
aws_route53_zone_association.endpoint_phz resource
aws_caller_identity.current data source
aws_route53_resolver_rule.root_domain data source
aws_route53_zone.centralised_endpoints data source
aws_route53_zone.selected data source
aws_vpc.endpoint data source
aws_vpc.selected data source

Inputs

Name Description Type Default Required
aws_region AWS region being deployed to string n/a yes
centralised_vpc_endpoints Which centralised VPC endpoints to consume map(string) n/a yes
environment Deployment environment passed as argument or environment variable string n/a yes
network_hub_account_number Network Hub account ID string n/a yes
root_domain Root domain for the delegated private hosted zone string n/a yes
vpc_id VPC ID to associate delegated subdomain to string n/a yes

Outputs

No outputs.