├── main.tf ├── outputs.tf ├── default.auto.tfvars ├── variables.tf ├── mysql_setup.sh ├── install_wordpres_script.sh ├── rds.tf ├── application_load_balancer.tf └── autscaling_group.tf /main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | cloud { 3 | organization = "tomondre" 4 | 5 | workspaces { 6 | tags = ["blog"] 7 | } 8 | } 9 | } 10 | 11 | provider "aws" { 12 | region = "eu-central-1" 13 | } 14 | 15 | locals { 16 | name_prefix = "blog" 17 | } -------------------------------------------------------------------------------- /outputs.tf: -------------------------------------------------------------------------------- 1 | output "private_key" { 2 | value = tls_private_key.ssh_key.private_key_pem 3 | sensitive = true 4 | } 5 | 6 | output "db_password" { 7 | value = random_password.db_password.result 8 | sensitive = true 9 | } 10 | 11 | output "db_username" { 12 | value = local.db_username 13 | sensitive = true 14 | } -------------------------------------------------------------------------------- /default.auto.tfvars: -------------------------------------------------------------------------------- 1 | public_subnet_ids = ["subnet-095236d9a74fc3a0f", "subnet-08453386059c0f702", "subnet-0e659d84f1ba59a04"] 2 | private_subnet_ids = ["subnet-095236d9a74fc3a0f", "subnet-08453386059c0f702", "subnet-0e659d84f1ba59a04"] 3 | vpc_id = "vpc-07374673f791a5931" 4 | ami_id = "ami-070b208e993b59cea" 5 | max_size = 2 6 | min_size = 1 -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_id" { 2 | type = string 3 | } 4 | 5 | variable "public_subnet_ids" { 6 | type = list(string) 7 | } 8 | 9 | variable "private_subnet_ids" { 10 | type = list(string) 11 | } 12 | 13 | variable "private_domain_key" { 14 | type = string 15 | } 16 | 17 | variable "certificate_body" { 18 | type = string 19 | } 20 | 21 | variable "ami_id" { 22 | type = string 23 | } 24 | 25 | variable "min_size" { 26 | type = number 27 | } 28 | 29 | variable "max_size" { 30 | type = number 31 | } -------------------------------------------------------------------------------- /mysql_setup.sh: -------------------------------------------------------------------------------- 1 | #Reference: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/hosting-wordpress.html 2 | 3 | #Change the password and scope after @ symbol. If wordpress is hosted on the same machine as mysql, use 'localhost'. Otherwise use % 4 | CREATE USER 'wordpress-user'@'%' IDENTIFIED BY ''; 5 | CREATE DATABASE `wordpress-db`; 6 | #Change the scope after @ symbol. If wordpress is hosted on the same machine as mysql, use 'localhost'. Otherwise use % 7 | GRANT ALL PRIVILEGES ON `wordpress-db`.* TO "wordpress-user"@"%"; 8 | FLUSH PRIVILEGES; 9 | -------------------------------------------------------------------------------- /install_wordpres_script.sh: -------------------------------------------------------------------------------- 1 | #Reference: https://medium.com/@babettelandmesser/install-wordpress-in-aws-ec2-instance-ada5b2db06d2 2 | sudo yum update -y 3 | sudo amazon-linux-extras install -y php7.4 4 | sudo yum install -y httpd 5 | sudo systemctl start httpd 6 | sudo systemctl enable httpd 7 | #Depending on the user, change the last argument 8 | sudo usermod -a -G apache ssm-user 9 | sudo chown -R ssm-user:apache /var/www 10 | # 11 | sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \; 12 | find /var/www -type f -exec sudo chmod 0664 {} \; 13 | cd ~ 14 | curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 15 | chmod +x wp-cli.phar 16 | sudo mv wp-cli.phar /usr/local/bin/wp 17 | cd /var/www/html/ 18 | wp core download -------------------------------------------------------------------------------- /rds.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | db_username = "tomondre" 3 | } 4 | 5 | resource "random_password" "db_password" { 6 | length = 10 7 | } 8 | 9 | resource "aws_security_group" "db_security_group" { 10 | name = "db-security-group" 11 | ingress { 12 | from_port = 3306 13 | protocol = "TCP" 14 | to_port = 3306 15 | security_groups = [aws_security_group.asg_security_group.id] 16 | } 17 | vpc_id = var.vpc_id 18 | } 19 | 20 | resource "aws_db_instance" "rds" { 21 | identifier = "wordpress-db" 22 | instance_class = "db.t3.micro" 23 | engine = "mysql" 24 | engine_version = "8.0.28" 25 | password = random_password.db_password.result 26 | username = local.db_username 27 | vpc_security_group_ids = [aws_security_group.db_security_group.id] 28 | allocated_storage = 200 29 | skip_final_snapshot = true 30 | final_snapshot_identifier = "final-snapshot" 31 | } -------------------------------------------------------------------------------- /application_load_balancer.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "alb_security_group" { 2 | name = "alb-sg" 3 | ingress { 4 | from_port = 0 5 | protocol = "-1" 6 | to_port = 0 7 | cidr_blocks = ["0.0.0.0/0"] 8 | } 9 | egress { 10 | from_port = 0 11 | protocol = "-1" 12 | to_port = 0 13 | cidr_blocks = ["0.0.0.0/0"] 14 | } 15 | } 16 | 17 | resource "aws_alb" "alb" { 18 | name = "blog-alb" 19 | internal = false 20 | load_balancer_type = "application" 21 | subnets = var.public_subnet_ids 22 | security_groups = [aws_security_group.alb_security_group.id] 23 | } 24 | 25 | resource "aws_lb_listener" "front_end" { 26 | load_balancer_arn = aws_alb.alb.arn 27 | port = "80" 28 | protocol = "HTTP" 29 | 30 | default_action { 31 | type = "redirect" 32 | 33 | redirect { 34 | port = "443" 35 | protocol = "HTTPS" 36 | status_code = "HTTP_301" 37 | } 38 | } 39 | } 40 | 41 | resource "aws_acm_certificate" "host_certificate" { 42 | private_key = file("${path.module}/private.pem") 43 | certificate_body = file("${path.module}/certificate_body.cer") 44 | certificate_chain = file("${path.module}/chain.pem") 45 | } 46 | 47 | resource "aws_lb_listener" "https_forward" { 48 | load_balancer_arn = aws_alb.alb.arn 49 | port = 443 50 | protocol = "HTTPS" 51 | certificate_arn = aws_acm_certificate.host_certificate.arn 52 | default_action { 53 | type = "forward" 54 | target_group_arn = aws_alb_target_group.asg_tg.arn 55 | } 56 | } -------------------------------------------------------------------------------- /autscaling_group.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | wp_port = 80 3 | wp_protocol = "HTTP" 4 | } 5 | 6 | resource "tls_private_key" "ssh_key" { 7 | algorithm = "RSA" 8 | rsa_bits = "4096" 9 | } 10 | 11 | resource "aws_key_pair" "pubic_key" { 12 | key_name = "wordpress-key" 13 | public_key = tls_private_key.ssh_key.public_key_openssh 14 | } 15 | 16 | resource "aws_security_group" "asg_security_group" { 17 | name = "wordpress-sg" 18 | ingress { 19 | from_port = local.wp_port 20 | protocol = "tcp" 21 | to_port = local.wp_port 22 | security_groups = aws_alb.alb.security_groups 23 | } 24 | ingress { 25 | from_port = 22 26 | protocol = "tcp" 27 | to_port = 22 28 | cidr_blocks = ["0.0.0.0/0"] 29 | } 30 | egress { 31 | from_port = 0 32 | protocol = "-1" 33 | to_port = 0 34 | cidr_blocks = ["0.0.0.0/0"] 35 | } 36 | } 37 | 38 | resource "aws_alb_target_group" "asg_tg" { 39 | name = "blog-tf" 40 | port = local.wp_port 41 | vpc_id = var.vpc_id 42 | protocol = local.wp_protocol 43 | } 44 | 45 | module "autoscaling_group" { 46 | source = "terraform-aws-modules/autoscaling/aws" 47 | image_id = var.ami_id 48 | key_name = aws_key_pair.pubic_key.key_name 49 | security_groups = [aws_security_group.asg_security_group.id] 50 | name = "${local.name_prefix}-asg" 51 | min_size = var.min_size 52 | max_size = var.max_size 53 | vpc_zone_identifier = var.private_subnet_ids 54 | instance_type = "t2.micro" 55 | target_group_arns = [aws_alb_target_group.asg_tg.arn] 56 | create_iam_instance_profile = true 57 | iam_role_name = "blog-instance-role" 58 | iam_role_policies = { 59 | AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" 60 | } 61 | scaling_policies = { 62 | avg-cpu-policy-greater-than-70 = { 63 | policy_type = "TargetTrackingScaling" 64 | estimated_instance_warmup = 1200 65 | target_tracking_configuration = { 66 | predefined_metric_specification = { 67 | predefined_metric_type = "ASGAverageCPUUtilization" 68 | } 69 | target_value = 70.0 70 | } 71 | } 72 | } 73 | } 74 | --------------------------------------------------------------------------------