Skip to content

terraform-aws-arc-network

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Known Vulnerabilities

Introduction

SourceFuse's AWS Reference Architecture (ARC) Terraform module facilitates the management of AWS VPC and associated networking resources. It includes features like VPC creation, Client VPN, and VPC endpoints for services like S3 and DynamoDB, enhancing network connectivity and security.

For more information about this repository and its usage, please see Terraform AWS ARC Network Module Usage Guide.

arc_network_hla

Create the following resources in a single region.

  • VPC
  • Multi-AZ private and public subnets
  • Route tables, internet gateway, and NAT gateways
  • Configurable VPN Gateway
  • Configurable Client VPN Endpoint
  • Configurable VPC Endpoints

Prerequisites

Before using this module, ensure you have the following:

  • AWS credentials configured.
  • Terraform installed.
  • A working knowledge of Terraform.

Usage

See the examples folder for a complete example.

module "network" {
  source                      = "sourcefuse/arc-network/aws"
  version                     = "2.6.10"
  namespace                   = var.namespace
  environment                 = var.environment
  availability_zones          = var.availability_zones
  vpc_ipv4_primary_cidr_block = var.vpc_ipv4_primary_cidr_block
  client_vpn_enabled          = false
  tags                        = module.tags.tags
  client_vpn_authorization_rules = [
    {
      target_network_cidr  = var.vpc_ipv4_primary_cidr_block
      authorize_all_groups = true
      description          = "default authorization group to allow all authenticated clients to access the vpc"
    }
  ]

  vpc_endpoint_config = {
    s3         = true
    kms        = false
    cloudwatch = false
    elb        = false
    dynamodb   = true
    ec2        = false
    sns        = true
    sqs        = true
    ecs        = true
    rds        = true
  }
  gateway_endpoint_route_table_filter = ["*private*"]
}

custom-subnets example

module "network" {
  source                      = "sourcefuse/arc-network/aws"
  version                     = "2.6.10"

  namespace                   = var.namespace
  environment                 = var.environment
  availability_zones          = var.availability_zones
  vpc_ipv4_primary_cidr_block = var.vpc_ipv4_primary_cidr_block
  client_vpn_enabled          = true

  ## custom subnets
  custom_subnets_enabled = true
  custom_private_subnets = [
    {
      name              = "${var.namespace}-${var.environment}-private-${var.region}a"
      availability_zone = "${var.region}a"
      cidr_block        = "10.0.0.0/19"
    },
    {
      name              = "${var.namespace}-${var.environment}-private-${var.region}b"
      availability_zone = "${var.region}b"
      cidr_block        = "10.0.64.0/19"
    }
  ]
  custom_public_subnets = [
    {
      name              = "${var.namespace}-${var.environment}-public-${var.region}a"
      availability_zone = "${var.region}a"
      cidr_block        = "10.0.96.0/20"
    },
    {
      name              = "${var.namespace}-${var.environment}-public-${var.region}b"
      availability_zone = "${var.region}b"
      cidr_block        = "10.0.112.0/20"
    }
  ]

  // If have disabled the default nat gateways for your custom subnetes
  // then you need to pass a nat gateway id for each private subnet that
  // you are creating. If custom_az_ngw_ids is left empty in this case
  // then no default route is created by the module.

  custom_nat_gateway_enabled = false
  custom_az_ngw_ids = {
    "us-east-1a" = "ngw-13df3f3" // Dummy NAT gateway IDs. Use data sources or resource attributes instead.
    "us-east-1b" = "ngw-12cesc3"
  }

  client_vpn_authorization_rules = [
    {
      target_network_cidr  = var.vpc_ipv4_primary_cidr_block
      authorize_all_groups = true
      description          = "default authorization group to allow all authenticated clients to access the vpc"
    }
  ]
  // if no vpc endpoint is required then you can remove this block with gateway_endpoint_route_table_filter
  vpc_endpoint_config = {
    s3         = true
    kms        = false
    cloudwatch = false
    elb        = false
    dynamodb   = true
    ec2        = false
    sns        = true
    sqs        = true
    ecs        = true
    rds        = true
  }

  gateway_endpoint_route_table_filter = ["*private*"]

  tags = module.tags.tags
}

Configuring your VPN Client

Please reference the AWS Documentation on how to configure the client once the VPN has been configured in AWS.

The pki keys and certificates can be obtained from the respective SSM parameters and can be used to generate client certificate for mutual authentication using easy-rsa.

You shall need to copy the ca cert and ca key to:

/path/etc/pki/ca.crt

