This repository contains terraform code to deploy a sample AWS Hub and Spoke architecture with Shared Services VPC, with the following centralized services:
- Managing EC2 instances using AWS Sytems Manager - ssm, ssmmessages and ec2messages VPC Endpoints.
- Amazon S3 access (the IAM role created for the EC2 instances allows READ ONLY access). If you want to change it, check the code in the compute module
- Hybrid DNS, both inbound and outbound Route 53 Resolver Endpoints are created.
The resources deployed and the architectural pattern they follow is purely for demonstration/testing purposes.
- An AWS account with an IAM user with the appropriate permissions
- Terraform installed
- Writing DRY (Do No Repeat Yourself) code using a modular design pattern
- Clone the repository
- Edit the variables.tf file in the project root directory. This file contains the variables that are used to configure the VPCs to create, and Hybrid DNS configuration needed to work with your environment.
- To change the configuration about the Security Groups and VPC endpoints to create, edit the locals.tf file in the project root directory
- Initialize Terraform using
terraform init
- Deploy the template using
terraform apply
Note The default number of Availability Zones to use in the Spoke VPCs is 1. For the Shared Services VPC, the default (and minimum) number of AZs to use is 2 - due to configuration requirements for Route 53 Resolver Endpoints. To follow best practices, each resource - EC2 instance, VPC endpoints, and Route 53 Resolver Endpoints - will be created in each Availability Zone. Keep this in mind to avoid extra costs unless you are happy to deploy more resources and accept additional costs.
- To centralize the SSM access for the instances created in the Spoke VPCs, 3 VPC endpoints are created with "Private DNS" option disabled: ssm, ssmmessages, and ec2messages. 3 Private Hosted Zones are created and associated with all the VPCs created (Spoke VPCs and Shared Services VPC) to allow DNS resolution.
- The fourth VPC endpoint created is to access Amazon S3. As indicated before, the EC2 instance roles only have read permission.
- Amazon S3 interface endpoints do not support the private DNS feature. However, thanks to the use of Private Hosted Zones, you can access S3 without having to use the VPC endpoint DNS name all the time. Two resource records are created within the S3 PHZ: one for the apex of the domain, and the second as a wildcard to allow all records within this domain to be resolved to the VPC endpoint. One example you can use to test the access to S3 is the following one:
aws s3 --region {aws_region} ls s3://
Both Amazon Route 53 Inbound and Outbound Resolver Endpoints are created. The configuration applied in the variables.tf file is not valid (example values). To use the example with your real-environment, please change the following variables:
- on_premises_cidr: Indicate the CIDR block of your on-premises location to allow DNS traffic in the Inbound Endpoints. This value is added in the Security Group attached to that endpoint.
- forwarding_rules: Add correct values of the DNS domains and DNS servers (target IPs) in your on-premises location. This values are used by the Outbound Endpoints to forward DNS queries from AWS to your on-premises DNS servers.
- AWS Reference Architecture - Hybrid DNS Resolution with Amazon Route 53 Resolver Endpoints
- AWS Whitepaper - Building a Scalable and Secure Multi-VPC AWS Network Infrastructure
- AWS Documentation - AWS PrivateLink for Amazon S3 interface endpoints
- AWS Blogs - Secure hybrid access to Amazon S3 using AWS PrivateLink
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.
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.
Name | Version |
---|---|
terraform | >= 1.3.0 |
aws | >= 3.73.0 |
awscc | >= 0.15.0 |
Name | Version |
---|---|
aws | 4.38.0 |
Name | Source | Version |
---|---|---|
compute | ./modules/compute | n/a |
endpoint_record | ./modules/route53_record | n/a |
shared_services_vpc | aws-ia/vpc/aws | = 3.0.1 |
spoke_vpcs | aws-ia/vpc/aws | = 3.0.1 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
aws_region | AWS Region to create the environment. | string |
"eu-west-2" |
no |
forwarding_rules | Forwarding rules to on-premises DNS servers. | map(any) |
{ |
no |
identifier | Project Name, used as identifer when creating resources. | string |
"hubspoke-shared-services" |
no |
on_premises_cidr | On-premises CIDR block. | string |
"192.168.0.0/16" |
no |
vpcs | VPCs to create. | any |
{ |
no |
Name | Description |
---|---|
ec2_instances | Instances created in each Spoke VPC. |
private_hosted_zones | Private Hosted Zones. |
route53_resolver_endpoints | Route 53 Resolver Endpoints. |
transit_gateway | Transit Gateway resources. |
vpc_endpoints | VPC endpoints created. |
vpcs | VPCs created. |