Creating Web Portal Using WordPress and MySQL on AWS
Task description:
We have to create a web portal with all the security as much as possible. So, we use Wordpress software with dedicated database server.
Database should not be accessible from the outside world for security purposes.
We only need to public the WordPress to clients. So here are the steps for proper understanding!
Prerequisites:
1) We need to have an account on AWS.
2) AWS CLI program should be downloaded and configured.
Tools and Technologies Involved:
- Terraform and AWS.
Getting started:
Step 1) Write a Infrastructure as code using terraform, which automatically creates the following resorces:
- First we need to describe the provider i.e. AWS.
provider "aws" { profile = "Admin" region = "ap-south-1" }
- A VPC (Virtual Private Cloud)
Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define.
resource "aws_vpc" "main" { cidr_block = "192.168.0.0/16" }
- In that VPC we have to create 2 subnets:
a) Public subnet [ Accessible for Public World ]
resource "aws_subnet" "public_subnet" { vpc_id = "${aws_vpc.main.id}" cidr_block = "192.168.1.0/24" map_public_ip_on_launch = true tags = { Name = "public_subnet" } }
NOTE : Don't forget to add auto ip assign assignment option to be enabled (map_public_ip_on_launch = true).
b) Private subnet [ Restricted for Public World ]
resource "aws_subnet" "private_subnet" { vpc_id = "${aws_vpc.main.id}" cidr_block = "192.168.2.0/24" tags = { Name = "private_subnet" } }
- Create a public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC.
resource "aws_internet_gateway" "internet_gateway" { vpc_id = "${aws_vpc.main.id}" }
- Create a routing table for Internet gateway so that instance can connect to outside world, update and associate it with public subnet.
resource "aws_route_table" "route_table" { vpc_id = "${aws_vpc.main.id}" route { cidr_block = "0.0.0.0/0" gateway_id = "${aws_internet_gateway.internet_gateway.id}" } tags = { Name = "public_subnet" } } resource "aws_route_table_association" "route_table_associate" { subnet_id = "${aws_subnet.public_subnet.id}" route_table_id = "${aws_route_table.route_table.id}" }
- A key for login into the instance.
variable "key_name" { default = "key2" } resource "tls_private_key" "example" { algorithm = "RSA" rsa_bits = 4096 } resource "aws_key_pair" "generated_key" { depends_on = [ tls_private_key.example ] key_name = "${var.key_name}" public_key = "${tls_private_key.example.public_key_openssh}" }
- A security group for Wordpress instance such that it has all required inbound and outbound rules.
resource "aws_security_group" "wordpress_sg" { name = "wordpress_sg" description = "Allow TLS inbound traffic" vpc_id = "${aws_vpc.main.id}" ingress { description = "IMCP" from_port = 0 to_port = 0 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "SSH" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "HTTP" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "wordpress_sg" } }
- Create a security group for MySQL.
resource "aws_security_group" "MySQL_sg" { name = "MySQL_sg" description = "Allow TLS inbound traffic" vpc_id = "${aws_vpc.main.id}" tags = { Name = "MySQL_sg" } }
In this security group we need to provide some rules so that only the instances having the wordpress security group are able to connect to the MySQL instance.
resource "aws_security_group_rule" "mysql_sg_rule_in" { type = "ingress" from_port = 3306 to_port = 3306 protocol = "tcp" security_group_id = "${aws_security_group.MySQL_sg.id}" source_security_group_id = "${aws_security_group.wordpress_sg.id}" } resource "aws_security_group_rule" "mysql_sg_rule_eg" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] security_group_id = "${aws_security_group.MySQL_sg.id}" }
- Launch an EC2 instance which has MYSQL setup already with security group allowing port 3306 (we have created already) in private subnet so that our wordpress vm can connect with the same.
Also attach the key with the instance.
resource "aws_instance" "mysql_instance" { ami = "ami-0428a02584750600f" instance_type = "t2.micro" key_name = aws_key_pair.generated_key.key_name vpc_security_group_ids = [ "${aws_security_group.MySQL_sg.id}" ] subnet_id = "${aws_subnet.private_subnet.id}" tags = { Name = "mysql_instance" } }
For this instance I have used the following AMI.
NOTE: MySQL instance has to be part of private subnet so that outside world can't connect to it.
- Launch an EC2 instance which has Wordpress setup already having the security group allowing port 80 (we have created already) so that our client can connect to our wordpress site.
Also attach the key to the instance for further login into it.
resource "aws_instance" "wordpress_instance" { ami = "ami-004a955bfb611bf13" instance_type = "t2.micro" key_name = aws_key_pair.generated_key.key_name vpc_security_group_ids = [ "${aws_security_group.wordpress_sg.id}" ] subnet_id = "${aws_subnet.public_subnet.id}" tags = { Name = "wordpress_instance" } }
For this instance I have used the following AMI.
NOTE : Wordpress instance has to be part of public subnet so that our client can connect our site.
Step 2. Executing the Terraform code.
Run terraform init — This command is used to initialise a working directory containing terraform configuration files. This is the first command that should be run after writing a new terraform configuration or cloning an existing one from version control
Run terraform apply -auto-approve — This command is used to apply the terraform code and also skip interactive approval of plan before applying.
After the complete execution, following resources can be seen launched in the aws console.
- A new VPC is created other than the default VPC
- Public subnet in the new VPC
- Route table in public subnet
- Private subnet in the new VPC
- Internet Gateway
- Newly generated key
- Security Groups.
- Two new instances
MySQL instance
Wordpress Instance
- A network ACL (Access Control List)
Now, we have the complete Architechture.
We can use the Public Ip of Wordpress VM/instance to acces the web portal. Here we need to provide the user name and password to login. 'user' is the default username and to get the password we can check the system logs of the Wordpress instance.
Now, we are ready with our wordpress and database server.
And the task is completed.