and

/path/etc/pki/private/ca.key

respectively to use the ca certificate and key generated in this module for mutual auth.

Requirements

Name Version
terraform ~> 1.3
aws >= 3.0.0, >= 4.0.0, >= 4.9.0
awsutils ~> 0.15

Providers

Name Version
aws 4.57.0

Modules

Name Source Version
client_vpn git::https://github.com/cloudposse/terraform-aws-ec2-client-vpn 0.14.0
custom_subnets ./modules/subnets n/a
private_subnets git::https://github.com/cloudposse/terraform-aws-multi-az-subnets.git 0.15.0
public_subnets git::https://github.com/cloudposse/terraform-aws-multi-az-subnets.git 0.15.0
vpc git::https://github.com/cloudposse/terraform-aws-vpc.git 2.0.0
vpc_endpoints git::https://github.com/cloudposse/terraform-aws-vpc.git//modules/vpc-endpoints 2.0.0

Resources

Name Type
aws_dx_connection.this resource
aws_vpc_endpoint.cloudwatch_endpoint resource
aws_vpc_endpoint.dynamodb_endpoint resource
aws_vpc_endpoint.ec2_endpoint resource
aws_vpc_endpoint.ecs resource
aws_vpc_endpoint.elb_endpoint resource
aws_vpc_endpoint.kms_endpoint resource
aws_vpc_endpoint.rds resource
aws_vpc_endpoint.s3_endpoint resource
aws_vpc_endpoint.sns_endpoint resource
aws_vpc_endpoint.sqs_endpoint resource
aws_vpn_gateway.this resource
aws_iam_policy_document.dynamodb data source
aws_route_tables.gateway data source

Inputs

