Create your own Cloud Native Multi-Cloud network in minutes using Terraform generator

Pawan Uberoy
epiphani
Published in
4 min readMar 23, 2021

Do you have apps that are in different clouds or regions and need to talk to each other over a private network segment? Or do you have to access cloud resources (like S3/DynamoDB) from different clouds on a secure network?

You can easily use epica arena to create a multi-cloud full mesh network in minutes. This network uses all cloud native functions so you can control your own resources and get the best latency and performance.

A generated terraform template is created from the No-Code UI that can be used to deploy the network in minutes.

Supported clouds: AWS, Google and Azure

Connects: Virtual Networks, VPCs, IPSEC VPN endpoints, S3, DynamoDB

You can also use this to provision IPSEC VPN endpoints that you can connect from branches to become part of the network.

Login here: https://www.epicanet.com

Step 1: Login to epica, run discovery using ephemeral keys for the cloud. This is optional, you can also upload your VPCs or configure them manually if you want

Step 2: Create the connections you want by clicking the network segments. You can create network segments by assigning them to app groups

This will connect the VPC to the other parts of the network.

If you wish to do network segmentation you can just apply an app group label to the network. The security policies for the network segment can also be created in a cloud agnostic fashion and will be included in the generated terraform template.

Step 3: Hit the “Publish” button the top right. This will create a template and download it to your computer.

Here is a representation of the network in a graph:

The actual network that is created uses all cloud native functions, here is an example of a generated terraform firewall template:

Here is a short video: https://youtu.be/JluuJNnaaA0

terraform {
required_providers {
aws = {
version = "3.28.0-ram-accepter-fix"
source = "epiphani.io/fixes/aws"
}
}
}
provider "aws" {
alias = "epiphani"
}
resource "aws_ec2_transit_gateway_vpc_attachment" "inspect-vpc-attachment" {
provider = aws.epiphani
subnet_ids = [var.fw_in_subnet_id]
transit_gateway_id = var.tgw_id
vpc_id = var.inspect_vpc_id
transit_gateway_default_route_table_association = false
transit_gateway_default_route_table_propagation = false
tags = {
Name = "inspect-vpc-attachment"
}
}
resource "aws_networkfirewall_rule_group" "app_groups" {
provider = aws.epiphani
for_each = var.rule_groups
capacity = 1000
name = each.value.name
type = "STATELESS"
rule_group {
rules_source {
stateless_rules_and_custom_actions {
dynamic stateless_rule {
#for_each = var.rule_groups[count.index].rules
for_each = each.value.rules
content {
priority = stateless_rule.value.priority
rule_definition {
actions = [stateless_rule.value.action]
match_attributes {
dynamic source {
for_each = stateless_rule.value.source
content {
address_definition = source.value
}
}
dynamic destination {
for_each = stateless_rule.value.destination
content {
address_definition = destination.value
}
}
dynamic source_port {
for_each = stateless_rule.value.source_port
content {
from_port = source_port.value.from_port
to_port = source_port.value.to_port
}
}
dynamic destination_port {
for_each = stateless_rule.value.destination_port
content {
from_port = destination_port.value.from_port
to_port = destination_port.value.to_port
}
}
protocols = stateless_rule.value.protocols
}
}
}
}
}
}
}
}
resource "aws_networkfirewall_firewall_policy" "inspect" {
provider = aws.epiphani
name = "inspect"
depends_on = [aws_networkfirewall_rule_group.app_groups]
firewall_policy {
stateless_default_actions = ["aws:drop"]
stateless_fragment_default_actions = ["aws:drop"]
dynamic stateless_rule_group_reference {
for_each = local.r_arns
content {
priority = stateless_rule_group_reference.value.pri
resource_arn = stateless_rule_group_reference.value.arn
}
}
}
}
resource "aws_networkfirewall_firewall" "inspect" {
provider = aws.epiphani
depends_on = [aws_networkfirewall_firewall_policy.inspect]
firewall_policy_arn = aws_networkfirewall_firewall_policy.inspect.arn
name = "inspect"
vpc_id = var.inspect_vpc_id
subnet_mapping {
subnet_id = var.fw_out_subnet_id
}
}
locals {
endpoints = flatten([
for fw_status in aws_networkfirewall_firewall.inspect.firewall_status: [
for sync_state in fw_status.sync_states: [
for attachment in sync_state.attachment: attachment.endpoint_id
]
]
])
r_arns = flatten([
for agrp in aws_networkfirewall_rule_group.app_groups: [
for ref in var.policy_refs: {
arn = agrp.arn
pri = ref.priority
}
if (ref.name == agrp.name)
]
])
}
resource "aws_route_table" "tgw" {
provider = aws.epiphani
vpc_id = var.inspect_vpc_id
route {
cidr_block = "0.0.0.0/0"
vpc_endpoint_id = local.endpoints[0]
}
tags = {
Name = "tgw"
}
}
resource "aws_route_table_association" "tgw" {
provider = aws.epiphani
route_table_id = aws_route_table.tgw.id
subnet_id = var.fw_in_subnet_id
}
resource "aws_route_table" "fw" {
provider = aws.epiphani
vpc_id = var.inspect_vpc_id
route {
cidr_block = "0.0.0.0/0"
transit_gateway_id = var.tgw_id
}
tags = {
Name = "fw"
}
}
resource "aws_route_table_association" "fw" {
provider = aws.epiphani
route_table_id = aws_route_table.fw.id
subnet_id = var.fw_out_subnet_id
}
resource "aws_ec2_transit_gateway_route_table_association" "fw" {
provider = aws.epiphani
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.inspect-vpc-attachment.id
transit_gateway_route_table_id = var.firewall_rtt_id
}
resource "aws_ec2_transit_gateway_route" "example" {
provider = aws.epiphani
destination_cidr_block = "0.0.0.0/0"
transit_gateway_attachment_id = aws_ec2_transit_gateway_vpc_attachment.inspect-vpc-attachment.id
transit_gateway_route_table_id = var.spoke_rtt_id
}

--

--