The goal of this project is to create secure infrastructure for a website on AWS cloud. Using project's source code you can provision mentioned infrastructure using Terraform and then deploy a website using Ansible and Docker.
Here are main elements of the project infrastructure:
-
Two public subnets that contain:
- an Internet Gateway
- 2 NAT Gateways (1 per each public subnet)
- an Application Load Balancer
- a Bastion server to access webservers in private networks via SSH
-
Two private subnets that contain:
- 2 webservers located in 2 private subnets
- one RDS instance with MariaDB database
- (optional) Read replica for the database (corresponding code is fully functioning, however it is commented because creation of a read replica takes additional 30 minutes)
Access to the webservers and the RDS instance is controlled using Security Groups.
In order to start this project you will need:
- AWS account
- AWS CLI - to configure access to AWS cloud
- Terraform - to provision infrastructure on AWS cloud
- Ansible - to configure servers and deploy a website
Steps to start the project:
-
In AWS create an IAM user that has programmatic access to such AWS services: EC2, RDS, S3, VPC, SSM, KMS.
-
Generate Access Key for the created user.
-
Use Access Key and Secret Access Key obtained during previous step to configure AWS CLI. Run following command and enter access keys and choose default AWS region:
aws configure --profile <any profile name>
-
Clone this Git repository to your computer.
-
Create S3 bucket where Terraform will be storing its state. Please use a Terraform file
main.tf
provided in the directoryterraform/state
Run the following commands:
cd terraform/state
- to open directory with scriptterraform plan
- to generate list of resources that Terraform will create on AWS cloud. Please, review it carefully before accepting and starting infrastructure provisioning.terraform aplly
- to start provisioning of S3 bucket for the project. Please review provisioning plan once again and enteryes
.
Finally, after finishing above mentioned preliminary steps we are ready to continue with the project.
-
Provided public SSH key will be automatically added to the servers as part of Cloud-Init, so you will be able to access the servers. Please feel free to generate additional SSH key pairs for the servers if needed. Afterwards, you can save public part of the SSH key in SSM Parameter Store. Then please add the name of the SSM parameter to the list
admin_public_ssh_keys
in the filevariables.tf
. Those keys will be automatically added to servers during provisioning. -
Change directory to
terraform
by runningcd ..
-
Create text file
secrets.auto.tfvars
in directoryterraform
. Copy the text below into thesecrets.auto.tfvars
file to assign values to these variables:
database_name = "< a name for the database >"
database_username = "< a name for a database user >"
database_password = "< a strong password >"
Alternatively you can set environment variables in the console by entering:
export TF_database_name=exampledatabase
export TF_database_username=exampleduser
export TF_database_password=examplepassword
-
Run
terraform plan
- to generate list of the project resources that Terraform will create on AWS cloud. Please, review it carefully before accepting and starting infrastructure provisioning. -
Run
terraform aplly
- to start provisioning of the infrastructure. Please review provisioning plan once again and enteryes
.
Provisioning will take approximately 10 minutes. During provisioning an inventory file for Ansible will be automatically populated with IP-addresses of webservers and a bastion server. Also, SSM parameters will be created on the AWS to store database endpoint and credentials. After provisioning is done you will see the output information with the link to the application load balancer, as well as IP-addresses of webservers(private) and the bastion server(public).
- Switch to
ansible
directory and runansible-playbook install_docker.yml
This command should install Docker on two webservers.
- To deploy Wordpress on webservers run
ansible-playbook deploy_wordpress.yml
Thecompose.yml
file indocker-compose
folder was changed to disable some Docker capabilities to improve security. Please open loadbalancer URL (obtained as output at step 10) in a browser to see the results of deploy.
In order to make this infrastructure production-ready we will need to take additional measures such as:
- add container orchestration
- change ec2 instance type to a larger, compute optimized type
- create autoscaling groups for webservers
- configure logging
- configure monitoring
- configure database read-replicas and standbys
- configure firewalls, etc
- configure backups
Change directory to terraform
and run terraform destroy
and confirm actions.