Repository: adv4000/terraform-lessons Branch: master Commit: 0f1e1b970f13 Files: 150 Total size: 101.7 KB Directory structure: gitextract_d5h_045t/ ├── .gitignore ├── Lesson-01/ │ └── Lesson-1.tf ├── Lesson-02/ │ └── WebServer.tf ├── Lesson-03/ │ ├── WebServer.tf │ └── user_data.sh ├── Lesson-04/ │ ├── WebServer.tf │ └── user_data.sh.tpl ├── Lesson-05/ │ └── DynamicSecurityGroup.tf ├── Lesson-06/ │ ├── WebServer.tf │ └── user_data.sh.tpl ├── Lesson-07/ │ ├── main.tf │ ├── outputs.tf │ └── user_data.sh.tpl ├── Lesson-08/ │ └── main.tf ├── Lesson-09/ │ └── main.tf ├── Lesson-10/ │ └── main.tf ├── Lesson-11-ALB-LaunchTemplate/ │ ├── main.tf │ └── user_data.sh ├── Lesson-11-ELB-LaunchConfiguration/ │ ├── main.tf │ └── user_data.sh ├── Lesson-12/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-13/ │ ├── dev.tfvars │ ├── main.tf │ ├── outputs.tf │ ├── prod.tfvars │ └── variables.tf ├── Lesson-14/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-15/ │ └── main.tf ├── Lesson-16/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-17/ │ ├── main.tf │ └── variables.tf ├── Lesson-18/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-19/ │ └── main.tf ├── Lesson-20/ │ ├── Layer1-Network/ │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── Layer2-Servers/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-21/ │ ├── modules/ │ │ ├── aws_network/ │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── aws_security_group/ │ │ │ └── main.tf │ │ └── aws_something/ │ │ └── main.tf │ └── projectA/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-22/ │ ├── ProjectXYZ/ │ │ ├── dev/ │ │ │ ├── kms/ │ │ │ │ └── main.tf │ │ │ ├── network/ │ │ │ │ └── main.tf │ │ │ ├── route53/ │ │ │ │ └── main.tf │ │ │ ├── s3/ │ │ │ │ └── main.tf │ │ │ └── vpc/ │ │ │ ├── applications/ │ │ │ │ ├── app1/ │ │ │ │ │ └── main.tf │ │ │ │ └── app2/ │ │ │ │ └── main.tf │ │ │ ├── databases/ │ │ │ │ └── main.tf │ │ │ ├── ecs_cluster/ │ │ │ │ └── main.tf │ │ │ └── vpn/ │ │ │ └── main.tf │ │ ├── prod/ │ │ │ ├── kms/ │ │ │ │ └── main.tf │ │ │ ├── network/ │ │ │ │ └── main.tf │ │ │ ├── route53/ │ │ │ │ └── main.tf │ │ │ ├── s3/ │ │ │ │ └── main.tf │ │ │ └── vpc/ │ │ │ ├── applications/ │ │ │ │ ├── app1/ │ │ │ │ │ └── main.tf │ │ │ │ └── app2/ │ │ │ │ └── main.tf │ │ │ ├── databases/ │ │ │ │ └── main.tf │ │ │ ├── ecs_cluster/ │ │ │ │ └── main.tf │ │ │ └── vpn/ │ │ │ └── main.tf │ │ └── staging/ │ │ ├── kms/ │ │ │ └── main.tf │ │ ├── network/ │ │ │ └── main.tf │ │ ├── route53/ │ │ │ └── main.tf │ │ ├── s3/ │ │ │ └── main.tf │ │ └── vpc/ │ │ ├── applications/ │ │ │ ├── app1/ │ │ │ │ └── main.tf │ │ │ └── app2/ │ │ │ └── main.tf │ │ ├── databases/ │ │ │ └── main.tf │ │ ├── ecs_cluster/ │ │ │ └── main.tf │ │ └── vpn/ │ │ └── main.tf │ ├── README.MD │ └── modules/ │ ├── aws_network/ │ │ └── main.tf │ ├── aws_security_group/ │ │ └── main.tf │ └── aws_something/ │ └── main.tf ├── Lesson-23/ │ ├── globalvars/ │ │ └── main.tf │ ├── stack1/ │ │ └── main.tf │ └── stack2/ │ └── main.tf ├── Lesson-24/ │ ├── main.tf │ └── mygcp-creds.json ├── Lesson-25/ │ └── README.MD ├── Lesson-26/ │ ├── import-begin.tf │ └── import-finish.tf ├── Lesson-27/ │ └── main.tf ├── Lesson-27-v0.15.2+/ │ └── main.tf ├── Lesson-28/ │ ├── new-prod/ │ │ ├── config.tf │ │ ├── ip-prod.tf │ │ ├── main.tf │ │ └── web-prod.tf │ ├── new-staging/ │ │ ├── config.tf │ │ ├── ip-stag.tf │ │ ├── main.tf │ │ └── web-stag.tf │ └── old-all/ │ ├── config.tf │ ├── ip-prod.tf │ ├── ip-stag.tf │ ├── main.tf │ ├── web-prod.tf │ └── web-stag.tf ├── Lesson-29/ │ ├── config.tf │ └── main.tf ├── Lesson-30/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-31/ │ ├── main.tf │ ├── modules/ │ │ ├── aws_network/ │ │ │ ├── main.tf │ │ │ ├── outputs.tf │ │ │ └── variables.tf │ │ ├── aws_security_group/ │ │ │ └── main.tf │ │ └── aws_something/ │ │ └── main.tf │ └── variables.tf ├── Lesson-32/ │ ├── main.tf │ └── module_servers/ │ ├── main.tf │ └── variables.tf ├── Lesson-33/ │ ├── iam_groups.tf │ ├── iam_groups_policies.tf │ └── variables.tf ├── Lesson-34/ │ └── main.tf ├── Lesson-35/ │ ├── deployments/ │ │ ├── dev/ │ │ │ ├── config.tf │ │ │ └── main.tf │ │ └── prod/ │ │ ├── config.tf │ │ └── main.tf │ ├── module-aws-rds/ │ │ ├── main.tf │ │ ├── outputs.tf │ │ └── variables.tf │ └── module-aws-vpc/ │ ├── main.tf │ ├── outputs.tf │ └── variables.tf ├── Lesson-36/ │ ├── ephemeral/ │ │ └── main.tf │ └── non-ephemeral/ │ └── main.tf ├── Lesson-37/ │ ├── action/ │ │ ├── lambda_function.py │ │ ├── lambda_function.tf │ │ ├── main.tf │ │ └── variables.tf │ └── non-action/ │ ├── lambda_function.py │ ├── lambda_function.tf │ ├── main.tf │ └── variables.tf └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .terraform/ *.tfstate *.tfstate.backup *.terraform.lock.hcl ================================================ FILE: Lesson-01/Lesson-1.tf ================================================ provider "aws" {} resource "aws_instance" "my_Ubuntu" { ami = "ami-090f10efc254eaf55" instance_type = "t3.micro" tags = { Name = "My Ubuntu Server" Owner = "Denis Astahov" Project = "Terraform Lessons" } } resource "aws_instance" "my_Amazon" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.small" tags = { Name = "My Amazon Server" Owner = "Denis Astahov" Project = "Terraform Lessons" } } ================================================ FILE: Lesson-02/WebServer.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_instance" "my_webserver" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] user_data_replace_on_change = true # This need to added!!!! user_data = <WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "Web Server Build by Terraform" Owner = "Denis Astahov" } } resource "aws_security_group" "my_webserver" { name = "WebServer Security Group" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-03/WebServer.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_instance" "my_webserver" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] user_data = file("user_data.sh") tags = { Name = "Web Server Build by Terraform" Owner = "Denis Astahov" } } resource "aws_security_group" "my_webserver" { name = "WebServer Security Group" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-03/user_data.sh ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` echo "

WebServer with IP: $myip


