1. Setting up a bastion host in a default subnet for secure access

    TypeScript

    Setting up a bastion host involves provisioning a server that acts as a single point of entry to your private network from the internet. A bastion host is used for managing instances within private subnets and is an essential part of a network's defense strategy. The bastion host is typically placed in a public subnet with a Security Group that strictly controls inbound and outbound traffic.

    Here’s how you can set up a bastion host on AWS using Pulumi with TypeScript:

    1. VPC and Subnets: It's best practice to place the bastion in its own public subnet within a VPC.
    2. Security Groups: You'll create a Security Group for the bastion host to regulate access, allowing SSH (port 22) traffic only from your IP address.
    3. EC2 Instance: This is the bastion host itself. You will launch an EC2 instance within the above-mentioned subnet and apply the Security Group to it.

    Now, let's walk through the Pulumi code to set this up:

    import * as aws from "@pulumi/aws"; // Create a new VPC with default settings const vpc = new aws.ec2.Vpc("vpc", { cidrBlock: "10.0.0.0/16", }); // Create a subnet, which will be our public subnet hosting the bastion host const subnet = new aws.ec2.Subnet("subnet", { vpcId: vpc.id, cidrBlock: "10.0.1.0/24", mapPublicIpOnLaunch: true, // Ensure instances receive a public IP }); // Create an internet gateway for the VPC const internetGateway = new aws.ec2.InternetGateway("igw", { vpcId: vpc.id, }); // Create a route table with routes for outbound internet access const routeTable = new aws.ec2.RouteTable("routeTable", { vpcId: vpc.id, routes: [ { cidrBlock: "0.0.0.0/0", gatewayId: internetGateway.id, }, ], }); // Associate the route table with our subnet const routeTableAssociation = new aws.ec2.RouteTableAssociation("rta", { subnetId: subnet.id, routeTableId: routeTable.id, }); // Create a security group for the bastion host const bastionSecGroup = new aws.ec2.SecurityGroup("bastionSecGroup", { vpcId: vpc.id, description: "Allow SSH inbound traffic", ingress: [ { protocol: "tcp", fromPort: 22, toPort: 22, cidrBlocks: ["YOUR_IP_ADDRESS_HERE/32"], // Replace with your IP address }, ], egress: [ { protocol: "-1", // Allow all outbound traffic fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"], }, ], }); // Create an EC2 instance to serve as the bastion host const bastionHost = new aws.ec2.Instance("bastionHost", { ami: "ami-0c55b159cbfafe1f0", // Update to the latest Amazon Linux 2 AMI in your region instanceType: "t2.micro", subnetId: subnet.id, vpcSecurityGroupIds: [bastionSecGroup.id], keyName: "my-key-pair", // Replace with your key pair name associatePublicIpAddress: true, tags: { Name: "BastionHost", }, }); export const bastionPublicIp = bastionHost.publicIp; export const bastionPublicDns = bastionHost.publicDns;

    Explanation of code:

    • We create a new VPC and a public subnet for our bastion host.
    • An Internet Gateway is provisioned to allow communication between instances in our VPC and the internet.
    • A route table is defined with a default route through the internet gateway for outbound traffic.
    • We define ingress rules for the security group to restrict SSH access only to your IP address.
    • An AWS EC2 instance is provisioned within the subnet associated with the security group.
    • We've kept the keyName for the EC2 instance generic; replace it with your actual EC2 key pair.
    • The bastion host's public IP and DNS are exported, which you'll use to SSH into the bastion.

    Remember to replace "YOUR_IP_ADDRESS_HERE/32" with the actual IP address you'll be connecting from and ensure you have the corresponding key pair for SSH access. If you don't have a key pair yet, you must create one through the AWS console or CLI and provide the name of that key pair where "my-key-pair" is set.

    After deploying this program with Pulumi, you'll have a bastion host set up in your defined VPC and subnet, which you can use as your secure point of entry for managing your AWS resources.