How to deploy private subnets in an AWS VPC and an instance in the private subnet in Go
GoTo deploy private subnets in an AWS VPC and launch an instance in a private subnet using Pulumi with Go, you will need to:
- Create a Virtual Private Cloud (VPC).
- Set up a private subnet within the VPC.
- Create an Elastic IP and a NAT Gateway for outbound connectivity (if internet access is required from instances in the private subnet).
- Launch an EC2 instance inside the private subnet.
For this setup, we will use Pulumi with the
aws
package, which abstracts the AWS infrastructure creation. Below is a detailed breakdown of what the code will do:- It will use the
aws.ec2.Vpc
resource to create a new VPC. - It will then create two subnets using the
aws.ec2.Subnet
resource, one public (for the NAT Gateway) and one private. - It will use
aws.ec2.Eip
andaws.ec2.NatGateway
to create a NAT Gateway with an Elastic IP in the public subnet to allow the instances in the private subnet to initiate outbound connections to the Internet (for software updates, etc.) while not being accessible from the outside. - Next, it will provision an EC2 instance in the private subnet using the
aws.ec2.Instance
resource. - No public IP will be assigned to the instance in the private subnet, to ensure that it isn't directly reachable from the Internet.
Here's the full Pulumi program in Go that accomplishes this:
package main import ( "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) func main() { pulumi.Run(func(ctx *pulumi.Context) error { // Create a new VPC. vpc, err := ec2.NewVpc(ctx, "my-vpc", &ec2.VpcArgs{ CidrBlock: pulumi.String("10.0.0.0/16"), }) if err != nil { return err } // Create a subnet for the NAT Gateway (public subnet). publicSubnet, err := ec2.NewSubnet(ctx, "my-public-subnet", &ec2.SubnetArgs{ VpcId: vpc.ID(), CidrBlock: pulumi.String("10.0.1.0/24"), MapPublicIpOnLaunch: pulumi.Bool(true), // Enable auto-assign public IP on launch }) if err != nil { return err } // Create an Elastic IP for our NAT Gateway. eip, err := ec2.NewEip(ctx, "my-eip", nil) if err != nil { return err } // Create a NAT Gateway in the public subnet. natGw, err := ec2.NewNatGateway(ctx, "my-nat-gw", &ec2.NatGatewayArgs{ SubnetId: publicSubnet.ID(), AllocationId: eip.ID(), }) if err != nil { return err } // Create a private subnet. privateSubnet, err := ec2.NewSubnet(ctx, "my-private-subnet", &ec2.SubnetArgs{ VpcId: vpc.ID(), CidrBlock: pulumi.String("10.0.2.0/24"), }) if err != nil { return err } // Route table and association for the private subnet to enable outbound connectivity through the NAT Gateway. privateRouteTable, err := ec2.NewRouteTable(ctx, "my-private-route-table", &ec2.RouteTableArgs{ VpcId: vpc.ID(), Routes: ec2.RouteTableRouteArray{ &ec2.RouteTableRouteArgs{ CidrBlock: pulumi.String("0.0.0.0/0"), NatGatewayId: natGw.ID(), }, }, }) if err != nil { return err } _, err = ec2.NewRouteTableAssociation(ctx, "my-route-table-association", &ec2.RouteTableAssociationArgs{ SubnetId: privateSubnet.ID(), RouteTableId: privateRouteTable.ID(), }) if err != nil { return err } // Launch an instance in the private subnet. _, err = ec2.NewInstance(ctx, "my-instance", &ec2.InstanceArgs{ Ami: pulumi.String("ami-0c55b159cbfafe1f0"), // Update with a valid AMI ID for your region. InstanceType: pulumi.String("t2.micro"), SubnetId: privateSubnet.ID(), KeyName: pulumi.String("my-keypair"), // Replace with your key pair name. // Network interfaces to associate with the instance. NetworkInterfaces: ec2.InstanceNetworkInterfaceArray{ &ec2.InstanceNetworkInterfaceArgs{ DeviceIndex: pulumi.Int(0), NetworkInterfaceId: privateSubnet.ID(), DeleteOnTermination: pulumi.Bool(true), AssociatePublicIpAddress: pulumi.Bool(false), // No public IP. }, }, Tags: pulumi.StringMap{ "Name": pulumi.String("my-private-instance"), }, }) if err != nil { return err } // Export the VPC ID and the private instance ID ctx.Export("vpcId", vpc.ID()) ctx.Export("privateInstanceId", pulumi.String("my-instance.Id")) return nil }) }
To start using this code:
- You'll need to have Go and Pulumi CLI installed on your machine.
- Set up the AWS provider for Pulumi.
- Write the above Go code in a
main.go
file. - Run
pulumi up
to deploy your infrastructure.
This program will provision a VPC with a public and private subnet, a NAT Gateway with an Elastic IP for outbound connections, and an EC2 instance in the private subnet.
Please remember to replace the
ami-0c55b159cbfafe1f0
with a valid AMI for your region andmy-keypair
with your key pair name before running the program. The key pair is required to securely SSH into your EC2 instances. You can generate or import a key pair in the AWS console in the EC2 service section before running this code.