├── .gitignore ├── README.md ├── alb-sg.tf ├── asgs.tf ├── bastion-sg.tf ├── bin ├── bastion.sh ├── nginx.sh ├── tooling.sh └── wordpress.sh ├── efs.tf ├── images ├── 3tierapplication.drawio.png └── iam policy.png ├── launch-templates.tf ├── nginx-sg.tf ├── provider.tf ├── rds.tf ├── vpc.tf └── webservers-sg.tf /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | crash.*.log 11 | 12 | # Exclude all .tfvars files, which are likely to contain sensitive data, such as 13 | # password, private keys, and other secrets. These should not be part of version 14 | # control as they are data points which are potentially sensitive and subject 15 | # to change depending on the environment. 16 | *.tfvars 17 | *.tfvars.json 18 | 19 | # Ignore override files as they are usually used to override resources locally and so 20 | # are not checked in 21 | override.tf 22 | override.tf.json 23 | *_override.tf 24 | *_override.tf.json 25 | 26 | # Include override files you do wish to add to version control using negated pattern 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* 31 | 32 | # Ignore CLI configuration files 33 | .terraformrc 34 | terraform.rc 35 | 36 | .terraform.lock.hcl 37 | .vscode 38 | devops.pem 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS_Terraform_3tier_app 2 | Code to deploy a 3 tier web application in AWS using Terraform 3 | 4 | ## Project Design Architecture Diagram 5 | ![Architecture Diagram](./images/3tierapplication.drawio.png) 6 | 7 | ## Prerequisites For Implementing the project 8 | - AWS Account 9 | 10 | If you do not currently have an aws account you can open [here](https://aws.amazon.com/resources/create-account/) 11 | 12 | - Terraform 13 | 14 | If you don't have terraform installed on your machine, you can follow this [documentation](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) to setup terraform 15 | 16 | - AWS CLI 17 | 18 | You can follow this [AWS Documentation](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) to install or update to the latest version of AWS CLI 19 | 20 | 21 | ## SetUp 22 | Login to your [AWS account](https://aws.amazon.com) and navigate to the IAM Dashboard to create an IAM User. Assign administrator access permissions to the user and be sure to download and save your access keys. 23 | 24 | ![IAM User Permissions](./images/iam%20policy.png) -------------------------------------------------------------------------------- /alb-sg.tf: -------------------------------------------------------------------------------- 1 | # external alb Security Group 2 | resource "aws_security_group" "external-alb-sg" { 3 | name = "external-alb-sg" 4 | description = "Public internet access" 5 | vpc_id = aws_vpc.main.id 6 | 7 | tags = { 8 | Name = "external-alb-sg" 9 | } 10 | } 11 | 12 | 13 | # security group rules 14 | resource "aws_security_group_rule" "public_in_http" { 15 | type = "ingress" 16 | from_port = 80 17 | to_port = 80 18 | protocol = "tcp" 19 | cidr_blocks = ["0.0.0.0/0"] 20 | security_group_id = aws_security_group.external-alb-sg.id 21 | } 22 | resource "aws_security_group_rule" "public_out_external_alb" { 23 | type = "egress" 24 | from_port = 0 25 | to_port = 0 26 | protocol = "-1" 27 | cidr_blocks = ["0.0.0.0/0"] 28 | 29 | security_group_id = aws_security_group.external-alb-sg.id 30 | } 31 | 32 | 33 | 34 | 35 | 36 | # Internal alb Security Group 37 | resource "aws_security_group" "internal-alb-sg" { 38 | name = "internal-alb-sg" 39 | description = "Internal ALB" 40 | vpc_id = aws_vpc.main.id 41 | 42 | tags = { 43 | Name = "internal-alb-sg" 44 | } 45 | } 46 | 47 | 48 | # security group rules 49 | resource "aws_security_group_rule" "allow_nginx_port80" { 50 | type = "ingress" 51 | from_port = 80 52 | to_port = 80 53 | protocol = "tcp" 54 | cidr_blocks = ["0.0.0.0/0"] 55 | security_group_id = aws_security_group.internal-alb-sg.id 56 | } 57 | 58 | resource "aws_security_group_rule" "allow_nginx_port443" { 59 | type = "ingress" 60 | from_port = 443 61 | to_port = 443 62 | protocol = "tcp" 63 | cidr_blocks = ["0.0.0.0/0"] 64 | security_group_id = aws_security_group.internal-alb-sg.id 65 | } 66 | 67 | resource "aws_security_group_rule" "public_out_internal_alb" { 68 | type = "egress" 69 | from_port = 0 70 | to_port = 0 71 | protocol = "-1" 72 | cidr_blocks = ["0.0.0.0/0"] 73 | 74 | security_group_id = aws_security_group.internal-alb-sg.id 75 | } 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /asgs.tf: -------------------------------------------------------------------------------- 1 | # Bastion ASG 2 | resource "aws_autoscaling_group" "bastion-asg" { 3 | name = "bastion-asg" 4 | max_size = 1 5 | min_size = 1 6 | health_check_grace_period = 300 7 | health_check_type = "ELB" 8 | desired_capacity = 1 9 | 10 | vpc_zone_identifier = [ 11 | aws_subnet.privateSubnet-1.id, 12 | aws_subnet.publicSubnet-2.id 13 | ] 14 | 15 | 16 | launch_template { 17 | id = aws_launch_template.bastion-launch-template.id 18 | version = "$Latest" 19 | } 20 | tag { 21 | key = "Name" 22 | value = "bastion" 23 | propagate_at_launch = true 24 | } 25 | 26 | } 27 | 28 | 29 | # Nginx ASG 30 | resource "aws_autoscaling_group" "nginx-asg" { 31 | name = "nginx-asg" 32 | max_size = 1 33 | min_size = 1 34 | health_check_grace_period = 300 35 | health_check_type = "ELB" 36 | desired_capacity = 1 37 | 38 | vpc_zone_identifier = [ 39 | aws_subnet.privateSubnet-1.id, 40 | aws_subnet.privateSubnet-2.id 41 | ] 42 | 43 | 44 | launch_template { 45 | id = aws_launch_template.nginx-launch-template.id 46 | version = "$Latest" 47 | } 48 | tag { 49 | key = "Name" 50 | value = "nginx" 51 | propagate_at_launch = true 52 | } 53 | 54 | } 55 | 56 | 57 | # Wordpress ASG 58 | resource "aws_autoscaling_group" "wordpress-asg" { 59 | name = "wordpress-asg" 60 | max_size = 1 61 | min_size = 1 62 | health_check_grace_period = 300 63 | health_check_type = "ELB" 64 | desired_capacity = 1 65 | 66 | vpc_zone_identifier = [ 67 | aws_subnet.privateSubnet-1.id, 68 | aws_subnet.privateSubnet-2.id 69 | ] 70 | 71 | 72 | launch_template { 73 | id = aws_launch_template.wordpress-launch-template.id 74 | version = "$Latest" 75 | } 76 | tag { 77 | key = "Name" 78 | value = "wordpress" 79 | propagate_at_launch = true 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /bastion-sg.tf: -------------------------------------------------------------------------------- 1 | # Internal alb Security Group 2 | resource "aws_security_group" "bastion-sg" { 3 | name = "bastion-sg" 4 | description = "Bastion SG" 5 | vpc_id = aws_vpc.main.id 6 | 7 | tags = { 8 | Name = "bastion-sg" 9 | } 10 | } 11 | 12 | 13 | # security group rules 14 | resource "aws_security_group_rule" "allow_ssh_access_from_ipaddress" { 15 | type = "ingress" 16 | from_port = 22 17 | to_port = 22 18 | protocol = "tcp" 19 | cidr_blocks = ["172.30.240.1/32"] 20 | security_group_id = aws_security_group.bastion-sg.id 21 | } 22 | 23 | resource "aws_security_group_rule" "allow_ssh_access_from_ipaddress_engineers" { 24 | type = "ingress" 25 | from_port = 22 26 | to_port = 22 27 | protocol = "tcp" 28 | cidr_blocks = ["192.168.215.25/32"] 29 | security_group_id = aws_security_group.bastion-sg.id 30 | } 31 | 32 | resource "aws_security_group_rule" "public_out_bastion" { 33 | type = "egress" 34 | from_port = 0 35 | to_port = 0 36 | protocol = "-1" 37 | cidr_blocks = ["0.0.0.0/0"] 38 | 39 | security_group_id = aws_security_group.bastion-sg.id 40 | } 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /bin/bastion.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # bastion userdata 4 | 5 | sudo yum update -y 6 | sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 7 | sudo yum install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm 8 | sudo yum install -y mysql 9 | -------------------------------------------------------------------------------- /bin/nginx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # nginx userdata 4 | 5 | sudo yum update -y 6 | sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 7 | sudo yum install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm 8 | sudo yum install -y nginx git -------------------------------------------------------------------------------- /bin/tooling.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # tooling userdata 4 | 5 | sudo yum update -y 6 | sudo yum install -y mysql git wget 7 | sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 8 | sudo yum install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm 9 | 10 | # this section is to install EFS util for mounting to the file system 11 | 12 | git clone https://github.com/aws/efs-utils 13 | 14 | cd /efs-utils 15 | 16 | sudo yum install -y make 17 | 18 | sudo yum install -y rpm-build 19 | 20 | make rpm 21 | 22 | sudo yum install -y ./build/amazon-efs-utils*rpm 23 | -------------------------------------------------------------------------------- /bin/wordpress.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # wordpress userdata 4 | 5 | sudo yum update -y 6 | sudo yum install -y mysql-client zip git wget 7 | sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm 8 | sudo yum install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-8.rpm 9 | 10 | # this section is to install EFS util for mounting to the file system 11 | 12 | git clone https://github.com/aws/efs-utils 13 | 14 | cd /efs-utils 15 | 16 | sudo yum install -y make 17 | 18 | sudo yum install -y rpm-build 19 | 20 | make rpm 21 | 22 | sudo yum install -y ./build/amazon-efs-utils*rpm 23 | -------------------------------------------------------------------------------- /efs.tf: -------------------------------------------------------------------------------- 1 | # create key from key management system 2 | resource "aws_kms_key" "efskey-kms" { 3 | description = "KMS key " 4 | policy = <