Building A Network


Lots of deployments start with building a network, and then working your way up the stack. This example shows you how to create a software-defined network called a Virtual Private Cloud (VPC) in Amazon Web Services using Fugue.


This example is for people new to Fugue and Ludwig. You’re welcome to window-shop it, but if you want to really do the work shown here, you’ll need to do a few quick steps to set up the Fugue CLI and install the Fugue Conductor into your AWS account.

What We’ll Do In This Example

We’ll cover making networks on AWS using Fugue. We’ll use basic Ludwig to get the job done. We’ll see some imports, a little bit of Fugue’s network definition features, and some examples on the CLI.

What We’ll Have When We’re Done

A Virtual Private Cloud (VPC) in AWS, along with a couple of subnets.

How Long It Will Take

Assuming you’re new to Fugue, about 15 minutes. Less if you can skip some of the basics, of course.


You can download the source code for this example here.

Get editor plug-ins here.

Let’s Go!


To begin with, we’ll want to declare that our file is a composition (using the composition keyword), and thus an entry point. We’ll also import the base AWS library, as well as the EC2 library.


import Fugue.AWS as AWS
import Fugue.AWS.EC2 as EC2

Making a VPC

Now that we are ready to write a Fugue composition using AWS and EC2, we can start declaring infrastructure. The foundation of our network will be the VPC, which we’ll build with the constructor, which we imported with the Fugue.AWS.EC2 module.

example-vpc: {
  cidrBlock: "",
  tags: [
    AWS.tag("Name", "My Cool VPC")
  region: AWS.Us-west-2

This gives us a nice class B network to work in with 65536 addresses in it, give or take. We’ve put the network in the us-west-2 region (Oregon), and given it the very desirable Name tag, My Cool VPC.

Making Some Subnets

We can’t directly launch instances in a VPC, and we’re going to want to segment our network anyway. Let’s make a couple of /24 subnets, both “public” (meaning they can be reached from the internet), but in different Availability Zones so that we have durability in the event of an AZ failure.

Subnet Validation at Compile-Time

Lots of Fugue modules (outside of the Core ones) contain compile-time validations for infrastructure. For example, let’s say you tried to make your public subnet with this CIDR block:

public-10-0-2-0: {
  cidrBlock: ''...

The Ludwig compiler would give you an error right away, catching this mistake very early:

"/opt/fugue/lib/Fugue/AWS/EC2/Subnet.lw" (line 38, column 5):

  38|     isValidCidrForVpc(cidrBlock, spec.vpc)

Subnet cidrBlock '' must be a subset of the Vpc cidrBlock ''

This could save you a lot of time and trouble, rather than figuring this out once things are already built!

public-10-0-1-0: {
  cidrBlock: '',
  vpc: example-vpc,
  availabilityZone: AWS.A,
  mapPublicIpOnLaunch: True,
  defaultForAz: False

public-10-0-2-0: {
  cidrBlock: '',
  vpc: example-vpc,
  availabilityZone: AWS.B,
  mapPublicIpOnLaunch: True,
  defaultForAz: False

Adding an Internet Gateway

Our public subnets aren’t going to be very effective without an Internet Gateway, which facilitates traffic flow between a VPC and the internet. We actually make our internet gateways in VPCs, but we’ll establish a route to them for our public subnets in the next step.

example-igw: {
  vpc: example-vpc

Adding a Route Table

A route table tells the VPC’s “implicit router” how to route traffic within the VPC’s subnets as well as to other networks, such as the internet.

First, we’ll write a route that sends internet-bound traffic to the internet gateway.

public-route: {
  destinationCidrBlock: "",
  target: EC2.GatewayTarget(example-igw)

Then, we’ll include that route in a route table that we associate with our public subnets.

public-route-table: {
  vpc: example-vpc,
  routes: [public-route],
  associations: [

Adding Some Security Groups

Now we have all the basic networking bits to start to build some infrastructure that uses TCP/IP. But what we have so far doesn’t pay a whole lot of attention to security. That’s an onion that is many layers deep, but we should at least establish some security groups that we can apply to instances we launch.

First, let’s make a security group that allows traffic from an Internet-wide IP range to ingress. This will be appropriate for our internet-facing instances or Elastic Load Balancers, so we’ll hint at ELBs in the binding name.

example-elb-sg: {
  description: "Allow http/s traffic from the Internet",
  ipPermissions: [
  ipPermissionsEgress: None,
  vpc: example-vpc

inet-HTTP: {
  ipProtocol: "tcp",
  fromPort: 80,
  toPort: 80,
  target: EC2.IpRanges([
    EC2.IpRange(cidrIp: "")
# Note the short form of this ^ is:
#   EC2.IpPermission.http(EC2.IpPermission.Target.all)
# Similar functions exist for common protocols. We've used the long form in this example to be more illustrative.

inet-HTTPS: {
  ipProtocol: "tcp",
  fromPort: 443,
  toPort: 443,
  target: EC2.IpRanges([
    EC2.IpRange(cidrIp: "")

Next, we probably want another security group that doesn’t allow any internet traffic, but exclusively allows traffic from instances in the security group we just created. We would likely use this security group for our application or web servers. To do this, we can use the previous security group as our target value for our IpPermission.

example-app-sg: {
  description: "Allow traffic from the internet-facing SG",
  ipPermissions: [
    EC2.IpPermission.tcp(3000, EC2.IpPermission.Target.securityGroup(example-elb-sg)),
    # This ^ is the shorthand for both IP permissions and targets.
  vpc: example-vpc

Starting the Fugue process

We can manage our network infrastructure in a single process dedicated to networking concerns by running this composition.

$ fugue run Network.lw -a example-network
[ fugue run ] Running /Users/fugueUser/Network.lw...

Compiling Ludwig file /Users/fugueUser/Network.lw
[ OK ] Successfully compiled. No errors.
Uploading compiled Ludwig composition to S3...
[ OK ] Successfully uploaded.
Asking Fugue launch and run composition infrastructure...
Fugue is running the composition FID:a6adf36d-b145-4825-8bef-20f9faada4ac, Alias:example-network.

After a couple minutes, we can see that Fugue has a successful, running process that embodies our network. This means Fugue has built the network, and is continually enforcing its configuration.

$ fugue status

Fugue Status Report - Thu Aug 4 2016 4:08pm

State    Updated    Created    FID                                   Alias            Last Message
-------  ---------  ---------  ------------------------------------  ---------------  --------------
Running  4:00pm     4:00pm     a6adf36d-b145-4825-8bef-20f9faada4ac  example-network  SUCCESS

A quick check of the console confirms that we have the VPC as described.

The resulting VPC.

The resulting VPC.

One of the resulting subnets.

One of the resulting subnets.

The resulting route table.

The resulting route table.

Killing The Fugue Process

We don’t want extra VPCs sitting around gathering dust, so we’ll clean this one up by killing the process. It’s very easy to do:

$ fugue kill example-network
[ fugue kill ] Killing running composition Alias:example-network

[ Help ] Are you sure you want to kill Alias:example-network? [y/N]: y
Asking Fugue to kill running composition Alias:example-network...
[ Success ] Fugue is killing process Alias:example-network

Within a few minutes, you should see My Cool VPC gone from your account. No mess!

Next Steps

Want to see what else you can make with VPCs? Check out the next example. Or, now that you have a VPC and all the bits that make it work, you can start putting stuff into it! A great way to do that is to continue with the Building Compute: Instances example. You can also try on your own to add an Instance, AutoScaling Group, Elastic Load Balancer, or more! You can ponder VPC subnet designs to serve your organization.