Set Up a 3-Tier Web App on AWS Using EC2 & RDS
Solution Overview
In this guide, we will set up a 3-tier web application on AWS using Pulumi. The three tiers will consist of:
- Web Tier: EC2 instances running a web server.
- Application Tier: EC2 instances running the application logic.
- Database Tier: Amazon RDS for the database.
We will use Pulumi’s AWS SDK to provision and manage these resources.
Step-by-Step Explanation
Prerequisites
- Ensure you have Pulumi installed. You can follow the installation guide here.
- Set up AWS credentials. You can follow the guide here.
Step 1: Create a new Pulumi project
- Create a new directory for your project and navigate into it:
mkdir my-3tier-webapp cd my-3tier-webapp
- Initialize a new Pulumi project:
pulumi new aws-typescript
Step 2: Define the VPC
- In the
index.ts
file, define a new VPC:import * as aws from "@pulumi/aws"; const vpc = new aws.ec2.Vpc("vpc", { cidrBlock: "10.0.0.0/16", });
Step 3: Define Subnets
- Define subnets for each tier:
const webSubnet = new aws.ec2.Subnet("web-subnet", { vpcId: vpc.id, cidrBlock: "10.0.1.0/24", availabilityZone: "us-west-2a", }); const appSubnet = new aws.ec2.Subnet("app-subnet", { vpcId: vpc.id, cidrBlock: "10.0.2.0/24", availabilityZone: "us-west-2b", }); const dbSubnet = new aws.ec2.Subnet("db-subnet", { vpcId: vpc.id, cidrBlock: "10.0.3.0/24", availabilityZone: "us-west-2c", });
Step 4: Define Security Groups
- Define security groups for each tier:
const webSecurityGroup = new aws.ec2.SecurityGroup("web-sg", { vpcId: vpc.id, ingress: [ { protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] }, ], egress: [ { protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] }, ], }); const appSecurityGroup = new aws.ec2.SecurityGroup("app-sg", { vpcId: vpc.id, ingress: [ { protocol: "tcp", fromPort: 8080, toPort: 8080, cidrBlocks: ["0.0.0.0/0"] }, ], egress: [ { protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] }, ], }); const dbSecurityGroup = new aws.ec2.SecurityGroup("db-sg", { vpcId: vpc.id, ingress: [ { protocol: "tcp", fromPort: 3306, toPort: 3306, cidrBlocks: ["0.0.0.0/0"] }, ], egress: [ { protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] }, ], });
Step 5: Provision EC2 Instances
- Provision EC2 instances for the web and application tiers:
const webServer = new aws.ec2.Instance("web-server", { ami: "ami-0c55b159cbfafe1f0", // Amazon Linux 2 AMI instanceType: "t2.micro", subnetId: webSubnet.id, securityGroups: [webSecurityGroup.name], tags: { "Name": "web-server" }, }); const appServer = new aws.ec2.Instance("app-server", { ami: "ami-0c55b159cbfafe1f0", // Amazon Linux 2 AMI instanceType: "t2.micro", subnetId: appSubnet.id, securityGroups: [appSecurityGroup.name], tags: { "Name": "app-server" }, });
Step 6: Provision RDS Instance
- Provision an RDS instance for the database tier:
const dbInstance = new aws.rds.Instance("db-instance", { engine: "mysql", instanceClass: "db.t2.micro", allocatedStorage: 20, dbSubnetGroupName: new aws.rds.SubnetGroup("db-subnet-group", { subnetIds: [dbSubnet.id], }).name, vpcSecurityGroupIds: [dbSecurityGroup.id], skipFinalSnapshot: true, });
Step 7: Output the Connection Information
- Output the connection information for the web server and database:
export const webServerPublicIp = webServer.publicIp; export const dbEndpoint = dbInstance.endpoint;
Summary
By following these steps, you have set up a 3-tier web application on AWS using Pulumi. The application consists of EC2 instances for the web and application tiers and an RDS instance for the database tier. Pulumi’s AWS SDK makes it easy to provision and manage these resources in a repeatable and scalable manner.
Full Code Example
import * as aws from "@pulumi/aws";
// Step 2: Define the VPC
const vpc = new aws.ec2.Vpc("vpc", {
cidrBlock: "10.0.0.0/16",
});
// Step 3: Define Subnets
const webSubnet = new aws.ec2.Subnet("web-subnet", {
vpcId: vpc.id,
cidrBlock: "10.0.1.0/24",
availabilityZone: "us-west-2a",
});
const appSubnet = new aws.ec2.Subnet("app-subnet", {
vpcId: vpc.id,
cidrBlock: "10.0.2.0/24",
availabilityZone: "us-west-2b",
});
const dbSubnet = new aws.ec2.Subnet("db-subnet", {
vpcId: vpc.id,
cidrBlock: "10.0.3.0/24",
availabilityZone: "us-west-2c",
});
// Step 4: Define Security Groups
const webSecurityGroup = new aws.ec2.SecurityGroup("web-sg", {
vpcId: vpc.id,
ingress: [
{ protocol: "tcp", fromPort: 80, toPort: 80, cidrBlocks: ["0.0.0.0/0"] },
],
egress: [
{ protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] },
],
});
const appSecurityGroup = new aws.ec2.SecurityGroup("app-sg", {
vpcId: vpc.id,
ingress: [
{ protocol: "tcp", fromPort: 8080, toPort: 8080, cidrBlocks: ["0.0.0.0/0"] },
],
egress: [
{ protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] },
],
});
const dbSecurityGroup = new aws.ec2.SecurityGroup("db-sg", {
vpcId: vpc.id,
ingress: [
{ protocol: "tcp", fromPort: 3306, toPort: 3306, cidrBlocks: ["0.0.0.0/0"] },
],
egress: [
{ protocol: "tcp", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] },
],
});
// Step 5: Provision EC2 Instances
const webServer = new aws.ec2.Instance("web-server", {
ami: "ami-0c55b159cbfafe1f0", // Amazon Linux 2 AMI
instanceType: "t2.micro",
subnetId: webSubnet.id,
securityGroups: [webSecurityGroup.name],
tags: { "Name": "web-server" },
});
const appServer = new aws.ec2.Instance("app-server", {
ami: "ami-0c55b159cbfafe1f0", // Amazon Linux 2 AMI
instanceType: "t2.micro",
subnetId: appSubnet.id,
securityGroups: [appSecurityGroup.name],
tags: { "Name": "app-server" },
});
// Step 6: Provision RDS Instance
const dbInstance = new aws.rds.Instance("db-instance", {
engine: "mysql",
instanceClass: "db.t2.micro",
allocatedStorage: 20,
dbSubnetGroupName: new aws.rds.SubnetGroup("db-subnet-group", {
subnetIds: [dbSubnet.id],
}).name,
vpcSecurityGroupIds: [dbSecurityGroup.id],
skipFinalSnapshot: true,
});
// Step 7: Output the Connection Information
export const webServerPublicIp = webServer.publicIp;
export const dbEndpoint = dbInstance.endpoint;
Deploy this code
Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.
Sign upNew to Pulumi?
Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.
Sign upThank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.