├── 13-WAF.tf ├── A-backend.tf ├── 0-Auth.tf ├── 3-IGW.tf ├── 1-VPC.tf ├── 4-NAT.tf ├── 11-Key.tf ├── 12-Route53.tf ├── azure-pipelines.yml ├── 8-TargetGroup.tf ├── 9-LoadBalancer.tf ├── 6-SG01-All.tf ├── 2-Subnets.tf ├── 7-launchtemplate.tf ├── 10-AutoScalingGroup.tf └── 5-Route.tf /13-WAF.tf: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /A-backend.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | backend "s3" { 3 | bucket = "mylocalterraform" 4 | key = "MyLinuxBox" 5 | region = "eu-west-1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /0-Auth.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "eu-west-1" 3 | } 4 | 5 | terraform { 6 | required_providers { 7 | aws = { 8 | source = "hashicorp/aws" 9 | version = "~> 3.0" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /3-IGW.tf: -------------------------------------------------------------------------------- 1 | resource "aws_internet_gateway" "igw" { 2 | vpc_id = aws_vpc.app1.id 3 | 4 | tags = { 5 | Name = "app1_IG" 6 | Service = "application1" 7 | Owner = "Luke" 8 | Planet = "Musafar" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /1-VPC.tf: -------------------------------------------------------------------------------- 1 | # this makes vpc.id which is aws_vpc.app1.id 2 | resource "aws_vpc" "app1" { 3 | cidr_block = "10.32.0.0/16" 4 | 5 | tags = { 6 | Name = "app1" 7 | Service = "application1" 8 | Owner = "Chewbacca" 9 | Planet = "Mustafar" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /4-NAT.tf: -------------------------------------------------------------------------------- 1 | resource "aws_eip" "nat" { 2 | vpc = true 3 | 4 | tags = { 5 | Name = "nat" 6 | } 7 | } 8 | 9 | resource "aws_nat_gateway" "nat" { 10 | allocation_id = aws_eip.nat.id 11 | subnet_id = aws_subnet.public-eu-west-1a.id 12 | 13 | tags = { 14 | Name = "nat" 15 | } 16 | 17 | depends_on = [aws_internet_gateway.igw] 18 | } 19 | -------------------------------------------------------------------------------- /11-Key.tf: -------------------------------------------------------------------------------- 1 | resource "tls_private_key" "MyLinuxBox" { 2 | algorithm = "RSA" 3 | rsa_bits = 2048 4 | } 5 | 6 | data "tls_public_key" "MyLinuxBox" { 7 | private_key_pem = tls_private_key.MyLinuxBox.private_key_pem 8 | } 9 | 10 | output "private_key" { 11 | value = tls_private_key.MyLinuxBox.private_key_pem 12 | sensitive = true 13 | } 14 | 15 | output "public_key" { 16 | value = data.tls_public_key.MyLinuxBox.public_key_openssh 17 | } 18 | -------------------------------------------------------------------------------- /12-Route53.tf: -------------------------------------------------------------------------------- 1 | 2 | data "aws_route53_zone" "main" { 3 | name = "revanwar.com" # The domain name you want to look up 4 | private_zone = false 5 | } 6 | 7 | 8 | resource "aws_route53_record" "www" { 9 | zone_id = data.aws_route53_zone.main.zone_id 10 | name = "revanwar.com" 11 | type = "A" 12 | 13 | alias { 14 | name = aws_lb.app1_alb.dns_name 15 | zone_id = aws_lb.app1_alb.zone_id 16 | evaluate_target_health = true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Starter pipeline 2 | # Start with a minimal pipeline that you can customize to build and deploy your code. 3 | # Add steps that build, run tests, deploy, and more: 4 | # https://aka.ms/yaml 5 | 6 | trigger: 7 | - main 8 | 9 | pool: 10 | vmImage: ubuntu-latest 11 | 12 | steps: 13 | - script: echo Hello, world! 14 | displayName: 'Run a one-line script' 15 | 16 | - script: | 17 | echo Add other tasks to build, test, and deploy your project. 18 | echo See https://aka.ms/yaml 19 | displayName: 'Run a multi-line script' 20 | -------------------------------------------------------------------------------- /8-TargetGroup.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb_target_group" "app1_tg" { 2 | name = "app1-target-group" 3 | port = 80 4 | protocol = "HTTP" 5 | vpc_id = aws_vpc.app1.id 6 | target_type = "instance" 7 | 8 | health_check { 9 | enabled = true 10 | interval = 30 11 | path = "/" 12 | protocol = "HTTP" 13 | healthy_threshold = 5 14 | unhealthy_threshold = 2 15 | timeout = 5 16 | matcher = "200" 17 | } 18 | 19 | tags = { 20 | Name = "App1TargetGroup" 21 | Service = "App1" 22 | Owner = "User" 23 | Project = "Web Service" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /9-LoadBalancer.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb" "app1_alb" { 2 | name = "app1-load-balancer" 3 | internal = false 4 | load_balancer_type = "application" 5 | security_groups = [aws_security_group.app1-sg02-LB01.id] 6 | subnets = [ 7 | aws_subnet.public-eu-west-1a.id, 8 | aws_subnet.public-eu-west-1b.id, 9 | aws_subnet.public-eu-west-1c.id 10 | ] 11 | enable_deletion_protection = false 12 | #Lots of death and suffering here, make sure it's false 13 | 14 | tags = { 15 | Name = "App1LoadBalancer" 16 | Service = "App1" 17 | Owner = "User" 18 | Project = "Web Service" 19 | } 20 | } 21 | 22 | resource "aws_lb_listener" "http" { 23 | load_balancer_arn = aws_lb.app1_alb.arn 24 | port = 80 25 | protocol = "HTTP" 26 | 27 | default_action { 28 | type = "forward" 29 | target_group_arn = aws_lb_target_group.app1_tg.arn 30 | } 31 | } 32 | 33 | data "aws_acm_certificate" "cert" { 34 | domain = "balerica-aisecops.com" 35 | statuses = ["ISSUED"] 36 | most_recent = true 37 | } 38 | 39 | 40 | resource "aws_lb_listener" "https" { 41 | load_balancer_arn = aws_lb.app1_alb.arn 42 | port = 443 43 | protocol = "HTTPS" 44 | ssl_policy = "ELBSecurityPolicy-2016-08" # or whichever policy suits your requirements 45 | certificate_arn = data.aws_acm_certificate.cert.arn 46 | 47 | 48 | 49 | default_action { 50 | type = "forward" 51 | target_group_arn = aws_lb_target_group.app1_tg.arn 52 | } 53 | } 54 | 55 | output "lb_dns_name" { 56 | value = aws_lb.app1_alb.dns_name 57 | description = "The DNS name of the App1 Load Balancer." 58 | } 59 | -------------------------------------------------------------------------------- /6-SG01-All.tf: -------------------------------------------------------------------------------- 1 | resource "aws_security_group" "app1-sg01-servers" { 2 | name = "app1-sg01-servers" 3 | description = "app1-sg01-servers" 4 | vpc_id = aws_vpc.app1.id 5 | 6 | ingress { 7 | description = "MyHomePage" 8 | from_port = 80 9 | to_port = 80 10 | protocol = "tcp" 11 | cidr_blocks = ["0.0.0.0/0"] 12 | } 13 | 14 | ingress { 15 | description = "SSH" 16 | from_port = 22 17 | to_port = 22 18 | protocol = "tcp" 19 | cidr_blocks = ["0.0.0.0/0"] 20 | } 21 | 22 | ingress { 23 | description = "MyEvilBox" 24 | from_port = 3389 25 | to_port = 3389 26 | protocol = "tcp" 27 | cidr_blocks = ["0.0.0.0/0"] 28 | } 29 | 30 | 31 | egress { 32 | from_port = 0 33 | to_port = 0 34 | protocol = "-1" 35 | cidr_blocks = ["0.0.0.0/0"] 36 | } 37 | 38 | tags = { 39 | Name = "app1-sg01-servers" 40 | Service = "application1" 41 | Owner = "Luke" 42 | Planet = "Musafar" 43 | } 44 | 45 | } 46 | 47 | 48 | 49 | 50 | 51 | resource "aws_security_group" "app1-sg02-LB01" { 52 | name = "app1-sg02-LB01" 53 | description = "app1-sg02-LB01" 54 | vpc_id = aws_vpc.app1.id 55 | 56 | ingress { 57 | description = "MyHomePage" 58 | from_port = 80 59 | to_port = 80 60 | protocol = "tcp" 61 | cidr_blocks = ["0.0.0.0/0"] 62 | } 63 | 64 | egress { 65 | from_port = 0 66 | to_port = 0 67 | protocol = "-1" 68 | cidr_blocks = ["0.0.0.0/0"] 69 | } 70 | 71 | tags = { 72 | Name = "app1-sg02-LB01" 73 | Service = "application1" 74 | Owner = "Luke" 75 | Planet = "Musafar" 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /2-Subnets.tf: -------------------------------------------------------------------------------- 1 | #These are for public 2 | 3 | resource "aws_subnet" "public-eu-west-1a" { 4 | vpc_id = aws_vpc.app1.id 5 | cidr_block = "10.32.1.0/24" 6 | availability_zone = "eu-west-1a" 7 | map_public_ip_on_launch = true 8 | 9 | tags = { 10 | Name = "public-eu-west-1a" 11 | Service = "application1" 12 | Owner = "Luke" 13 | Planet = "Musafar" 14 | } 15 | } 16 | 17 | resource "aws_subnet" "public-eu-west-1b" { 18 | vpc_id = aws_vpc.app1.id 19 | cidr_block = "10.32.2.0/24" 20 | availability_zone = "eu-west-1b" 21 | map_public_ip_on_launch = true 22 | 23 | tags = { 24 | Name = "public-eu-west-1b" 25 | Service = "application1" 26 | Owner = "Luke" 27 | Planet = "Musafar" 28 | } 29 | } 30 | 31 | 32 | resource "aws_subnet" "public-eu-west-1c" { 33 | vpc_id = aws_vpc.app1.id 34 | cidr_block = "10.32.3.0/24" 35 | availability_zone = "eu-west-1c" 36 | map_public_ip_on_launch = true 37 | 38 | tags = { 39 | Name = "public-eu-west-1c" 40 | Service = "application1" 41 | Owner = "Luke" 42 | Planet = "Musafar" 43 | } 44 | } 45 | 46 | #these are for private 47 | resource "aws_subnet" "private-eu-west-1a" { 48 | vpc_id = aws_vpc.app1.id 49 | cidr_block = "10.32.11.0/24" 50 | availability_zone = "eu-west-1a" 51 | 52 | tags = { 53 | Name = "private-eu-west-1a" 54 | Service = "application1" 55 | Owner = "Luke" 56 | Planet = "Musafar" 57 | } 58 | } 59 | 60 | resource "aws_subnet" "private-eu-west-1b" { 61 | vpc_id = aws_vpc.app1.id 62 | cidr_block = "10.32.12.0/24" 63 | availability_zone = "eu-west-1b" 64 | 65 | tags = { 66 | Name = "private-eu-west-1b" 67 | Service = "application1" 68 | Owner = "Luke" 69 | Planet = "Musafar" 70 | } 71 | } 72 | 73 | 74 | resource "aws_subnet" "private-eu-west-1c" { 75 | vpc_id = aws_vpc.app1.id 76 | cidr_block = "10.32.13.0/24" 77 | availability_zone = "eu-west-1c" 78 | 79 | tags = { 80 | Name = "private-eu-west-1c" 81 | Service = "application1" 82 | Owner = "Luke" 83 | Planet = "Musafar" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /7-launchtemplate.tf: -------------------------------------------------------------------------------- 1 | resource "aws_launch_template" "app1_LT" { 2 | name_prefix = "app1_LT" 3 | image_id = "ami-06ed60ed1369448bd" 4 | instance_type = "t2.micro" 5 | 6 | key_name = "MyLinuxBox" 7 | 8 | vpc_security_group_ids = [aws_security_group.app1-sg01-servers.id] 9 | 10 | user_data = base64encode(<<-EOF 11 | #!/bin/bash 12 | yum update -y 13 | yum install -y httpd 14 | systemctl start httpd 15 | systemctl enable httpd 16 | 17 | # Get the IMDSv2 token 18 | TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") 19 | 20 | # Background the curl requests 21 | curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/local-ipv4 &> /tmp/local_ipv4 & 22 | curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/placement/availability-zone &> /tmp/az & 23 | curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/ &> /tmp/macid & 24 | wait 25 | 26 | macid=$(cat /tmp/macid) 27 | local_ipv4=$(cat /tmp/local_ipv4) 28 | az=$(cat /tmp/az) 29 | vpc=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/network/interfaces/macs/$macid/vpc-id) 30 | 31 | # Create HTML file 32 | cat <<-HTML > /var/www/html/index.html 33 | 34 | 35 | 36 | Details for EC2 instance 37 | 38 | 39 |
40 |

Malgus Clan

41 |

Chains Broken in Ireland

42 |

Instance Name: $(hostname -f)

43 |

Instance Private Ip Address: $local_ipv4

44 |

Availability Zone: $az

45 |

Virtual Private Cloud (VPC): $vpc

46 |
47 | 48 | 49 | HTML 50 | 51 | # Clean up the temp files 52 | rm -f /tmp/local_ipv4 /tmp/az /tmp/macid 53 | EOF 54 | ) 55 | 56 | tag_specifications { 57 | resource_type = "instance" 58 | tags = { 59 | Name = "app1_LT" 60 | Service = "application1" 61 | Owner = "Chewbacca" 62 | Planet = "Mustafar" 63 | } 64 | } 65 | 66 | lifecycle { 67 | create_before_destroy = true 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /10-AutoScalingGroup.tf: -------------------------------------------------------------------------------- 1 | resource "aws_autoscaling_group" "app1_asg" { 2 | name_prefix = "app1-auto-scaling-group-" 3 | min_size = 3 4 | max_size = 15 5 | desired_capacity = 6 6 | vpc_zone_identifier = [ 7 | aws_subnet.private-eu-west-1a.id, 8 | aws_subnet.private-eu-west-1b.id, 9 | aws_subnet.private-eu-west-1c.id 10 | ] 11 | health_check_type = "ELB" 12 | health_check_grace_period = 300 13 | force_delete = true 14 | target_group_arns = [aws_lb_target_group.app1_tg.arn] 15 | 16 | launch_template { 17 | id = aws_launch_template.app1_LT.id 18 | version = "$Latest" 19 | } 20 | 21 | enabled_metrics = ["GroupMinSize", "GroupMaxSize", "GroupDesiredCapacity", "GroupInServiceInstances", "GroupTotalInstances"] 22 | 23 | # Instance protection for launching 24 | initial_lifecycle_hook { 25 | name = "instance-protection-launch" 26 | lifecycle_transition = "autoscaling:EC2_INSTANCE_LAUNCHING" 27 | default_result = "CONTINUE" 28 | heartbeat_timeout = 60 29 | notification_metadata = "{\"key\":\"value\"}" 30 | } 31 | 32 | # Instance protection for terminating 33 | initial_lifecycle_hook { 34 | name = "scale-in-protection" 35 | lifecycle_transition = "autoscaling:EC2_INSTANCE_TERMINATING" 36 | default_result = "CONTINUE" 37 | heartbeat_timeout = 300 38 | } 39 | 40 | tag { 41 | key = "Name" 42 | value = "app1-instance" 43 | propagate_at_launch = true 44 | } 45 | 46 | tag { 47 | key = "Environment" 48 | value = "Production" 49 | propagate_at_launch = true 50 | } 51 | } 52 | 53 | 54 | # Auto Scaling Policy 55 | resource "aws_autoscaling_policy" "app1_scaling_policy" { 56 | name = "app1-cpu-target" 57 | autoscaling_group_name = aws_autoscaling_group.app1_asg.name 58 | 59 | policy_type = "TargetTrackingScaling" 60 | estimated_instance_warmup = 120 61 | 62 | target_tracking_configuration { 63 | predefined_metric_specification { 64 | predefined_metric_type = "ASGAverageCPUUtilization" 65 | } 66 | target_value = 75.0 67 | } 68 | } 69 | 70 | # Enabling instance scale-in protection 71 | resource "aws_autoscaling_attachment" "app1_asg_attachment" { 72 | autoscaling_group_name = aws_autoscaling_group.app1_asg.name 73 | alb_target_group_arn = aws_lb_target_group.app1_tg.arn 74 | } 75 | -------------------------------------------------------------------------------- /5-Route.tf: -------------------------------------------------------------------------------- 1 | resource "aws_route_table" "private" { 2 | vpc_id = aws_vpc.app1.id 3 | 4 | route = [ 5 | { 6 | cidr_block = "0.0.0.0/0" 7 | nat_gateway_id = aws_nat_gateway.nat.id 8 | carrier_gateway_id = "" 9 | destination_prefix_list_id = "" 10 | egress_only_gateway_id = "" 11 | gateway_id = "" 12 | instance_id = "" 13 | ipv6_cidr_block = "" 14 | local_gateway_id = "" 15 | network_interface_id = "" 16 | transit_gateway_id = "" 17 | vpc_endpoint_id = "" 18 | vpc_peering_connection_id = "" 19 | }, 20 | ] 21 | 22 | tags = { 23 | Name = "private" 24 | } 25 | } 26 | 27 | resource "aws_route_table" "public" { 28 | vpc_id = aws_vpc.app1.id 29 | 30 | route = [ 31 | { 32 | cidr_block = "0.0.0.0/0" 33 | gateway_id = aws_internet_gateway.igw.id 34 | nat_gateway_id = "" 35 | carrier_gateway_id = "" 36 | destination_prefix_list_id = "" 37 | egress_only_gateway_id = "" 38 | instance_id = "" 39 | ipv6_cidr_block = "" 40 | local_gateway_id = "" 41 | network_interface_id = "" 42 | transit_gateway_id = "" 43 | vpc_endpoint_id = "" 44 | vpc_peering_connection_id = "" 45 | }, 46 | ] 47 | 48 | tags = { 49 | Name = "public" 50 | } 51 | } 52 | 53 | resource "aws_route_table_association" "private-eu-west-1a" { 54 | subnet_id = aws_subnet.private-eu-west-1a.id 55 | route_table_id = aws_route_table.private.id 56 | } 57 | 58 | resource "aws_route_table_association" "private-eu-west-1b" { 59 | subnet_id = aws_subnet.private-eu-west-1b.id 60 | route_table_id = aws_route_table.private.id 61 | } 62 | resource "aws_route_table_association" "private-eu-west-1c" { 63 | subnet_id = aws_subnet.private-eu-west-1c.id 64 | route_table_id = aws_route_table.private.id 65 | } 66 | 67 | 68 | #public 69 | 70 | resource "aws_route_table_association" "public-eu-west-1a" { 71 | subnet_id = aws_subnet.public-eu-west-1a.id 72 | route_table_id = aws_route_table.public.id 73 | } 74 | 75 | resource "aws_route_table_association" "public-eu-west-1b" { 76 | subnet_id = aws_subnet.public-eu-west-1b.id 77 | route_table_id = aws_route_table.public.id 78 | } 79 | 80 | resource "aws_route_table_association" "public-eu-west-1c" { 81 | subnet_id = aws_subnet.public-eu-west-1c.id 82 | route_table_id = aws_route_table.public.id 83 | } 84 | --------------------------------------------------------------------------------