Creating and launching sample webServer(with Backend DB)in AWS using Terraform.
Rashni Ghosh
AWS || Jenkins(CI/CD) || Docker || Terraform || Git & GitHub || Python(Boto3) || DevOps || Control-M || Rancher
First, we will instruct our Terraform that the below code is to create Infrastructure in?AWS?. To achieve this we need to create a?provider.tf?file where we will declare the provider. So, in backend terraform will download the required files for the?aws?to launch the resources. We will pass the?region?as a variable which we will declare later.
The?content of?provider.tf?is as below,
provider "aws" {
region = var.region
}
As our?vpc?and?subnets?are created earlier we will create a variable file called?variable.tf?and declare them. So we can call them where ever we required. Also, we will declare our?AWS?region as well.
The content of?variables.tf?is as below,
variable "region" {
default = "ap-south-1"
description = "AWS Region"
}
variable "vpc_id" {
default = "vpc-0feaa21ebf38d2ae6"
}
variable "public_subnet_1_id" {
default = "subnet-051834cfc5d3a418c"
description = "Public Subnet 1 ID"
}
variable "public_subnet_2_id" {
default = "subnet-0ba7500feadae8dfd"
description = "Public Subnet 2 ID"
}
variable "public_subnet_3_id" {
default = "subnet-0c584f40c260d270a"
description = "Public Subnet 3 ID"
}
variable "private_subnet_1_id" {
default = "subnet-08feb8b7fa670a5db"
description = "Private Subnet 1 ID"
}
variable "private_subnet_2_id" {
default = "subnet-00303f87b29feeebd"
description = "Private Subnet 2 ID"
}
variable "private_subnet_3_id" {
default = "subnet-06cc1daab419a03f7"
description = "Private Subnet 3 ID"
}
Creating two security groups, One is for Internet-facing instance i.e.?wordpress?and another for the Database server i.e.?MySQL. So, let's write the terraform code. we will name the file as?wordpress-sg.tf?and?mysql-sg.tf?respectively.
In the?wordpress-sg.tf?file which is meant to create a security group for WordPress, we will open?HTTP(80)?and?SSH(22)?to all. The reason behind that is we will open the webpage for all the customers across the globe also we need to?SSH?into the instance for required modification.
The content of?wordpress-sg.tf?is as below,
resource "aws_security_group" "ec2_public_security_group" {
name = "wordpress-sg"
description = "Security Group for public access"
vpc_id = var.vpc_id
ingress {
from_port = 80
protocol = "TCP"
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
protocol = "TCP"
to_port = 22
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
After creating the security group for?wordpress?let’s create the security group for?Mysql. We will give that file a name as?mysql-sg.tf?for our identification.
The content of?mysql-sg.tf?is as below,
resource "aws_security_group" "ec2_private_security_group" {
name = "mysql-sg"
description = "Security Group allowing only public subnet instances"
vpc_id = var.vpc_id
ingress {
from_port = 0
protocol = "-1"
to_port = 0
security_groups = ["${aws_security_group.ec2_public_security_group.id}"]
}
egress {
from_port = 0
protocol = "-1"
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
In?mysql-sg.tf?we are allowing all ports to our?wordpress?security group. That means any instance with that security group can access to?Mysql?server. No outsider is allowed to get into?MySQL?server. It’ll add another layer of security.
We will now create the key pairs which can be used to?SSH?into the instances.
$ ssh-keygen -t rsa -f mykey
It will create a key pair named?mykey?and?mykey.pub. We will create a Terraform file to upload the key to?AWS. The content of?key.tf?is as below,
领英推荐
resource "aws_key_pair" "key" {
key_name = "mykey"
public_key = file("mykey.pub")
}
Now, it’s time to create our last and final resources which is two?EC2?Instances. One for?wordpress?and another for?mysql. The content of?wp-instance.tf?is as below. It will create an EC2 instance and install WordPress in it.
resource "aws_instance" "my_public_instance" {
ami = "ami-0732b62d310b80e97"
instance_type = "t2.micro"
key_name = "mykey"
subnet_id = var.public_subnet_1_id
associate_public_ip_address = true
vpc_security_group_ids = [aws_security_group.ec2_public_security_group.id]
private_ip = "192.168.1.5"
connection {
type = "ssh"
user = "ec2-user"
private_key = file("mykey")
host = aws_instance.my_public_instance.public_ip
}
provisioner "file" {
source = "mykey"
destination = "/home/ec2-user/mykey"
}
provisioner "remote-exec" {
inline = [
"chmod 0400 /home/ec2-user/mykey",
]
}
provisioner "file" {
source = "wordpress.sh"
destination = "/home/ec2-user/wordpress.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x wordpress.sh",
"./wordpress.sh",
]
}
tags = {
Name = "WordPress"
}
}
In the previous terraform file we’re passing a shell script named?wordpress.sh?. It will install WordPress in the EC2 instance. The content of the wordpress.sh?is as below,
#!/bin/bash
sudo setenforce 0
sudo sed -i 's/enforcing/disabled/g' /etc/selinux/config
sudo yum install httpd php php-common php-mysqlnd php-mbstring php-gd -y
sudo sed -i 's/AllowOverride none/AllowOverride all/g' /etc/httpd/conf/httpd.conf
wget https://wordpress.org/wordpress-4.9.tar.gz
sudo tar xvzf wordpress-4.9.tar.gz
sudo mv wordpress/* /var/www/html/
sudo chown -R apache:apache /var/www/html/
sudo systemctl restart httpd
The above script will install PHP and HTTPD which are pre-requites for WordPress. Then it will download the WordPress installation bundle and unzip that. After unzipping it will put the content to?\var\www\html?which is the default location for Apache Web Server. Then it will restart the HTTP daemon.
The final step is to create a Terraform file for installing?MySQL?and creating a DataBase which will be used for WordPress. The content of?ms-instance.tf?is like below,
resource "aws_instance" "my_private_instance" {
ami = "ami-0732b62d310b80e97"
instance_type = "t2.micro"
key_name = "mykey"
subnet_id = var.private_subnet_1_id
vpc_security_group_ids = [aws_security_group.ec2_private_security_group.id]
private_ip = "192.168.4.5"
user_data = <<EOF
#!/bin/bash
sudo yum update -y
wget https://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
sudo yum install mysql-community-release-el7-5.noarch.rpm -y
sudo yum install mysql-server -y
sudo systemctl start mysqld
sudo systemctl enable mysqld
mysql -uroot <<MYSQL_SCRIPT
CREATE DATABASE wordpress;
CREATE USER 'wordpress'@'%' IDENTIFIED BY '12345';
GRANT ALL ON wordpress.* TO wordpress@'%' IDENTIFIED BY '12345';
MYSQL_SCRIPT
EOF
tags = {
Name = "MySQL"
}
}
Now, it’s time to create the output file which will display the required IPs for further operation on Web Console. The?outputs.tf?file content is as below,
output "wp_instance_public_ip" {
value = aws_instance.my_public_instance.public_ip
}
output "ms_instance_private_ip" {
value = aws_instance.my_private_instance.private_ip
}
The coding part is now completed. Let’s run the?terraform apply?and see the output. But before that, we have to run?terraform init?to download the required plugins. It’s always advisable to run?terraform validate?and?terraform plan?before firing the?terraform apply?command. It will show the errors and we can rectify them.
$ terraform init
$ terraform validate
$ terraform plan
$ terraform apply
After running the?apply?command, it will give the public IP of WordPress instance. In a browser put that IP and hit ‘Enter’. A WordPress Configuration page will come, just configure it.
YOUR WORDPRESS IS READY NOW :)
DevOps Engineer at Flentas | 2xAWSCertified | CKA Certified | Docker | Jenkin | Terraform
3 年Nice Structure of Code..