Build by Terraform using External Script!" > /var/www/html/index.html echo "
Hello World!!" >> /var/www/html/index.html sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-04/WebServer.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_instance" "my_webserver" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] user_data = templatefile("user_data.sh.tpl", { f_name = "Denis", l_name = "Astahov", names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha"] }) tags = { Name = "Web Server Build by Terraform" Owner = "Denis Astahov" } } resource "aws_security_group" "my_webserver" { name = "WebServer Security Group" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-04/user_data.sh.tpl ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` cat < /var/www/html/index.html

Build by Power of Terraform v0.12


Owner ${f_name} ${l_name}
%{ for x in names ~} Hello to ${x} from ${f_name}
%{ endfor ~} EOF sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-05/DynamicSecurityGroup.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "my_webserver" { name = "Dynamic Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = ["80", "443", "8080", "1541", "9092", "9093"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["10.10.0.0/16"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Dynamic SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-06/WebServer.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_eip" "my_static_ip" { instance = aws_instance.my_webserver.id domain = "vpc" # Need to add in new AWS Provider version tags = { Name = "Web Server IP" Owner = "Denis Astahov" } } resource "aws_instance" "my_webserver" { ami = "ami-07ab3281411d31d04" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] user_data = templatefile("user_data.sh.tpl", { f_name = "Denis", l_name = "Astahov", names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"] }) user_data_replace_on_change = true # Added in the new AWS provider!!! tags = { Name = "Web Server Build by Terraform" Owner = "Denis Astahov" } lifecycle { create_before_destroy = true } } resource "aws_security_group" "my_webserver" { name = "WebServer Security Group" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = ["80", "443"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-06/user_data.sh.tpl ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` cat < /var/www/html/index.html

Build by Power of Terraform v0.12


Owner ${f_name} ${l_name}
%{ for x in names ~} Hello to ${x} from ${f_name}
%{ endfor ~}

Server IP: $myip
EOF sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-07/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Build WebServer during Bootstrap # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_eip" "my_static_ip" { vpc = true # Need to add in new AWS Provider version instance = aws_instance.my_webserver.id tags = { Name = "Web Server IP" Owner = "Denis Astahov" } } resource "aws_instance" "my_webserver" { ami = "ami-07ab3281411d31d04" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] user_data = templatefile("user_data.sh.tpl", { f_name = "Denis", l_name = "Astahov", names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"] }) tags = { Name = "Web Server Build by Terraform" Owner = "Denis Astahov" } lifecycle { create_before_destroy = true } } resource "aws_security_group" "my_webserver" { name = "WebServer Security Group" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = ["80", "443"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-07/outputs.tf ================================================ output "my_web_site_ip" { description = "Elatic IP address assigned to our WebSite" value = aws_eip.my_static_ip.public_ip } output "my_instance_id" { description = "InstanceID of our WebSite" value = aws_instance.my_webserver.id } output "my_instance_arn" { description = "InstanceARN of our WebSite" value = aws_instance.my_webserver.arn } output "my_sg_id" { description = "SecurityGroup of our WebSite" value = aws_security_group.my_webserver.id } ================================================ FILE: Lesson-07/user_data.sh.tpl ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` cat < /var/www/html/index.html

Build by Power of Terraform v0.12


Owner ${f_name} ${l_name}
%{ for x in names ~} Hello to ${x} from ${f_name}
%{ endfor ~}

Server IP: $myip
EOF sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-08/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_instance" "my_server_web" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] tags = { Name = "Server-Web" } depends_on = [aws_instance.my_server_db, aws_instance.my_server_app] } resource "aws_instance" "my_server_app" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] tags = { Name = "Server-Application" } depends_on = [aws_instance.my_server_db] } resource "aws_instance" "my_server_db" { ami = "ami-03a71cec707bfc3d7" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.my_webserver.id] tags = { Name = "Server-Database" } } resource "aws_security_group" "my_webserver" { name = "My Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = ["80", "443", "22"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "My SecurityGroup" } } ================================================ FILE: Lesson-09/main.tf ================================================ provider "aws" {} data "aws_availability_zones" "working" {} data "aws_caller_identity" "current" {} data "aws_region" "current" {} data "aws_vpcs" "my_vpcs" {} data "aws_vpc" "prod_vpc" { tags = { Name = "prod" } } resource "aws_subnet" "prod_subnet_1" { vpc_id = data.aws_vpc.prod_vpc.id availability_zone = data.aws_availability_zones.working.names[0] cidr_block = "10.10.1.0/24" tags = { Name = "Subnet-1 in ${data.aws_availability_zones.working.names[0]}" Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}" Region = data.aws_region.current.description } } resource "aws_subnet" "prod_subnet_2" { vpc_id = data.aws_vpc.prod_vpc.id availability_zone = data.aws_availability_zones.working.names[1] cidr_block = "10.10.2.0/24" tags = { Name = "Subnet-2 in ${data.aws_availability_zones.working.names[1]}" Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}" Region = data.aws_region.current.description } } output "prod_vpc_id" { value = data.aws_vpc.prod_vpc.id } output "prod_vpc_cidr" { value = data.aws_vpc.prod_vpc.cidr_block } output "aws_vpcs" { value = data.aws_vpcs.my_vpcs.ids } output "data_aws_availability_zones" { value = data.aws_availability_zones.working.names } output "data_aws_caller_identity" { value = data.aws_caller_identity.current.account_id } output "data_aws_region_name" { value = data.aws_region.current.region } output "data_aws_region_description" { value = data.aws_region.current.description } ================================================ FILE: Lesson-10/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Find Latest AMI id of: # - Ubuntu 18.04 # - Amazon Linux 2 # - Windows Server 2016 Base # # Made by Denis Astahov #----------------------------------------------------------- provider "aws" { region = "ap-southeast-2" } data "aws_ami" "latest_ubuntu" { owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] } } data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } data "aws_ami" "latest_windows_2016" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["Windows_Server-2016-English-Full-Base-*"] } } // How to use /* resource "aws_instance" "my_webserver_with_latest_ubuntu_ami" { ami = data.aws_ami.latest_ubuntu.id instance_type = "t3.micro" } */ output "latest_windows_2016_ami_id" { value = data.aws_ami.latest_windows_2016.id } output "latest_windows_2016_ami_name" { value = data.aws_ami.latest_windows_2016.name } output "latest_amazon_linux_ami_id" { value = data.aws_ami.latest_amazon_linux.id } output "latest_amazon_linux_ami_name" { value = data.aws_ami.latest_amazon_linux.name } output "latest_ubuntu_ami_id" { value = data.aws_ami.latest_ubuntu.id } output "latest_ubuntu_ami_name" { value = data.aws_ami.latest_ubuntu.name } ================================================ FILE: Lesson-11-ALB-LaunchTemplate/main.tf ================================================ #---------------------------------------------------------- # Provision Highly Availabe Web in any Region Default VPC # Create: # - Security Group for Web Server and ALB # - Launch Template with Auto AMI Lookup # - Auto Scaling Group using 2 Availability Zones # - Application Load Balancer in 2 Availability Zones # - Application Load Balancer TargetGroup # Update to Web Servers will be via Green/Blue Deployment Strategy # Made by Denis Astahov 07-March-2023 #----------------------------------------------------------- provider "aws" { region = "ca-central-1" default_tags { tags = { Owner = "Denis Astahov" CreatedBy = "Terraform" Course = "From Zero to Certified Professional" } } } data "aws_availability_zones" "working" {} data "aws_ami" "latest_amazon_linux" { owners = ["137112412989"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } #------------------------------------------------------------------------------- resource "aws_default_vpc" "default" {} resource "aws_default_subnet" "default_az1" { availability_zone = data.aws_availability_zones.working.names[0] } resource "aws_default_subnet" "default_az2" { availability_zone = data.aws_availability_zones.working.names[1] } #------------------------------------------------------------------------------- resource "aws_security_group" "web" { name = "Web Security Group" vpc_id = aws_default_vpc.default.id dynamic "ingress" { for_each = ["80", "443"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Security Group" } } #------------------------------------------------------------------------------- resource "aws_launch_template" "web" { name = "WebServer-Highly-Available-LT" image_id = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web.id] user_data = filebase64("${path.module}/user_data.sh") } resource "aws_autoscaling_group" "web" { name = "WebServer-Highly-Available-ASG-Ver-${aws_launch_template.web.latest_version}" min_size = 2 max_size = 2 min_elb_capacity = 2 health_check_type = "ELB" vpc_zone_identifier = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] target_group_arns = [aws_lb_target_group.web.arn] launch_template { id = aws_launch_template.web.id version = aws_launch_template.web.latest_version } dynamic "tag" { for_each = { Name = "WebServer in ASG-v${aws_launch_template.web.latest_version}" TAGKEY = "TAGVALUE" } content { key = tag.key value = tag.value propagate_at_launch = true } } lifecycle { create_before_destroy = true } } #------------------------------------------------------------------------------- resource "aws_lb" "web" { name = "WebServer-HighlyAvailable-ALB" load_balancer_type = "application" security_groups = [aws_security_group.web.id] subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] } resource "aws_lb_target_group" "web" { name = "WebServer-HighlyAvailable-TG" vpc_id = aws_default_vpc.default.id port = 80 protocol = "HTTP" deregistration_delay = 10 # seconds } resource "aws_lb_listener" "http" { load_balancer_arn = aws_lb.web.arn port = "80" protocol = "HTTP" default_action { type = "forward" target_group_arn = aws_lb_target_group.web.arn } } #------------------------------------------------------------------------------- output "web_loadbalancer_url" { value = aws_lb.web.dns_name } ================================================ FILE: Lesson-11-ALB-LaunchTemplate/user_data.sh ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` cat < /var/www/html/index.html

Build by Power of Terraform v0.12


Server PrivateIP: $myip

Version 3.0 EOF sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-11-ELB-LaunchConfiguration/main.tf ================================================ #---------------------------------------------------------- # Provision Highly Availabe Web in any Region Default VPC # Create: # - Security Group for Web Server # - Launch Configuration with Auto AMI Lookup # - Auto Scaling Group using 2 Availability Zones # - Classic Load Balancer in 2 Availability Zones # # Made by Denis Astahov 11-June-2019 #----------------------------------------------------------- provider "aws" { region = "eu-west-2" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id data "aws_availability_zones" "available" {} data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } #-------------------------------------------------------------- resource "aws_security_group" "web" { name = "Dynamic Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = ["80", "443"] content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Dynamic SecurityGroup" Owner = "Denis Astahov" } } resource "aws_launch_configuration" "web" { // name = "WebServer-Highly-Available-LC" name_prefix = "WebServer-Highly-Available-LC-" image_id = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" security_groups = [aws_security_group.web.id] user_data = file("user_data.sh") lifecycle { create_before_destroy = true } } resource "aws_autoscaling_group" "web" { name = "ASG-${aws_launch_configuration.web.name}" launch_configuration = aws_launch_configuration.web.name min_size = 2 max_size = 2 min_elb_capacity = 2 health_check_type = "ELB" vpc_zone_identifier = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] load_balancers = [aws_elb.web.name] dynamic "tag" { for_each = { Name = "WebServer in ASG" Owner = "Denis Astahov" TAGKEY = "TAGVALUE" } content { key = tag.key value = tag.value propagate_at_launch = true } } lifecycle { create_before_destroy = true } } resource "aws_elb" "web" { name = "WebServer-HA-ELB" availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]] security_groups = [aws_security_group.web.id] listener { lb_port = 80 lb_protocol = "http" instance_port = 80 instance_protocol = "http" } health_check { healthy_threshold = 2 unhealthy_threshold = 2 timeout = 3 target = "HTTP:80/" interval = 10 } tags = { Name = "WebServer-Highly-Available-ELB" } } resource "aws_default_subnet" "default_az1" { availability_zone = data.aws_availability_zones.available.names[0] } resource "aws_default_subnet" "default_az2" { availability_zone = data.aws_availability_zones.available.names[1] } #-------------------------------------------------- output "web_loadbalancer_url" { value = aws_elb.web.dns_name } ================================================ FILE: Lesson-11-ELB-LaunchConfiguration/user_data.sh ================================================ #!/bin/bash yum -y update yum -y install httpd myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` cat < /var/www/html/index.html

Build by Power of Terraform v0.12


Server PrivateIP: $myip

Version 3.0 EOF sudo service httpd start chkconfig httpd on ================================================ FILE: Lesson-12/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Variables # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = var.region } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } resource "aws_eip" "my_static_ip" { vpc = true # Need to add in new AWS Provider version instance = aws_instance.my_server.id //tags = var.common_tags tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server IP" }) /* tags = { Name = "Server IP" Owner = "Denis Astahov" Project = "Phoenix" } */ } resource "aws_instance" "my_server" { ami = data.aws_ami.latest_amazon_linux.id instance_type = var.instance_type vpc_security_group_ids = [aws_security_group.my_server.id] monitoring = var.enable_detailed_monitoring tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server Build by Terraform" }) } resource "aws_security_group" "my_server" { name = "My Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = var.allow_ports content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server SecurityGroup" }) } ================================================ FILE: Lesson-12/outputs.tf ================================================ output "my_server_ip" { value = aws_eip.my_static_ip.public_ip } output "my_instance_id" { value = aws_instance.my_server.id } output "my_sg_id" { value = aws_security_group.my_server.id } ================================================ FILE: Lesson-12/variables.tf ================================================ variable "region" { description = "Please Enter AWS Region to deploy Server" type = string default = "ca-central-1" } variable "instance_type" { description = "Enter Instance Type" type = string default = "t3.small" } variable "allow_ports" { description = "List of Ports to open for server" type = list default = ["80", "443", "22", "8080"] } variable "enable_detailed_monitoring" { type = bool default = false } variable "common_tags" { description = "Common Tags to apply to all resources" type = map default = { Owner = "Denis Astahov" Project = "Phoenix" CostCenter = "12345" Environment = "development" } } ================================================ FILE: Lesson-13/dev.tfvars ================================================ # Auto Fill variables for DEV #File names can be as: # terraform.tfvars # prod.auto.tfvars # dev.auto.tfvars region = "ca-central-1" instance_type = "t2.micro" enable_detailed_monitoring = false allow_ports = ["80", "22", "8080"] common_tags = { Owner = "Denis Astahov" Project = "Phoenix" CostCenter = "12345" Environment = "dev" } ================================================ FILE: Lesson-13/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Autofill Variables # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = var.region } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } resource "aws_eip" "my_static_ip" { vpc = true # Need to add in new AWS Provider version instance = aws_instance.my_server.id //tags = var.common_tags tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server IP" }) /* tags = { Name = "Server IP" Owner = "Denis Astahov" Project = "Phoenix" } */ } resource "aws_instance" "my_server" { ami = data.aws_ami.latest_amazon_linux.id instance_type = var.instance_type vpc_security_group_ids = [aws_security_group.my_server.id] monitoring = var.enable_detailed_monitoring tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server Build by Terraform" }) } resource "aws_security_group" "my_server" { name = "My Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = var.allow_ports content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server SecurityGroup" }) } ================================================ FILE: Lesson-13/outputs.tf ================================================ output "my_server_ip" { value = aws_eip.my_static_ip.public_ip } output "my_instance_id" { value = aws_instance.my_server.id } output "my_sg_id" { value = aws_security_group.my_server.id } ================================================ FILE: Lesson-13/prod.tfvars ================================================ # Auto Fill variables for PROD #File names can be as: # terraform.tfvars # prod.auto.tfvars # dev.auto.tfvars region = "ca-central-1" instance_type = "t2.small" enable_detailed_monitoring = true allow_ports = ["80", "443"] common_tags = { Owner = "Denis Astahov" Project = "Phoenix" CostCenter = "123477" Environment = "prod" } ================================================ FILE: Lesson-13/variables.tf ================================================ variable "region" { description = "Please Enter AWS Region to deploy Server" type = string default = "ca-central-1" } variable "instance_type" { description = "Enter Instance Type" type = string default = "t3.small" } variable "allow_ports" { description = "List of Ports to open for server" type = list default = ["80", "443", "22", "8080"] } variable "enable_detailed_monitoring" { type = bool default = false } variable "common_tags" { description = "Common Tags to apply to all resources" type = map default = { Owner = "Denis Astahov" Project = "Phoenix" CostCenter = "12345" Environment = "development" } } ================================================ FILE: Lesson-14/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Local Variables # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } data "aws_region" "current" {} data "aws_availability_zones" "available" {} locals { full_project_name = "${var.environment}-${var.project_name}" project_owner = "${var.owner} owner of ${var.project_name}" } locals { country = "Canada" city = "Deadmonton" az_list = join(",", data.aws_availability_zones.available.names) region = data.aws_region.current.description location = "In ${local.region} there are AZ: ${local.az_list}" } resource "aws_eip" "my_static_ip" { vpc = true # Need to add in new AWS Provider version tags = { Name = "Static IP" Owner = var.owner Project = local.full_project_name proj_owner = local.project_owner city = local.city region_azs = local.az_list location = local.location } } ================================================ FILE: Lesson-14/outputs.tf ================================================ output "my_static_ip" { value = aws_eip.my_static_ip.public_ip } ================================================ FILE: Lesson-14/variables.tf ================================================ variable "environment" { default = "DEV" } variable "project_name" { default = "ANDESA" } variable "owner" { default = "Denis Astahov" } ================================================ FILE: Lesson-15/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Execute Local Commands on Computer with Terraform # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } resource "null_resource" "command1" { provisioner "local-exec" { command = "echo Terraform START: $(date) >> log.txt" } } resource "null_resource" "command2" { provisioner "local-exec" { command = "ping -c 5 www.google.com" } } resource "null_resource" "command3" { provisioner "local-exec" { command = "print('Hello World!')" interpreter = ["python", "-c"] } } resource "null_resource" "command4" { provisioner "local-exec" { command = "echo $NAME1 $NAME2 $NAME3 >> names.txt" environment = { NAME1 = "Vasya" NAME2 = "Petya" NAME3 = "Kolya" } } } resource "aws_instance" "myserver" { ami = "ami-08a9b721ecc5b0a53" instance_type = "t3.micro" provisioner "local-exec" { command = "echo Hello from AWS Instance Creations!" } } resource "null_resource" "command6" { provisioner "local-exec" { command = "echo Terraform END: $(date) >> log.txt" } depends_on = [null_resource.command1, null_resource.command2, null_resource.command3, null_resource.command4, aws_instance.myserver] } ================================================ FILE: Lesson-16/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Genarate Password # Store Password in SSM Parameter Store # Get Password from SSM Parameter Store # Example of Use Password in RDS # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } // Generate Password resource "random_string" "rds_password" { length = 12 special = true override_special = "!#$&" keepers = { kepeer1 = var.name //keperr2 = var.something } } // Store Password in SSM Parameter Store resource "aws_ssm_parameter" "rds_password" { name = "/prod/mysql" description = "Master Password for RDS MySQL" type = "SecureString" value = random_string.rds_password.result } // Get Password from SSM Parameter Store data "aws_ssm_parameter" "my_rds_password" { name = "/prod/mysql" depends_on = [aws_ssm_parameter.rds_password] } // Example of Use Password in RDS resource "aws_db_instance" "default" { identifier = "prod-rds" allocated_storage = 20 storage_type = "gp2" engine = "mysql" engine_version = "5.7" instance_class = "db.t2.micro" name = "prod" username = "administrator" password = data.aws_ssm_parameter.my_rds_password.value parameter_group_name = "default.mysql5.7" skip_final_snapshot = true apply_immediately = true } ================================================ FILE: Lesson-16/outputs.tf ================================================ output "rds_password" { value = data.aws_ssm_parameter.my_rds_password.value } ================================================ FILE: Lesson-16/variables.tf ================================================ variable "name" { default = "petya" } ================================================ FILE: Lesson-17/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Terraform Conditions and Lookups # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "eu-central-1" } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id // Use of Condition resource "aws_instance" "my_webserver1" { ami = "ami-03a71cec707bfc3d7" //instance_type = (var.env == "prod" ? "t2.large" : "t2.micro") instance_type = var.env == "prod" ? var.ec2_size["prod"] : var.ec2_size["dev"] tags = { Name = "${var.env}-server" Owner = var.env == "prod" ? var.prod_onwer : var.noprod_owner } } // Use of LOOKUP resource "aws_instance" "my_webserver2" { ami = "ami-03a71cec707bfc3d7" instance_type = lookup(var.ec2_size, var.env) tags = { Name = "${var.env}-server" Owner = var.env == "prod" ? var.prod_onwer : var.noprod_owner } } // Create Bastion ONLY for if "dev" environment resource "aws_instance" "my_dev_bastion" { count = var.env == "dev" ? 1 : 0 ami = "ami-03a71cec707bfc3d7" instance_type = "t2.micro" tags = { Name = "Bastion Server for Dev-server" } } resource "aws_security_group" "my_webserver" { name = "Dynamic Security Group" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id dynamic "ingress" { for_each = lookup(var.allow_port_list, var.env) content { from_port = ingress.value to_port = ingress.value protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Dynamic SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-17/variables.tf ================================================ variable "env" { default = "dev" } variable "prod_onwer" { default = "Denis Astahov" } variable "noprod_owner" { default = "Dyadya Vasya" } variable "ec2_size" { default = { "prod" = "t3.medium" "dev" = "t3.micro" "staging" = "t2.small" } } variable "allow_port_list" { default = { "prod" = ["80", "443"] "dev" = ["80", "443", "8080", "22"] } } ================================================ FILE: Lesson-18/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Terraform Loops: Count and For if # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } resource "aws_iam_user" "user1" { name = "pushkin" } resource "aws_iam_user" "users" { count = length(var.aws_users) name = element(var.aws_users, count.index) } #---------------------------------------------------------------- resource "aws_instance" "servers" { count = 3 ami = "ami-07ab3281411d31d04" instance_type = "t3.micro" tags = { Name = "Server Number ${count.index + 1}" } } ================================================ FILE: Lesson-18/outputs.tf ================================================ // Print all details output "created_iam_users_all" { value = aws_iam_user.users } //Print only ID of users output "created_iam_users_ids" { value = aws_iam_user.users[*].id } //Print my Custom output list output "created_iam_users_custom" { value = [ for user in aws_iam_user.users : "Username: ${user.name} has ARN: ${user.arn}" ] } //Print My Custom output MAP output "created_iam_users_map" { value = { for user in aws_iam_user.users : user.unique_id => user.id // "AIDA4BML4STW22K74HQFF" : "vasya" } } // Print List of users with name 4 characters ONLY output "custom_if_length" { value = [ for x in aws_iam_user.users : x.name if length(x.name) == 4 ] } #=================================================================== // Print nice MAP of InstanceID: PublicIP output "server_all" { value = { for server in aws_instance.servers : server.id => server.public_ip // "i-0490f049844513179" = "99.79.58.22" } } ================================================ FILE: Lesson-18/variables.tf ================================================ variable "aws_users" { description = "List of IAM Users to create" default = ["vasya", "petya", "kolya", "lena", "masha", "misha", "vova", "donald"] } ================================================ FILE: Lesson-19/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Provision Resources in Multiply AWS Regions / Accounts # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { // This is example to use Another AWS Account alias = "ANOTHER_AWS_ACCOUNT" region = "ca-central-1" access_key = "xxxxxxxxxxxx" secret_key = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" assume_role { role_arn = "arn:aws:iam::1234567890:role/RemoteAdministrators" session_name = "TERRAFROM_SESSION" } } provider "aws" { region = "ca-central-1" } provider "aws" { region = "us-east-1" alias = "USA" } provider "aws" { region = "eu-central-1" alias = "GER" } #================================================================== data "aws_ami" "defaut_latest_ubuntu" { owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] } } data "aws_ami" "usa_latest_ubuntu" { provider = aws.USA owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] } } data "aws_ami" "ger_latest_ubuntu" { provider = aws.GER owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] } } #============================================================================ resource "aws_instance" "my_default_server" { instance_type = "t3.micro" ami = data.aws_ami.defaut_latest_ubuntu.id tags = { Name = "Default Server" } } resource "aws_instance" "my_usa_server" { provider = aws.USA instance_type = "t3.micro" ami = data.aws_ami.usa_latest_ubuntu.id tags = { Name = "USA Server" } } resource "aws_instance" "my_ger_server" { provider = aws.GER instance_type = "t3.micro" ami = data.aws_ami.ger_latest_ubuntu.id tags = { Name = "GERMANY Server" } } ================================================ FILE: Lesson-20/Layer1-Network/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Remote State on S3 # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "dev/network/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } #============================================================== data "aws_availability_zones" "available" {} resource "aws_vpc" "main" { cidr_block = var.vpc_cidr tags = { Name = "${var.env}-vpc" } } resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.env}-igw" } } resource "aws_subnet" "public_subnets" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = element(var.public_subnet_cidrs, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true tags = { Name = "${var.env}-puvlic-${count.index + 1}" } } resource "aws_route_table" "public_subnets" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "${var.env}-route-public-subnets" } } resource "aws_route_table_association" "public_routes" { count = length(aws_subnet.public_subnets[*].id) route_table_id = aws_route_table.public_subnets.id subnet_id = element(aws_subnet.public_subnets[*].id, count.index) } #============================================================== ================================================ FILE: Lesson-20/Layer1-Network/outputs.tf ================================================ output "vpc_id" { value = aws_vpc.main.id } output "vpc_cidr" { value = aws_vpc.main.cidr_block } output "public_subnet_ids" { value = aws_subnet.public_subnets[*].id } ================================================ FILE: Lesson-20/Layer1-Network/variables.tf ================================================ variable "vpc_cidr" { default = "10.0.0.0/16" } variable "env" { default = "dev" } variable "public_subnet_cidrs" { default = [ "10.0.1.0/24", "10.0.2.0/24", ] } ================================================ FILE: Lesson-20/Layer2-Servers/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Remote State on S3 # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "dev/servers/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } #==================================================================== data "terraform_remote_state" "network" { backend = "s3" config = { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket from where to GET Terraform State key = "dev/network/terraform.tfstate" // Object name in the bucket to GET Terraform state region = "us-east-1" // Region where bycket created } } data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } #=============================================================== resource "aws_instance" "web_server" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.webserver.id] subnet_id = data.terraform_remote_state.network.outputs.public_subnet_ids[0] user_data = <WebServer with IP: $myip
Build by Terraform with Remote State" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "${var.env}-WebServer" } } resource "aws_security_group" "webserver" { name = "WebServer Security Group" vpc_id = data.terraform_remote_state.network.outputs.vpc_id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = [data.terraform_remote_state.network.outputs.vpc_cidr] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.env}-web-server-sg" Owner = "Denis Astahov" } } #================================================================= ================================================ FILE: Lesson-20/Layer2-Servers/outputs.tf ================================================ output "webserver_sg_id" { value = aws_security_group.webserver.id } output "web_server_public_ip" { value = aws_instance.web_server.public_ip } ================================================ FILE: Lesson-20/Layer2-Servers/variables.tf ================================================ variable "env" { default = "dev" } ================================================ FILE: Lesson-21/modules/aws_network/main.tf ================================================ #---------------------------------------------------------- # My Terraform # Provision: # - VPC # - Internet Gateway # - XX Public Subnets # - XX Private Subnets # - XX NAT Gateways in Public Subnets to give access to Internet from Private Subnets # # Made by Denis Astahov. Summer 2019 #---------------------------------------------------------- #============================================================== data "aws_availability_zones" "available" {} resource "aws_vpc" "main" { cidr_block = var.vpc_cidr tags = { Name = "${var.env}-vpc" } } resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.env}-igw" } } #-------------Public Subnets and Routing---------------------------------------- resource "aws_subnet" "public_subnets" { count = length(var.public_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = element(var.public_subnet_cidrs, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true tags = { Name = "${var.env}-public-${count.index + 1}" } } resource "aws_route_table" "public_subnets" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "${var.env}-route-public-subnets" } } resource "aws_route_table_association" "public_routes" { count = length(aws_subnet.public_subnets[*].id) route_table_id = aws_route_table.public_subnets.id subnet_id = element(aws_subnet.public_subnets[*].id, count.index) } #-----NAT Gateways with Elastic IPs-------------------------- resource "aws_eip" "nat" { count = length(var.private_subnet_cidrs) domain = "vpc" tags = { Name = "${var.env}-nat-gw-${count.index + 1}" } } resource "aws_nat_gateway" "nat" { count = length(var.private_subnet_cidrs) allocation_id = aws_eip.nat[count.index].id subnet_id = element(aws_subnet.public_subnets[*].id, count.index) tags = { Name = "${var.env}-nat-gw-${count.index + 1}" } } #--------------Private Subnets and Routing------------------------- resource "aws_subnet" "private_subnets" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = element(var.private_subnet_cidrs, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] tags = { Name = "${var.env}-private-${count.index + 1}" } } resource "aws_route_table" "private_subnets" { count = length(var.private_subnet_cidrs) vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_nat_gateway.nat[count.index].id } tags = { Name = "${var.env}-route-private-subnet-${count.index + 1}" } } resource "aws_route_table_association" "private_routes" { count = length(aws_subnet.private_subnets[*].id) route_table_id = aws_route_table.private_subnets[count.index].id subnet_id = element(aws_subnet.private_subnets[*].id, count.index) } #============================================================== ================================================ FILE: Lesson-21/modules/aws_network/outputs.tf ================================================ output "vpc_id" { value = aws_vpc.main.id } output "vpc_cidr" { value = aws_vpc.main.cidr_block } output "public_subnet_ids" { value = aws_subnet.public_subnets[*].id } output "private_subnet_ids" { value = aws_subnet.private_subnets[*].id } ================================================ FILE: Lesson-21/modules/aws_network/variables.tf ================================================ variable "vpc_cidr" { default = "10.0.0.0/16" } variable "env" { default = "dev" } variable "public_subnet_cidrs" { default = [ "10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24" ] } variable "private_subnet_cidrs" { default = [ "10.0.11.0/24", "10.0.22.0/24", "10.0.33.0/24" ] } ================================================ FILE: Lesson-21/modules/aws_security_group/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-21/modules/aws_something/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-21/projectA/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Use Our Terraform Module to create AWS VPC Networks # # Made by Denis Astahov. Summer 2019 #---------------------------------------------------------- provider "aws" { region = var.region } module "vpc-default" { source = "../modules/aws_network" // source = "git@github.com:adv4000/terraform-modules.git//aws_network" } module "vpc-dev" { source = "../modules/aws_network" // source = "git@github.com:adv4000/terraform-modules.git//aws_network" env = "dev" vpc_cidr = "10.100.0.0/16" public_subnet_cidrs = ["10.100.1.0/24", "10.100.2.0/24"] private_subnet_cidrs = [] } module "vpc-prod" { source = "../modules/aws_network" // source = "git@github.com:adv4000/terraform-modules.git//aws_network" env = "prod" vpc_cidr = "10.10.0.0/16" public_subnet_cidrs = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"] private_subnet_cidrs = ["10.10.11.0/24", "10.10.22.0/24", "10.10.33.0/24"] } module "vpc-test" { source = "../modules/aws_network" // source = "git@github.com:adv4000/terraform-modules.git//aws_network" env = "staging" vpc_cidr = "10.10.0.0/16" public_subnet_cidrs = ["10.10.1.0/24", "10.10.2.0/24"] private_subnet_cidrs = ["10.10.11.0/24", "10.10.22.0/24"] } #=============================================== ================================================ FILE: Lesson-21/projectA/outputs.tf ================================================ output "prod_public_subnet_ids" { value = module.vpc-prod.public_subnet_ids } output "prod_private_subnet_ids" { value = module.vpc-prod.private_subnet_ids } output "dev_public_subnet_ids" { value = module.vpc-dev.public_subnet_ids } output "dev_private_subnet_ids" { value = module.vpc-dev.private_subnet_ids } ================================================ FILE: Lesson-21/projectA/variables.tf ================================================ variable "region" { description = "AWS Region where to provision VPC Network" default = "eu-north-1" } ================================================ FILE: Lesson-22/ProjectXYZ/dev/kms/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/network/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/route53/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/s3/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/vpc/applications/app1/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "dev/vpc/applications/app1/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/dev/vpc/applications/app2/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "dev/vpc/applications/app2/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/dev/vpc/databases/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/vpc/ecs_cluster/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/dev/vpc/vpn/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/kms/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/network/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/route53/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/s3/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/vpc/applications/app1/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "prod/vpc/applications/app1/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/prod/vpc/applications/app2/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "prod/vpc/applications/app2/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/prod/vpc/databases/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/vpc/ecs_cluster/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/prod/vpc/vpn/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/kms/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/network/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/route53/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/s3/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/vpc/applications/app1/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "staging/vpc/applications/app1/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/staging/vpc/applications/app2/main.tf ================================================ Future Terraform Code :) Do it yourself! terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State key = "staging/vpc/applications/app2/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-east-1" // Region where bycket created } } ================================================ FILE: Lesson-22/ProjectXYZ/staging/vpc/databases/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/vpc/ecs_cluster/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/ProjectXYZ/staging/vpc/vpn/main.tf ================================================ Future Terraform Code :) Do it yourself! ================================================ FILE: Lesson-22/README.MD ================================================ # Terraform Folder Hierarchy for Multi Environment example Terraform Modules better to keep in GitHub or BitBucket, otherwise in separate folder. ``` . ├── modules │   ├── aws_network │   ├── aws_security_group │   └── aws_something └── ProjectXYZ ├── dev │   ├── kms │   ├── network │   ├── route53 │   ├── s3 │   └── vpc │   ├── applications │   │   ├── app1 │   │   └── app2 │   ├── databases │   ├── ecs_cluster │   └── vpn ├── prod │   ├── kms │   ├── network │   ├── route53 │   ├── s3 │   └── vpc │   ├── applications │   │   ├── app1 │   │   └── app2 │   ├── databases │   ├── ecs_cluster │   └── vpn └── staging ├── kms ├── network ├── route53 ├── s3 └── vpc ├── applications │   ├── app1 │   └── app2 ├── databases ├── ecs_cluster └── vpn ``` # ---------------------------- ================================================ FILE: Lesson-22/modules/aws_network/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-22/modules/aws_security_group/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-22/modules/aws_something/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-23/globalvars/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Global Variables in Remote State on S3 # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } terraform { backend "s3" { bucket = "denis-astahov-project-kgb-terraform-state" key = "globalvars/terraform.tfstate" region = "us-east-1" } } #================================================== output "company_name" { value = "ANDESA Soft International" } output "owner" { value = "Denis Astahov" } output "tags" { value = { Project = "Assembly-2020" CostCenter = "R&D" Country = "Canada" } } ================================================ FILE: Lesson-23/stack1/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Use Global Variables from Remote State # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } data "terraform_remote_state" "global" { backend = "s3" config = { bucket = "denis-astahov-project-kgb-terraform-state" key = "globalvars/terraform.tfstate" region = "us-east-1" } } locals { company_name = data.terraform_remote_state.global.outputs.company_name owner = data.terraform_remote_state.global.outputs.owner common_tags = data.terraform_remote_state.global.outputs.tags } #--------------------------------------------------------------------- resource "aws_vpc" "vpc1" { cidr_block = "10.0.0.0/16" tags = { Name = "Stack1-VPC1" Company = local.company_name Owner = local.owner } } resource "aws_vpc" "vpc2" { cidr_block = "10.0.0.0/16" tags = merge(local.common_tags, { Name = "Stack1-VPC2" }) } ================================================ FILE: Lesson-23/stack2/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Use Global Variables from Remote State # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-central-1" } data "terraform_remote_state" "global" { backend = "s3" config = { bucket = "denis-astahov-project-kgb-terraform-state" key = "globalvars/terraform.tfstate" region = "us-east-1" } } locals { company_name = data.terraform_remote_state.global.outputs.company_name owner = data.terraform_remote_state.global.outputs.owner common_tags = data.terraform_remote_state.global.outputs.tags } #--------------------------------------------------------------------- resource "aws_vpc" "vpc1" { cidr_block = "10.0.0.0/16" tags = { Name = "Stack2-VPC1" Company = local.company_name Owner = local.owner } } resource "aws_vpc" "vpc2" { cidr_block = "10.0.0.0/16" tags = merge(local.common_tags, { Name = "Stack2-VPC2" }) } ================================================ FILE: Lesson-24/main.tf ================================================ #---------------------------------------------------------- # My Terraform # # Use Terraform with GCP - Google Cloud Platform # # Made by Denis Astahov # #----------------------------------------------------------- //export GOOGLE_CLOUD_KEYFILE_JSON="gcp-creds.json" provider "google" { credentials = file("mygcp-creds.json") project = "my-gcp-project-238521" region = "us-west1" zone = "us-west1-c" } resource "google_compute_instance" "my_server" { name = "my-gcp-server" machine_type = "f1-micro" boot_disk { initialize_params { image = "debian-cloud/debian-9" } } network_interface { network = "default" } } ================================================ FILE: Lesson-24/mygcp-creds.json ================================================ // Fake Credentials file, but should look like this { "type": "service_account", "project_id": "my-gcp-project-xyzxyz", "private_key_id": "d6fasdasfasfasf935f7", "private_key": "-----BEGIN PRIVATE KEY-----\nA0xFAafq5visBkpMBDscO5YIQ+w=\n-----END PRIVATE KEY-----\n", "client_email": "tf-22-677@my-gcp-project-xyzxyz.iam.gserviceaccount.com", "client_id": "34623523523523523", "auth_uri": "https://accounts.astahov.com/o/oauth2/auth", "token_uri": "https://oauth2.astahov.com/token", "auth_provider_x509_cert_url": "https://www.astahov.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.astahov.com/robot/v1/metadata/x509/tf-22-677%40my-gcp-project-xyzxyz.iam.gserviceaccount.com" } ================================================ FILE: Lesson-25/README.MD ================================================ ## Officail Terraform website https://www.terraform.io/ ## A Comprehensive Guide to Terraform - blog https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b3d32832baca ## Terraform: Up & Running: Writing Infrastructure as Code - book https://www.amazon.ca/Terraform-Running-Writing-Infrastructure-Code/dp/1492046906/ ## Collection of Terraform AWS modules supported by the community https://github.com/terraform-aws-modules ## Source Code for All Terraform Lessons https://github.com/adv4000/terraform-lessons ================================================ FILE: Lesson-26/import-begin.tf ================================================ # terraform import aws_instance.node1 i-0417da3dfcfd6e059 # terraform import aws_instance.node2 i-0b92baf1fa014b3e2 # terraform import aws_instance.node3 i-0ca6e4b3d52437673 # terraform import aws_security_group.nomad sg-0bb76870a0cbc887a resource "aws_instance" "node1" { } resource "aws_instance" "node2" { } resource "aws_instance" "node3" { } resource "aws_security_group" "nomad" { } ================================================ FILE: Lesson-26/import-finish.tf ================================================ resource "aws_instance" "node1" { ami = "ami-0a634ae95e11c6f91" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.nomad.id] ebs_optimized = true tags = { Name = "Nomad Ubuntu Node-1" Owner = "Denis Astahov" } } resource "aws_instance" "node2" { ami = "ami-0a634ae95e11c6f91" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.nomad.id] ebs_optimized = true tags = { Name = "Nomad Ubuntu Node-2" Owner = "Denis Astahov" } } resource "aws_instance" "node3" { ami = "ami-0a634ae95e11c6f91" instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.nomad.id] ebs_optimized = true tags = { Name = "Nomad Ubuntu Node-3" Owner = "Denis Astahov" } } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "nomad" { description = "Nomad" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 0 to_port = 65535 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Nomad Cluster" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-27/main.tf ================================================ # Up to Terraform v0.15.1 # terraform taint aws_instance.node2 # provider "aws" { region = "us-west-1" } resource "aws_instance" "node1" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-1" Owner = "Denis Astahov" } } resource "aws_instance" "node2" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-2" Owner = "Denis Astahov" } } resource "aws_instance" "node3" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-3" Owner = "Denis Astahov" } depends_on = [aws_instance.node2] } ================================================ FILE: Lesson-27-v0.15.2+/main.tf ================================================ # Since Terraform v0.15.2 # terraform apply -replace aws_instance.node2 # provider "aws" { region = "us-west-1" } resource "aws_instance" "node1" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-1" Owner = "Denis Astahov" } } resource "aws_instance" "node2" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-2" Owner = "Denis Astahov" } } resource "aws_instance" "node3" { ami = "ami-05655c267c89566dd" instance_type = "t3.micro" tags = { Name = "Node-3" Owner = "Denis Astahov" } depends_on = [aws_instance.node2] } ================================================ FILE: Lesson-28/new-prod/config.tf ================================================ provider "aws" { region = "us-west-2" // Region where to Create Resources } terraform { backend "s3" { bucket = "adv-it-terraform-state" // Bucket where to SAVE Terraform State key = "new-prod/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-west-2" // Region where bucket is created } } ================================================ FILE: Lesson-28/new-prod/ip-prod.tf ================================================ resource "aws_eip" "prod-ip1" { domain = "vpc" } # Need to add in new AWS Provider version resource "aws_eip" "prod-ip2" { domain = "vpc" } # Need to add in new AWS Provider version ================================================ FILE: Lesson-28/new-prod/main.tf ================================================ data "aws_availability_zones" "available" {} data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } ================================================ FILE: Lesson-28/new-prod/web-prod.tf ================================================ resource "aws_instance" "web-prod" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web-prod.id] user_data = <PROD WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "PROD WebServer" Owner = "Denis Astahov" } } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "web-prod" { name = "WebServer SG Prod" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-28/new-staging/config.tf ================================================ provider "aws" { region = "us-west-2" // Region where to Create Resources } terraform { backend "s3" { bucket = "adv-it-terraform-state" // Bucket where to SAVE Terraform State key = "new-staging/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-west-2" // Region where bucket is created } } ================================================ FILE: Lesson-28/new-staging/ip-stag.tf ================================================ resource "aws_eip" "stag-ip1" { vpc = true } # Need to add in new AWS Provider version resource "aws_eip" "stag-ip2" { vpc = true } # Need to add in new AWS Provider version ================================================ FILE: Lesson-28/new-staging/main.tf ================================================ data "aws_availability_zones" "available" {} data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } ================================================ FILE: Lesson-28/new-staging/web-stag.tf ================================================ resource "aws_instance" "web-stag" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web-stag.id] user_data = <STAG WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "STAG WebServer" Owner = "Denis Astahov" } } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "web-stag" { name = "WebServer SG Stag" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-28/old-all/config.tf ================================================ provider "aws" { region = "us-west-2" // Region where to Create Resources } terraform { backend "s3" { bucket = "adv-it-terraform-state" // Bucket where to SAVE Terraform State key = "old-all/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-west-2" // Region where bucket is created } } ================================================ FILE: Lesson-28/old-all/ip-prod.tf ================================================ resource "aws_eip" "prod-ip1" { domain = "vpc" } # Need to add in new AWS Provider version resource "aws_eip" "prod-ip2" { domain = "vpc" } # Need to add in new AWS Provider version ================================================ FILE: Lesson-28/old-all/ip-stag.tf ================================================ resource "aws_eip" "stag-ip1" { domain = "vpc" } # Need to add in new AWS Provider version resource "aws_eip" "stag-ip2" { domain = "vpc" } # Need to add in new AWS Provider version ================================================ FILE: Lesson-28/old-all/main.tf ================================================ data "aws_availability_zones" "available" {} data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } resource "aws_eip" "myip-prod" {} resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id ================================================ FILE: Lesson-28/old-all/web-prod.tf ================================================ resource "aws_instance" "web-prod" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web-prod.id] user_data = <PROD WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "PROD WebServer" Owner = "Denis Astahov" } } resource "aws_security_group" "web-prod" { name = "WebServer SG Prod" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-28/old-all/web-stag.tf ================================================ resource "aws_instance" "web-stag" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web-stag.id] user_data = <STAG WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "STAG WebServer" Owner = "Denis Astahov" } } resource "aws_security_group" "web-stag" { name = "WebServer SG Stag" description = "My First SecurityGroup" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-29/config.tf ================================================ provider "aws" { region = "us-west-2" // Region where to Create Resources } terraform { backend "s3" { bucket = "adv-it-terraform-state" // Bucket where to SAVE Terraform State key = "prod/terraform.tfstate" // Object name in the bucket to SAVE Terraform State region = "us-west-2" // Region where bucket is created } } ================================================ FILE: Lesson-29/main.tf ================================================ data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } resource "aws_instance" "web" { ami = data.aws_ami.latest_amazon_linux.id instance_type = "t3.micro" vpc_security_group_ids = [aws_security_group.web.id] user_data = <PROD WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "PROD WebServer - ${terraform.workspace}" Owner = "Denis Astahov" } } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "web" { name_prefix = "WebServer SG Prod" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "Web Server SecurityGroup - ${terraform.workspace}" Owner = "Denis Astahov" } } resource "aws_eip" "web" { vpc = true # Need to add in new AWS Provider version instance = aws_instance.web.id tags = { Name = "PROD WebServer IP - ${terraform.workspace}" Owner = "Denis Astahov" } } #################################### output "web_public_ip" { value = aws_eip.web.public_ip } ================================================ FILE: Lesson-30/main.tf ================================================ data "aws_ami" "latest_amazon_linux" { owners = ["amazon"] most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } } resource "aws_instance" "web" { ami = data.aws_ami.latest_amazon_linux.id instance_type = var.server_size vpc_security_group_ids = [aws_security_group.web.id] user_data = <${var.server_name}-WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html sudo service httpd start chkconfig httpd on EOF tags = { Name = "${var.server_name}-WebServer" Owner = "Denis Astahov" } } resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id resource "aws_security_group" "web" { name_prefix = "${var.server_name}-WebServer-SG" vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "${var.server_name}-WebServer SecurityGroup" Owner = "Denis Astahov" } } resource "aws_eip" "web" { domain = "vpc" # Need to add in new AWS Provider version instance = aws_instance.web.id tags = { Name = "${var.server_name}-WebServer-IP" Owner = "Denis Astahov" } } ================================================ FILE: Lesson-30/outputs.tf ================================================ output "web_public_ip" { value = aws_eip.web.public_ip } ================================================ FILE: Lesson-30/variables.tf ================================================ variable "server_name" { description = "Name for WebServer" type = string default = "demo" } variable "server_size" { description = "Server Size for WebServer" type = string default = "t3.micro" } ================================================ FILE: Lesson-31/main.tf ================================================ provider "aws" { region = var.region } module "vpc-dev" { source = "./modules/aws_network" env = "dev" vpc_cidr = var.vpc_settings["dev"] } module "vpc-staging" { source = "./modules/aws_network" env = "stag" vpc_cidr = var.vpc_settings["stag"] } module "vpc-prod" { source = "./modules/aws_network" env = "prod" vpc_cidr = var.vpc_settings["prod"] depends_on = [module.vpc-dev, module.vpc-staging] # <--Supported only in Terraform 0.13+ } module "vpc" { count = 2 # <--Supported only in Terraform 0.13+ source = "./modules/aws_network" env = "demo-${count.index + 1}" } module "vpc_list" { for_each = var.vpc_settings # <--Supported only in Terraform 0.13+ source = "./modules/aws_network" env = each.key vpc_cidr = each.value } ================================================ FILE: Lesson-31/modules/aws_network/main.tf ================================================ #---------------------------------------------------------- # My Terraform # Provision: # - VPC # - Internet Gateway # Made by Denis Astahov. Summer 2020 #---------------------------------------------------------- #============================================================== data "aws_availability_zones" "available" {} resource "aws_vpc" "main" { cidr_block = var.vpc_cidr tags = { Name = "${var.env}-vpc" } } resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.env}-igw" } } ================================================ FILE: Lesson-31/modules/aws_network/outputs.tf ================================================ output "vpc_id" { value = aws_vpc.main.id } output "vpc_cidr" { value = aws_vpc.main.cidr_block } ================================================ FILE: Lesson-31/modules/aws_network/variables.tf ================================================ variable "vpc_cidr" { default = "10.0.0.0/16" } variable "env" { default = "demo" } ================================================ FILE: Lesson-31/modules/aws_security_group/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-31/modules/aws_something/main.tf ================================================ Future Terraform Module :) Do it yourself! ================================================ FILE: Lesson-31/variables.tf ================================================ variable "vpc_settings" { default = { prod = "10.10.0.0/16", stag = "10.20.0.0/16" dev = "10.30.0.0/16" } } variable "region" { type = string default = "eu-west-1" validation { condition = substr(var.region, 0, 3) == "eu-" error_message = "Must be an EUROPE AWS Region, like \"eu-\"." } } ================================================ FILE: Lesson-32/main.tf ================================================ provider "aws" { // My Root Account region = "us-west-2" } provider "aws" { // My DEV Account region = "us-west-1" alias = "dev" assume_role { role_arn = "arn:aws:iam::639130796919:role/TerraformRole" } } provider "aws" { // My PROD Account region = "ca-central-1" alias = "prod" assume_role { role_arn = "arn:aws:iam::032823347814:role/TerraformRole" } } #-------------------------------------------------------------- module "servers" { source = "./module_servers" instance_type = "t3.small" providers = { aws.root = aws aws.prod = aws.prod aws.dev = aws.dev } } ================================================ FILE: Lesson-32/module_servers/main.tf ================================================ terraform { required_providers { aws = { source = "hashicorp/aws" configuration_aliases = [ aws.root, aws.prod, aws.dev ] } } } #---------------------------------------------- data "aws_ami" "latest_ubuntu20_root" { provider = aws.root owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } } data "aws_ami" "latest_ubuntu20_prod" { provider = aws.prod owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } } data "aws_ami" "latest_ubuntu20_dev" { provider = aws.dev owners = ["099720109477"] most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } } #------------------------------------------------------------------- resource "aws_instance" "server_root" { provider = aws.root ami = data.aws_ami.latest_ubuntu20_root.id instance_type = var.instance_type tags = { Name = "Server-ROOT" } } resource "aws_instance" "server_prod" { provider = aws.prod ami = data.aws_ami.latest_ubuntu20_prod.id instance_type = var.instance_type tags = { Name = "Server-PROD" } } resource "aws_instance" "server_dev" { provider = aws.dev ami = data.aws_ami.latest_ubuntu20_dev.id instance_type = var.instance_type tags = { Name = "Server-DEV" } } ================================================ FILE: Lesson-32/module_servers/variables.tf ================================================ variable "instance_type" { default = "t3.micro" } ================================================ FILE: Lesson-33/iam_groups.tf ================================================ #---------------------------------------------------------- # Terraform - From Zero to Certified Professional # # Create IAM Groups from the map # # Made by Denis Astahov #---------------------------------------------------------- locals { group_map_with_key = { for item in var.iam_group_map : item.group_name => item } } #=============================================================================== output "iam_group_map_with_key" { value = local.group_map_with_key } #=============================================================================== resource "aws_iam_group" "this" { for_each = local.group_map_with_key name = each.key } #=============================================================================== ================================================ FILE: Lesson-33/iam_groups_policies.tf ================================================ #---------------------------------------------------------- # Terraform - From Zero to Certified Professional # # Create IAM Group Policies from the map # # Made by Denis Astahov #---------------------------------------------------------- locals { group_policy_map_setproduct = [ for item in var.iam_group_map : setproduct([item.group_name], item.group_policies) ] group_policy_map_setproduct_pairs = [ for item in var.iam_group_map : [ for pair in setproduct([item.group_name], item.group_policies) : { group_name = pair[0] group_policy = pair[1] } ] ] group_policy_map_setproduct_pairs_flatten = flatten(local.group_policy_map_setproduct_pairs) group_policy_map_setproduct_pairs_flatten_with_key = { for item in local.group_policy_map_setproduct_pairs_flatten : "${item.group_name}__${item.group_policy}" => item } group_map_converted = { for flatitem in flatten([ for item in var.iam_group_map : [ for pair in setproduct([item.group_name], item.group_policies) : { group_name = pair[0] group_policy = pair[1] } ] ]) : "${flatitem.group_name}__${flatitem.group_policy}" => flatitem } } #=============================================================================== output "map_setproduct" { value = local.group_policy_map_setproduct } output "map_setproduct_pairs" { value = local.group_policy_map_setproduct_pairs } output "map_setproduct_pairs_flatten" { value = local.group_policy_map_setproduct_pairs_flatten } output "map_setproduct_pairs_flatten_with_key" { value = local.group_policy_map_setproduct_pairs_flatten_with_key } output "map_xconverted" { value = local.group_map_converted } #=============================================================================== resource "aws_iam_group_policy_attachment" "this" { for_each = local.group_map_converted group = each.value.group_name policy_arn = each.value.group_policy depends_on = [aws_iam_group.this] } #=============================================================================== ================================================ FILE: Lesson-33/variables.tf ================================================ variable "iam_group_map" { default = [ { group_name = "Developers" group_policies = [ "arn:aws:iam::aws:policy/AWSProtonDeveloperAccess", "arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess" ] }, { group_name = "SysOps" group_policies = [ "arn:aws:iam::aws:policy/job-function/SystemAdministrator", "arn:aws:iam::aws:policy/job-function/NetworkAdministrator", "arn:aws:iam::aws:policy/AWSSecurityHubReadOnlyAccess" ] }, { group_name = "Administrators" group_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"] }, { group_name = "SecurityAuditors" group_policies = [ "arn:aws:iam::aws:policy/SecurityAudit", "arn:aws:iam::aws:policy/AWSSecurityHubReadOnlyAccess" ] } ] } ================================================ FILE: Lesson-34/main.tf ================================================ #---------------------------------------------------------- # Build EC2 Instace using AWS Provider VS AWSCC Provider # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "us-west-2" } provider "awscc" { region = "us-west-2" } variable "tags" { description = "Tags to apply" type = map(any) default = { Owner = "Denis Astahov" Project = "Phoenix" } } # Reformat Tags from MAP(ANY) to List of MAPS locals { awscc_reformat_tags = [ for tagKey, tagValue in var.tags : { key = tagKey value = tagValue } ] } # Create EC2 Instance using AWS Provider resource "aws_instance" "my_ubuntu" { ami = "ami-06e54d05255faf8f6" instance_type = "t3.micro" tags = merge( { Name = "Server-created-by-AWS-Provider" }, var.tags) } # Create EC2 Instance using AWSCC Provider resource "awscc_ec2_instance" "my_ubuntu" { image_id = "ami-06e54d05255faf8f6" instance_type = "t3.micro" tags = concat( [ { key = "Name", value = "Server-created-by-AWSCC-Provider" } ], local.awscc_reformat_tags) } ================================================ FILE: Lesson-35/deployments/dev/config.tf ================================================ terraform { backend "s3" { bucket = "astahov-terraform-remote-state" # Bucket where to SAVE Terraform State key = "dev/terraform.tfstate" # Object name in the bucket to SAVE Terraform State region = "ca-west-1" # Region where bucket created use_lockfile = true } } provider "aws" { region = "ca-west-1" # Region where to create resources default_tags { tags = { Owner = "Denis Astahov" Project = "Terraform From Zero to Professional" } } } ================================================ FILE: Lesson-35/deployments/dev/main.tf ================================================ module "vpc" { source = "../../module-aws-vpc" environment = "dev" vpc_cidr = "10.10.0.0/16" subnet_cidrs = [ "10.10.1.0/24", "10.10.2.0/24" ] } module "database" { source = "../../module-aws-rds" environment = "dev" name = "astahov-db" engine = "mysql" engine_version = "8.4" db_cluster_instance_class = "db.t3.micro" db_name = "mydatabase" username = "dbadmin" multi_az = false allocated_storage = 20 port = 1433 vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.subnet_ids cidr_blocks = [module.vpc.vpc_cidr] tags = { ProjectCode = "5674848" } } ================================================ FILE: Lesson-35/deployments/prod/config.tf ================================================ terraform { backend "s3" { bucket = "astahov-terraform-remote-state" # Bucket where to SAVE Terraform State key = "prod/terraform.tfstate" # Object name in the bucket to SAVE Terraform State region = "ca-west-1" # Region where bucket created use_lockfile = true } } provider "aws" { region = "ca-west-1" # Region where to create resources default_tags { tags = { Owner = "Denis Astahov" Project = "Terraform From Zero to Professional" } } } ================================================ FILE: Lesson-35/deployments/prod/main.tf ================================================ module "vpc" { source = "../../module-aws-vpc" environment = "prod" vpc_cidr = "10.20.0.0/16" subnet_cidrs = [ "10.20.1.0/24", "10.20.2.0/24" ] } module "database" { source = "../../module-aws-rds" environment = "prod" name = "astahov-db" engine = "mysql" engine_version = "8.4" db_cluster_instance_class = "db.t3.small" db_name = "mydatabase" username = "dbadmin" multi_az = true allocated_storage = 20 port = 1433 vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.subnet_ids cidr_blocks = [module.vpc.vpc_cidr] } ================================================ FILE: Lesson-35/module-aws-rds/main.tf ================================================ resource "aws_db_instance" "this" { identifier = "${var.environment}-${var.name}" allocated_storage = var.allocated_storage max_allocated_storage = var.max_allocated_storage engine = var.engine engine_version = var.engine_version instance_class = var.db_cluster_instance_class storage_type = var.storage_type username = var.username password = random_password.rds_password.result skip_final_snapshot = true copy_tags_to_snapshot = true vpc_security_group_ids = [aws_security_group.rds_sg.id] db_subnet_group_name = aws_db_subnet_group.rds_subnet_group.name port = var.port backup_retention_period = var.backup_retention_period storage_encrypted = var.storage_encrypted multi_az = var.multi_az db_name = var.db_name tags = var.tags } resource "random_password" "rds_password" { length = var.password_length special = false upper = true lower = true numeric = true } resource "aws_security_group" "rds_sg" { name = "${var.environment}-${var.name}-rds-sg" vpc_id = var.vpc_id description = "Security group for RDS instance" ingress { from_port = var.port to_port = var.port protocol = "tcp" cidr_blocks = var.cidr_blocks } tags = merge(var.tags, { "Name" = "${var.environment}-${var.name}-rds-sg" }) lifecycle { create_before_destroy = true } } resource "aws_db_subnet_group" "rds_subnet_group" { name = "${var.environment}-${var.name}-subnet-group" subnet_ids = var.subnet_ids tags = var.tags lifecycle { create_before_destroy = true } } resource "aws_ssm_parameter" "rds_instance_host" { name = "/${var.environment}/rds/${var.name}/db_host" type = "String" value = aws_db_instance.this.address tags = var.tags } resource "aws_ssm_parameter" "rds_instance_port" { name = "/${var.environment}/rds/${var.name}/db_port" type = "String" value = aws_db_instance.this.port tags = var.tags } resource "aws_ssm_parameter" "rds_instance_username" { name = "/${var.environment}/rds/${var.name}/db_username" type = "String" value = aws_db_instance.this.username tags = var.tags } resource "aws_ssm_parameter" "rds_instance_password" { name = "/${var.environment}/rds/${var.name}/db_password" type = "SecureString" value = random_password.rds_password.result tags = var.tags } ================================================ FILE: Lesson-35/module-aws-rds/outputs.tf ================================================ output "rds_instance_endpoint" { value = aws_db_instance.this.endpoint } output "rds_instance_port" { value = aws_db_instance.this.port } output "rds_instance_username" { value = aws_db_instance.this.username } output "rds_instance_password_ssm_arn" { value = aws_ssm_parameter.rds_instance_password.arn } output "rds_instance_identifier" { value = aws_db_instance.this.identifier } ================================================ FILE: Lesson-35/module-aws-rds/variables.tf ================================================ variable "name" { description = "A unique identifier for the RDS instance" type = string } variable "engine" { description = "The name of the database engine to be used for this DB instance" } variable "engine_version" { description = "The version number of the database engine to use" } variable "username" { description = "Master username for the database" } variable "port" { description = "The port on which the DB accepts connections" } variable "backup_retention_period" { description = "The number of days during which automatic DB snapshots are retained" default = 0 } variable "storage_encrypted" { description = "Specifies whether the DB instance is encrypted" default = true } variable "multi_az" { description = "Is the RDS MultiAZ or SingleAZ. False for Single AZ and True for MultiAZ" default = false } variable "password_length" { description = "Length of the randomly generated password" default = 16 } variable "tags" { type = map(any) default = {} } variable "environment" { description = "The name of the environment" type = string } variable "db_cluster_instance_class" { description = "The instance type of the RDS instance" type = string } variable "storage_type" { description = "One of 'standard' (magnetic), 'gp3' (general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'standard' if not. Note that this behavior is different from the AWS web console, where the default is 'gp2'." type = string default = "gp3" } variable "vpc_id" { description = "The ID of the VPC where the RDS Single-AZ/MultiAZ instance will be created" } variable "subnet_ids" { description = "The IDs of the subnets for the RDS Single-AZ/MultiAZ instance" type = list(string) } variable "allocated_storage" { description = "Size of the storage" default = 20 } variable "max_allocated_storage" { description = "Enable AutoScaling up to" default = null } variable "cidr_blocks" { description = "ingress CIDR " default = ["0.0.0.0/0"] type = list(string) } variable "db_name" { description = "value of the initial database name" type = string default = "" } ================================================ FILE: Lesson-35/module-aws-vpc/main.tf ================================================ data "aws_availability_zones" "available" {} resource "aws_vpc" "main" { cidr_block = var.vpc_cidr tags = { Name = "${var.environment}-vpc" } } resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "${var.environment}-igw" } } resource "aws_subnet" "public_subnets" { count = length(var.subnet_cidrs) vpc_id = aws_vpc.main.id cidr_block = element(var.subnet_cidrs, count.index) availability_zone = data.aws_availability_zones.available.names[count.index] map_public_ip_on_launch = true tags = { Name = "${var.environment}-public-${count.index + 1}" } } resource "aws_route_table" "public_subnets" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "${var.environment}-route-public-subnets" } } resource "aws_route_table_association" "public_routes" { count = length(aws_subnet.public_subnets[*].id) route_table_id = aws_route_table.public_subnets.id subnet_id = element(aws_subnet.public_subnets[*].id, count.index) } ================================================ FILE: Lesson-35/module-aws-vpc/outputs.tf ================================================ output "vpc_id" { value = aws_vpc.main.id } output "vpc_cidr" { value = aws_vpc.main.cidr_block } output "igw_id" { value = aws_internet_gateway.main.id } output "subnet_ids" { value = aws_subnet.public_subnets[*].id } ================================================ FILE: Lesson-35/module-aws-vpc/variables.tf ================================================ variable "tags" { type = map(any) default = {} } variable "environment" { description = "The name of the environment" type = string } variable "vpc_cidr" { default = "10.0.0.0/16" } variable "subnet_cidrs" { default = [ "10.0.1.0/24", "10.0.2.0/24" ] } ================================================ FILE: Lesson-36/ephemeral/main.tf ================================================ #---------------------------------------------------------- # Terraform - From Zero to Certified Professional # # New way of Secrets management using Ephemeral block # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-west-1" } ephemeral "random_password" "masterdb" { #---> Generate Password length = 16 special = true override_special = "!$%#" } resource "aws_ssm_parameter" "masterdb_password" { #---> Store Password name = "/prod/masterdb/password" type = "SecureString" value_wo = ephemeral.random_password.masterdb.result value_wo_version = 1 } ephemeral "aws_ssm_parameter" "masterdb_password" { #---> Get Password arn = aws_ssm_parameter.masterdb_password.arn } resource "aws_db_instance" "masterdb" { #---> Use Password identifier = "prod-master-db" db_name = "master" allocated_storage = 20 instance_class = "db.t3.micro" engine = "mysql" engine_version = "8.0" username = "admin" skip_final_snapshot = true password_wo = ephemeral.aws_ssm_parameter.masterdb_password.value password_wo_version = 1 } ================================================ FILE: Lesson-36/non-ephemeral/main.tf ================================================ #---------------------------------------------------------- # Terraform - From Zero to Certified Professional # # Old way of Secrets management NOT using Ephemeral block # # Made by Denis Astahov #---------------------------------------------------------- provider "aws" { region = "ca-west-1" } resource "random_password" "masterdb" { #---> Generate Password length = 16 special = true override_special = "!$%#" } resource "aws_ssm_parameter" "masterdb_password" { #---> Store Password name = "/prod/masterdb/password" type = "SecureString" value = random_password.masterdb.result } data "aws_ssm_parameter" "masterdb_password" { #---> Get Password name = aws_ssm_parameter.masterdb_password.name } resource "aws_db_instance" "masterdb" { #---> Use Password identifier = "prod-master-db" db_name = "master" allocated_storage = 20 instance_class = "db.t3.micro" engine = "mysql" engine_version = "8.0" username = "admin" skip_final_snapshot = true password = data.aws_ssm_parameter.masterdb_password.value } ================================================ FILE: Lesson-37/action/lambda_function.py ================================================ # ------------------------------------------------------------------------------ # Simple Lambda Function which print payload # # Version Date Name Info # 1.0 15-October-2025 Denis Astahov Initial Version # # ------------------------------------------------------------------------------ def lambda_handler(event, context): print("Incoming Event:") print(event) message = { "message": "Lambda got this Payload:", "payload": event } return message ================================================ FILE: Lesson-37/action/lambda_function.tf ================================================ resource "aws_lambda_function" "this" { function_name = var.name description = "Created by Terraform" role = aws_iam_role.lambda.arn runtime = "python3.13" handler = "lambda_function.lambda_handler" filename = data.archive_file.lambda_zip.output_path source_code_hash = data.archive_file.lambda_zip.output_base64sha256 tags = var.tags lifecycle { action_trigger { events = [after_create, after_update] actions = [action.aws_lambda_invoke.this] } } } action "aws_lambda_invoke" "this" { config { function_name = aws_lambda_function.this.function_name payload = jsonencode({ Message = "Triggered by Terraform Action" }) } } # terraform apply -invoke action.aws_lambda_invoke.count action "aws_lambda_invoke" "count" { count = 5 config { function_name = aws_lambda_function.this.function_name payload = jsonencode({ Message = "Triggered by Terraform Action" InvokeNumber = count.index + 1 }) } } ================================================ FILE: Lesson-37/action/main.tf ================================================ # -----Lambda Package data "archive_file" "lambda_zip" { type = "zip" output_path = "lambda_function.zip" source { filename = "lambda_function.py" content = file("${path.module}/lambda_function.py") } } #--------------- Lambda IAM Permissions resource "aws_iam_role" "lambda" { name = "${var.name}-iam-role" tags = var.tags assume_role_policy = <
Course covering all features of Terraform v0.12, v0.13, v0.14, v0.15 and v1.x # Terraform Lessons by Denis Astahov ### Set AWS Credentials in Windows PowerShell: ``` $env:AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxx" $env:AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyyyyyyyyyy" $env:AWS_DEFAULT_REGION="zzzzzzzzz" ``` ### Set AWS Credentials in Linux Shell: ``` export AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxx" export AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyyyyyyyyyy" export AWS_DEFAULT_REGION="zzzzzzzzz" ``` ### Terraform Commands ``` terraform init terraform plan terraform apply terraform destroy terraform show terraform output terraform console terraform import terraform taint ``` ### Terraform State Commands ``` terraform state show terraform state list terraform state pull terraform state rm terraform state mv terraform state push ``` `for x in $(terraform state list | grep xyz); do terraform state mv -state-out=”terraform.tfstate” $x $x; done` ### Terraform Workspace Commands ``` terraform workspace show terraform workspace list terraform workspace new terraform workspace select terraform workspace delete ``` `${terraform.workspace}`