Name Description Type Default Required
assign_generated_ipv6_cidr_block When true, assign AWS generated IPv6 CIDR block to the VPC. Conflicts with ipv6_ipam_pool_id. bool true no
auto_generate_multi_az_subnets Auto-generate subnets in defined availability zones. This value is overridden if the variable custom_subnets_enabled
is set to true. This is to avoid conflicts within the VPC network configuration.
bool true no
availability_zones List of availability zones to deploy resources in. list(string) n/a yes
aws_dx_connection_name_override AWS DX Connection. If left undefined, this will use the naming convention of
namespace-environment-dx-connection.
string null no
aws_region Specify region for VPC endpoints string "us-east-1" no
client_vpn_allowed_security_group_ids A list of IDs of Security Groups to allow access to the security group created by this module.
The length of this list must be known at "plan" time.
list(string) [] no
client_vpn_associated_security_group_ids A list of IDs of Security Groups to associate the VPN endpoints with, in addition to the created security group.
These security groups will not be modified and, if create_security_group is false, must have rules providing the desired access.
list(string) [] no
client_vpn_authorization_rules List of objects describing the authorization rules for the client vpn list(map(any)) n/a yes
client_vpn_client_cidr_block CIDR block to be assigned tpo VPN clients string "10.1.0.0/16" no
client_vpn_create_security_group Set true to create and configure a new security group. If false, associated_security_group_ids must be provided. bool true no
client_vpn_enabled Enable client VPN endpoint bool false no
client_vpn_logging_enabled Enable/disable CloudWatch logs for client VPN bool true no
client_vpn_name_override Client VPN Name override. If left undefined, this will use the naming convention of
namespace-environment-client-vpn.
string null no
client_vpn_organization_name Organization name for self signed certificates string "" no
client_vpn_retention_in_days Number of days to retain the client VPN logs on CloudWatch number 30 no
client_vpn_split_tunnel Enable/disable split tunnel bool true no
cloudwatch_endpoint_name_override CloudWatch endpoint name. If left undefined, this will use the naming convention of
namespace-environment-cloudwatch-endpoint.
string null no
custom_az_ngw_ids Only for private subnets. Map of AZ names to NAT Gateway IDs that are used as default routes when creating private subnets.
You should either supply one NAT Gateway ID for each AZ in var.availability_zones or leave the map empty.
If empty, no default egress route will be created and you will have to create your own using aws_route.
map(string) {} no
custom_create_aws_network_acl This indicates whether to create aws network acl or not bool false no
custom_nat_gateway_enabled Enable the NAT Gateway between public and private subnets bool true no
custom_private_network_acl_egress Egress network ACL rules
list(object({
rule_no = number
action = string
cidr_block = string
from_port = number
to_port = number
protocol = string
icmp_code = optional(string, null)
icmp_type = optional(string, null)
ipv6_cidr_block = optional(string, null)
}))
[
{
"action": "allow",
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_no": 100,
"to_port": 0
}
]
no
custom_private_network_acl_ingress Ingress network ACL rules
list(object({
rule_no = number
action = string
cidr_block = string
from_port = number
to_port = number
protocol = string
icmp_code = optional(string, null)
icmp_type = optional(string, null)
ipv6_cidr_block = optional(string, null)
}))
[
{
"action": "allow",
"cidr_block": "0.0.0.0/0",
"from_port": 0,
"protocol": "-1",
"rule_no": 100,
"to_port": 0
}
]
no
custom_private_network_acl_subnet_ids Private network ACL Subnet IDs. This is typically unused due to using the default_network_acl_id. list(string) [] no
custom_private_route_table_additional_tags Additional tags to add to the private route table map(string) {} no
custom_private_subnets List of private subnets to add to the VPC
list(object({
name = string
availability_zone = string
cidr_block = string
tags = optional(map(string), {})
}))
[] no
custom_public_route_table_additional_tags Additional tags to add to the public route table map(string) {} no
custom_public_subnets List of public subnets to add to the VPC
list(object({
name = string
availability_zone = string
cidr_block = string
map_public_ip_on_launch = optional(bool, false)
igw_id = optional(string, "")
tags = optional(map(string), {})
}))
[] no
custom_route_table_association_enabled If the route table has an association. bool true no
custom_subnets_enabled Set to true to allow custom subnet configuration.
If this is set to true, the variable auto_generate_multi_az_subnets will be overridden and not create the
multi-az subnets.
bool false no
default_network_acl_deny_all When true, manage the default network acl and remove all rules, disabling all ingress and egress.
When false, do not mange the default networking acl, allowing it to be managed by another component.
bool false no
default_route_table_no_routes When true, manage the default route table and remove all routes, disabling all ingress and egress.
When false, do not mange the default route table, allowing it to be managed by another component.
Conflicts with Terraform resource aws_main_route_table_association.
bool false no
default_security_group_deny_all When true, manage the default security group and remove all rules, disabling all ingress and egress.
When false, do not manage the default security group, allowing it to be managed by another component.
bool true no
direct_connect_bandwidth The bandwidth of the connection.
Valid values for dedicated connections: 1Gbps, 10Gbps.
Valid values for hosted connections: 50Mbps, 100Mbps, 200Mbps, 300Mbps, 400Mbps, 500Mbps, 1Gbps, 2Gbps, 5Gbps, 10Gbps and 100Gbps.
Case sensitive.
string "10Gbps" no
direct_connect_enabled Enable direct connect. bool false no
direct_connect_encryption_mode The connection MAC Security (MACsec) encryption mode. MAC Security (MACsec) is only available on dedicated connections. Valid values are no_encrypt, should_encrypt, and must_encrypt. string "must_encrypt" no
direct_connect_location The location of AWS Direct Connect. Use aws directconnect describe-locations for the list of AWS Direct Connect locations. Use locationCode for the value. string null no
direct_connect_provider The name of the service provider associated with the connection. string null no
direct_connect_request_macsec Boolean value indicating whether you want the connection to support MAC Security (MACsec).
MAC Security (MACsec) is only available on dedicated connections.
Changing this value will cause the resource to be destroyed and re-created.
See MACsec prerequisites for more information.
bool false no
direct_connect_skip_destroy et to true if you do not wish the connection to be deleted at destroy time, and instead just removed from the Terraform state. bool false no
dns_hostnames_enabled Set true to enable DNS hostnames in the VPC bool true no
dns_support_enabled Set true to enable DNS resolution in the VPC through the Amazon provided DNS server bool true no
dynamodb_endpoint_name_override DynamoDB endpoint name. If left undefined, this will use the naming convention of
namespace-environment-dynamodb-endpoint.
string null no
ec2_endpoint_name_override EC2 endpoint name. If left undefined, this will use the naming convention of
namespace-environment-ec2-endpoint.
string null no
ecs_endpoint_name_override ECS endpoint name. If left undefined, this will use the naming convention of
namespace-environment-ecs-endpoint.
string null no
elb_endpoint_name_override ELB endpoint name. If left undefined, this will use the naming convention of
namespace-environment-elb-endpoint.
string null no
environment Name of the environment, i.e. dev, stage, prod string n/a yes
gateway_endpoint_route_table_filter List of strings to filter route tables , eg [ 'private' , 'public' ] list(string) [] no
gateway_vpc_endpoints A map of Gateway VPC Endpoints to provision into the VPC. This is a map of objects with the following attributes:
- name: Short service name (either "s3" or "dynamodb")
- policy = A policy (as JSON string) to attach to the endpoint that controls access to the service. May be null for full access.
- route_table_ids: List of route tables to associate the gateway with. Routes to the gateway
will be automatically added to these route tables.
map(object({
name = string
policy = string
route_table_ids = list(string)
}))
{} no
interface_vpc_endpoints A map of Interface VPC Endpoints to provision into the VPC.
This is a map of objects with the following attributes:
- name: Simple name of the service, like "ec2" or "redshift"
- policy: A policy (as JSON string) to attach to the endpoint that controls access to the service. May be null for full access.
- private_dns_enabled: Set true to associate a private hosted zone with the specified VPC
- security_group_ids: The ID of one or more security groups to associate with the network interface. The first
security group will replace the default association with the VPC's default security group. If you want
to maintain the association with the default security group, either leave security_group_ids empty or
include the default security group ID in the list.
- subnet_ids: List of subnet in which to install the endpoints.
map(object({
name = string
policy = string
private_dns_enabled = bool
security_group_ids = list(string)
subnet_ids = list(string)
}))
{} no
internet_gateway_enabled Set true to create an Internet Gateway for the VPC bool true no
ipv6_egress_only_internet_gateway_enabled Set true to create an IPv6 Egress-Only Internet Gateway for the VPC bool false no
kms_endpoint_name_override KMS Endpoint name. If left undefined, this will use the naming convention of
namespace-environment-kms-endpoint.<br>
string null no
namespace Namespace of the project, i.e. refarch string n/a yes
private_dns_enabled Whether to enable Private DNS for the endpoint(s) bool true no
private_subnet_name_override Private Subnets name. If left undefined, this will use the naming convention of
namespace-environment-private-subnet.
string null no
public_subnet_name_override Public Subnets name. If left undefined, this will use the naming convention of
namespace-environment-public-subnet.
string null no
rds_endpoint_name_override RDS endpoint name. If left undefined, this will use the naming convention of
namespace-environment-rds-endpoint.
string null no
s3_endpoint_name_override S3 endpoint name. If left undefined, this will use the naming convention of
namespace-environment-s3-endpoint.
string null no
sns_endpoint_name_override SNS endpoint name. If left undefined, this will use the naming convention of
namespace-environment-sns-endpoint.
string null no
sqs_endpoint_name_override SQS endpoint name. If left undefined, this will use the naming convention of
namespace-environment-sqs-endpoint.
string null no
tags Default tags to apply to every resource map(string) n/a yes
vpc_endpoint_config Map variable that toggles the enablement of an application map(bool)
{
"cloudwatch": false,
"dynamodb": false,
"ec2": false,
"ecs": false,
"elb": false,
"kms": false,
"rds": false,
"s3": false,
"sns": false,
"sqs": false
}
no
vpc_endpoint_type The VPC endpoint type, Gateway, GatewayLoadBalancer, or Interface. string "Interface" no
vpc_endpoints_enabled Enable VPC endpoints. bool false no
vpc_ipv4_primary_cidr_block IPv4 CIDR block for the VPC to use. string n/a yes
vpc_name_override VPC Name override. If left undefined, this will use the naming convention of
namespace-environment-vpc.
string null no
vpn_gateway_enabled Enable VPN Gateway. bool false no

Outputs

Name Description
default_route_table_id The Default Route Table ID for the VPC
full_client_configuration Client configuration including client certificate and private key
igw_id Internet gateway ID for the VPC
main_route_table_id The Main Route Table ID for the VPC
private_subnet_cidrs Private subnet CIDRs
private_subnet_ids Private subnet IDs
public_subnet_cidrs Public subnet CIDRs
public_subnet_ids Public subnet IDs
vpc_cidr The VPC CIDR block
vpc_default_network_acl_id The ID of the network ACL created by default on VPC creation
vpc_id The VPC ID
vpn_endpoint_arn The ARN of the Client VPN Endpoint Connection.
vpn_endpoint_dns_name The DNS Name of the Client VPN Endpoint Connection.
vpn_subnets subnets associated with the VPN

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
    pre-commit install
    
  • Configure golang deps for tests
    go get github.com/gruntwork-io/terratest/modules/terraform
    go get github.com/stretchr/testify/assert
    

Git commits

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"
By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly

Tests

  • Tests are available in test directory
  • In the test directory, run the below command
    go test -timeout 1800s
    

Authors

This project is authored by: - SourceFuse