├── .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-v0.15.2+ └── main.tf ├── Lesson-27 └── 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 ├── README.md └── terraform.jpg /.gitignore: -------------------------------------------------------------------------------- 1 | .terraform/ 2 | *.tfstate 3 | *.tfstate.backup 4 | *.terraform.lock.hcl 5 | -------------------------------------------------------------------------------- /Lesson-01/Lesson-1.tf: -------------------------------------------------------------------------------- 1 | provider "aws" {} 2 | 3 | 4 | resource "aws_instance" "my_Ubuntu" { 5 | ami = "ami-090f10efc254eaf55" 6 | instance_type = "t3.micro" 7 | 8 | tags = { 9 | Name = "My Ubuntu Server" 10 | Owner = "Denis Astahov" 11 | Project = "Terraform Lessons" 12 | } 13 | } 14 | 15 | resource "aws_instance" "my_Amazon" { 16 | ami = "ami-03a71cec707bfc3d7" 17 | instance_type = "t3.small" 18 | 19 | tags = { 20 | Name = "My Amazon Server" 21 | Owner = "Denis Astahov" 22 | Project = "Terraform Lessons" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Lesson-02/WebServer.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "eu-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_instance" "my_webserver" { 17 | ami = "ami-03a71cec707bfc3d7" 18 | instance_type = "t3.micro" 19 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 20 | user_data_replace_on_change = true # This need to added!!!! 21 | user_data = <WebServer with IP: $myip
Build by Terraform!" > /var/www/html/index.html 27 | sudo service httpd start 28 | chkconfig httpd on 29 | EOF 30 | 31 | tags = { 32 | Name = "Web Server Build by Terraform" 33 | Owner = "Denis Astahov" 34 | } 35 | } 36 | 37 | 38 | resource "aws_security_group" "my_webserver" { 39 | name = "WebServer Security Group" 40 | description = "My First SecurityGroup" 41 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 42 | 43 | ingress { 44 | from_port = 80 45 | to_port = 80 46 | protocol = "tcp" 47 | cidr_blocks = ["0.0.0.0/0"] 48 | } 49 | 50 | ingress { 51 | from_port = 443 52 | to_port = 443 53 | protocol = "tcp" 54 | cidr_blocks = ["0.0.0.0/0"] 55 | } 56 | 57 | egress { 58 | from_port = 0 59 | to_port = 0 60 | protocol = "-1" 61 | cidr_blocks = ["0.0.0.0/0"] 62 | } 63 | 64 | tags = { 65 | Name = "Web Server SecurityGroup" 66 | Owner = "Denis Astahov" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Lesson-03/WebServer.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "eu-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_instance" "my_webserver" { 17 | ami = "ami-03a71cec707bfc3d7" 18 | instance_type = "t3.micro" 19 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 20 | user_data = file("user_data.sh") 21 | 22 | tags = { 23 | Name = "Web Server Build by Terraform" 24 | Owner = "Denis Astahov" 25 | } 26 | } 27 | 28 | 29 | resource "aws_security_group" "my_webserver" { 30 | name = "WebServer Security Group" 31 | description = "My First SecurityGroup" 32 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 33 | 34 | ingress { 35 | from_port = 80 36 | to_port = 80 37 | protocol = "tcp" 38 | cidr_blocks = ["0.0.0.0/0"] 39 | } 40 | 41 | ingress { 42 | from_port = 443 43 | to_port = 443 44 | protocol = "tcp" 45 | cidr_blocks = ["0.0.0.0/0"] 46 | } 47 | 48 | egress { 49 | from_port = 0 50 | to_port = 0 51 | protocol = "-1" 52 | cidr_blocks = ["0.0.0.0/0"] 53 | } 54 | 55 | tags = { 56 | Name = "Web Server SecurityGroup" 57 | Owner = "Denis Astahov" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Lesson-03/user_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 5 | echo "

WebServer with IP: $myip


Build by Terraform using External Script!" > /var/www/html/index.html 6 | echo "
Hello World!!" >> /var/www/html/index.html 7 | sudo service httpd start 8 | chkconfig httpd on 9 | -------------------------------------------------------------------------------- /Lesson-04/WebServer.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "eu-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_instance" "my_webserver" { 17 | ami = "ami-03a71cec707bfc3d7" 18 | instance_type = "t3.micro" 19 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 20 | user_data = templatefile("user_data.sh.tpl", { 21 | f_name = "Denis", 22 | l_name = "Astahov", 23 | names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha"] 24 | }) 25 | 26 | tags = { 27 | Name = "Web Server Build by Terraform" 28 | Owner = "Denis Astahov" 29 | } 30 | } 31 | 32 | 33 | resource "aws_security_group" "my_webserver" { 34 | name = "WebServer Security Group" 35 | description = "My First SecurityGroup" 36 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 37 | 38 | ingress { 39 | from_port = 80 40 | to_port = 80 41 | protocol = "tcp" 42 | cidr_blocks = ["0.0.0.0/0"] 43 | } 44 | 45 | ingress { 46 | from_port = 443 47 | to_port = 443 48 | protocol = "tcp" 49 | cidr_blocks = ["0.0.0.0/0"] 50 | } 51 | 52 | egress { 53 | from_port = 0 54 | to_port = 0 55 | protocol = "-1" 56 | cidr_blocks = ["0.0.0.0/0"] 57 | } 58 | 59 | tags = { 60 | Name = "Web Server SecurityGroup" 61 | Owner = "Denis Astahov" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Lesson-04/user_data.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | 5 | 6 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 7 | 8 | cat < /var/www/html/index.html 9 | 10 |

Build by Power of Terraform v0.12


11 | Owner ${f_name} ${l_name}
12 | 13 | %{ for x in names ~} 14 | Hello to ${x} from ${f_name}
15 | %{ endfor ~} 16 | 17 | 18 | EOF 19 | 20 | sudo service httpd start 21 | chkconfig httpd on 22 | -------------------------------------------------------------------------------- /Lesson-05/DynamicSecurityGroup.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "eu-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_security_group" "my_webserver" { 17 | name = "Dynamic Security Group" 18 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 19 | 20 | 21 | dynamic "ingress" { 22 | for_each = ["80", "443", "8080", "1541", "9092", "9093"] 23 | content { 24 | from_port = ingress.value 25 | to_port = ingress.value 26 | protocol = "tcp" 27 | cidr_blocks = ["0.0.0.0/0"] 28 | } 29 | } 30 | 31 | 32 | ingress { 33 | from_port = 22 34 | to_port = 22 35 | protocol = "tcp" 36 | cidr_blocks = ["10.10.0.0/16"] 37 | } 38 | 39 | 40 | 41 | egress { 42 | from_port = 0 43 | to_port = 0 44 | protocol = "-1" 45 | cidr_blocks = ["0.0.0.0/0"] 46 | } 47 | 48 | tags = { 49 | Name = "Dynamic SecurityGroup" 50 | Owner = "Denis Astahov" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Lesson-06/WebServer.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "ca-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_eip" "my_static_ip" { 17 | instance = aws_instance.my_webserver.id 18 | domain = "vpc" # Need to add in new AWS Provider version 19 | tags = { 20 | Name = "Web Server IP" 21 | Owner = "Denis Astahov" 22 | } 23 | } 24 | 25 | 26 | resource "aws_instance" "my_webserver" { 27 | ami = "ami-07ab3281411d31d04" 28 | instance_type = "t3.micro" 29 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 30 | user_data = templatefile("user_data.sh.tpl", { 31 | f_name = "Denis", 32 | l_name = "Astahov", 33 | names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"] 34 | }) 35 | user_data_replace_on_change = true # Added in the new AWS provider!!! 36 | 37 | tags = { 38 | Name = "Web Server Build by Terraform" 39 | Owner = "Denis Astahov" 40 | } 41 | 42 | lifecycle { 43 | create_before_destroy = true 44 | } 45 | } 46 | 47 | 48 | resource "aws_security_group" "my_webserver" { 49 | name = "WebServer Security Group" 50 | description = "My First SecurityGroup" 51 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 52 | 53 | dynamic "ingress" { 54 | for_each = ["80", "443"] 55 | content { 56 | from_port = ingress.value 57 | to_port = ingress.value 58 | protocol = "tcp" 59 | cidr_blocks = ["0.0.0.0/0"] 60 | } 61 | } 62 | 63 | 64 | egress { 65 | from_port = 0 66 | to_port = 0 67 | protocol = "-1" 68 | cidr_blocks = ["0.0.0.0/0"] 69 | } 70 | 71 | tags = { 72 | Name = "Web Server SecurityGroup" 73 | Owner = "Denis Astahov" 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Lesson-06/user_data.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | 5 | 6 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 7 | 8 | cat < /var/www/html/index.html 9 | 10 |

Build by Power of Terraform v0.12


11 | Owner ${f_name} ${l_name}
12 | 13 | %{ for x in names ~} 14 | Hello to ${x} from ${f_name}
15 | %{ endfor ~} 16 |

17 | Server IP: $myip
18 | 19 | EOF 20 | 21 | sudo service httpd start 22 | chkconfig httpd on 23 | -------------------------------------------------------------------------------- /Lesson-07/main.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Build WebServer during Bootstrap 5 | # 6 | # Made by Denis Astahov 7 | #---------------------------------------------------------- 8 | 9 | 10 | provider "aws" { 11 | region = "ca-central-1" 12 | } 13 | 14 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 15 | 16 | resource "aws_eip" "my_static_ip" { 17 | vpc = true # Need to add in new AWS Provider version 18 | instance = aws_instance.my_webserver.id 19 | tags = { 20 | Name = "Web Server IP" 21 | Owner = "Denis Astahov" 22 | } 23 | } 24 | 25 | 26 | resource "aws_instance" "my_webserver" { 27 | ami = "ami-07ab3281411d31d04" 28 | instance_type = "t3.micro" 29 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 30 | user_data = templatefile("user_data.sh.tpl", { 31 | f_name = "Denis", 32 | l_name = "Astahov", 33 | names = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"] 34 | }) 35 | 36 | tags = { 37 | Name = "Web Server Build by Terraform" 38 | Owner = "Denis Astahov" 39 | } 40 | 41 | lifecycle { 42 | create_before_destroy = true 43 | } 44 | 45 | } 46 | 47 | 48 | resource "aws_security_group" "my_webserver" { 49 | name = "WebServer Security Group" 50 | description = "My First SecurityGroup" 51 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 52 | 53 | 54 | dynamic "ingress" { 55 | for_each = ["80", "443"] 56 | content { 57 | from_port = ingress.value 58 | to_port = ingress.value 59 | protocol = "tcp" 60 | cidr_blocks = ["0.0.0.0/0"] 61 | } 62 | } 63 | 64 | 65 | egress { 66 | from_port = 0 67 | to_port = 0 68 | protocol = "-1" 69 | cidr_blocks = ["0.0.0.0/0"] 70 | } 71 | 72 | tags = { 73 | Name = "Web Server SecurityGroup" 74 | Owner = "Denis Astahov" 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Lesson-07/outputs.tf: -------------------------------------------------------------------------------- 1 | output "my_web_site_ip" { 2 | description = "Elatic IP address assigned to our WebSite" 3 | value = aws_eip.my_static_ip.public_ip 4 | } 5 | 6 | output "my_instance_id" { 7 | description = "InstanceID of our WebSite" 8 | value = aws_instance.my_webserver.id 9 | } 10 | 11 | output "my_instance_arn" { 12 | description = "InstanceARN of our WebSite" 13 | value = aws_instance.my_webserver.arn 14 | } 15 | 16 | output "my_sg_id" { 17 | description = "SecurityGroup of our WebSite" 18 | value = aws_security_group.my_webserver.id 19 | } 20 | -------------------------------------------------------------------------------- /Lesson-07/user_data.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | 5 | 6 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 7 | 8 | cat < /var/www/html/index.html 9 | 10 |

Build by Power of Terraform v0.12


11 | Owner ${f_name} ${l_name}
12 | 13 | %{ for x in names ~} 14 | Hello to ${x} from ${f_name}
15 | %{ endfor ~} 16 |

17 | Server IP: $myip
18 | 19 | EOF 20 | 21 | sudo service httpd start 22 | chkconfig httpd on 23 | -------------------------------------------------------------------------------- /Lesson-08/main.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Made by Denis Astahov 5 | #---------------------------------------------------------- 6 | 7 | provider "aws" { 8 | region = "eu-central-1" 9 | } 10 | 11 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 12 | 13 | resource "aws_instance" "my_server_web" { 14 | ami = "ami-03a71cec707bfc3d7" 15 | instance_type = "t3.micro" 16 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 17 | 18 | tags = { 19 | Name = "Server-Web" 20 | } 21 | depends_on = [aws_instance.my_server_db, aws_instance.my_server_app] 22 | } 23 | 24 | resource "aws_instance" "my_server_app" { 25 | ami = "ami-03a71cec707bfc3d7" 26 | instance_type = "t3.micro" 27 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 28 | 29 | tags = { 30 | Name = "Server-Application" 31 | } 32 | 33 | depends_on = [aws_instance.my_server_db] 34 | } 35 | 36 | 37 | resource "aws_instance" "my_server_db" { 38 | ami = "ami-03a71cec707bfc3d7" 39 | instance_type = "t3.micro" 40 | vpc_security_group_ids = [aws_security_group.my_webserver.id] 41 | 42 | tags = { 43 | Name = "Server-Database" 44 | } 45 | } 46 | 47 | 48 | 49 | resource "aws_security_group" "my_webserver" { 50 | name = "My Security Group" 51 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 52 | 53 | 54 | dynamic "ingress" { 55 | for_each = ["80", "443", "22"] 56 | content { 57 | from_port = ingress.value 58 | to_port = ingress.value 59 | protocol = "tcp" 60 | cidr_blocks = ["0.0.0.0/0"] 61 | } 62 | } 63 | 64 | egress { 65 | from_port = 0 66 | to_port = 0 67 | protocol = "-1" 68 | cidr_blocks = ["0.0.0.0/0"] 69 | } 70 | 71 | tags = { 72 | Name = "My SecurityGroup" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Lesson-09/main.tf: -------------------------------------------------------------------------------- 1 | provider "aws" {} 2 | 3 | 4 | data "aws_availability_zones" "working" {} 5 | data "aws_caller_identity" "current" {} 6 | data "aws_region" "current" {} 7 | data "aws_vpcs" "my_vpcs" {} 8 | 9 | 10 | data "aws_vpc" "prod_vpc" { 11 | tags = { 12 | Name = "prod" 13 | } 14 | } 15 | 16 | 17 | resource "aws_subnet" "prod_subnet_1" { 18 | vpc_id = data.aws_vpc.prod_vpc.id 19 | availability_zone = data.aws_availability_zones.working.names[0] 20 | cidr_block = "10.10.1.0/24" 21 | tags = { 22 | Name = "Subnet-1 in ${data.aws_availability_zones.working.names[0]}" 23 | Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}" 24 | Region = data.aws_region.current.description 25 | } 26 | } 27 | 28 | resource "aws_subnet" "prod_subnet_2" { 29 | vpc_id = data.aws_vpc.prod_vpc.id 30 | availability_zone = data.aws_availability_zones.working.names[1] 31 | cidr_block = "10.10.2.0/24" 32 | tags = { 33 | Name = "Subnet-2 in ${data.aws_availability_zones.working.names[1]}" 34 | Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}" 35 | Region = data.aws_region.current.description 36 | } 37 | } 38 | 39 | 40 | 41 | output "prod_vpc_id" { 42 | value = data.aws_vpc.prod_vpc.id 43 | } 44 | 45 | output "prod_vpc_cidr" { 46 | value = data.aws_vpc.prod_vpc.cidr_block 47 | } 48 | 49 | output "aws_vpcs" { 50 | value = data.aws_vpcs.my_vpcs.ids 51 | } 52 | 53 | 54 | output "data_aws_availability_zones" { 55 | value = data.aws_availability_zones.working.names 56 | } 57 | 58 | 59 | output "data_aws_caller_identity" { 60 | value = data.aws_caller_identity.current.account_id 61 | } 62 | 63 | output "data_aws_region_name" { 64 | value = data.aws_region.current.name 65 | } 66 | 67 | output "data_aws_region_description" { 68 | value = data.aws_region.current.description 69 | } 70 | -------------------------------------------------------------------------------- /Lesson-10/main.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # My Terraform 3 | # 4 | # Find Latest AMI id of: 5 | # - Ubuntu 18.04 6 | # - Amazon Linux 2 7 | # - Windows Server 2016 Base 8 | # 9 | # Made by Denis Astahov 10 | #----------------------------------------------------------- 11 | 12 | 13 | provider "aws" { 14 | region = "ap-southeast-2" 15 | } 16 | 17 | data "aws_ami" "latest_ubuntu" { 18 | owners = ["099720109477"] 19 | most_recent = true 20 | filter { 21 | name = "name" 22 | values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] 23 | } 24 | } 25 | 26 | 27 | data "aws_ami" "latest_amazon_linux" { 28 | owners = ["amazon"] 29 | most_recent = true 30 | filter { 31 | name = "name" 32 | values = ["amzn2-ami-hvm-*-x86_64-gp2"] 33 | } 34 | } 35 | 36 | 37 | data "aws_ami" "latest_windows_2016" { 38 | owners = ["amazon"] 39 | most_recent = true 40 | filter { 41 | name = "name" 42 | values = ["Windows_Server-2016-English-Full-Base-*"] 43 | } 44 | 45 | } 46 | 47 | // How to use 48 | /* 49 | resource "aws_instance" "my_webserver_with_latest_ubuntu_ami" { 50 | ami = data.aws_ami.latest_ubuntu.id 51 | instance_type = "t3.micro" 52 | } 53 | */ 54 | 55 | 56 | output "latest_windows_2016_ami_id" { 57 | value = data.aws_ami.latest_windows_2016.id 58 | } 59 | 60 | output "latest_windows_2016_ami_name" { 61 | value = data.aws_ami.latest_windows_2016.name 62 | } 63 | 64 | 65 | output "latest_amazon_linux_ami_id" { 66 | value = data.aws_ami.latest_amazon_linux.id 67 | } 68 | 69 | output "latest_amazon_linux_ami_name" { 70 | value = data.aws_ami.latest_amazon_linux.name 71 | } 72 | 73 | 74 | output "latest_ubuntu_ami_id" { 75 | value = data.aws_ami.latest_ubuntu.id 76 | } 77 | 78 | output "latest_ubuntu_ami_name" { 79 | value = data.aws_ami.latest_ubuntu.name 80 | } 81 | -------------------------------------------------------------------------------- /Lesson-11-ALB-LaunchTemplate/main.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # Provision Highly Availabe Web in any Region Default VPC 3 | # Create: 4 | # - Security Group for Web Server and ALB 5 | # - Launch Template with Auto AMI Lookup 6 | # - Auto Scaling Group using 2 Availability Zones 7 | # - Application Load Balancer in 2 Availability Zones 8 | # - Application Load Balancer TargetGroup 9 | # Update to Web Servers will be via Green/Blue Deployment Strategy 10 | # Made by Denis Astahov 07-March-2023 11 | #----------------------------------------------------------- 12 | 13 | provider "aws" { 14 | region = "ca-central-1" 15 | 16 | default_tags { 17 | tags = { 18 | Owner = "Denis Astahov" 19 | CreatedBy = "Terraform" 20 | Course = "From Zero to Certified Professional" 21 | } 22 | } 23 | } 24 | 25 | 26 | data "aws_availability_zones" "working" {} 27 | data "aws_ami" "latest_amazon_linux" { 28 | owners = ["137112412989"] 29 | most_recent = true 30 | filter { 31 | name = "name" 32 | values = ["amzn2-ami-hvm-*-x86_64-gp2"] 33 | } 34 | } 35 | 36 | #------------------------------------------------------------------------------- 37 | resource "aws_default_vpc" "default" {} 38 | 39 | resource "aws_default_subnet" "default_az1" { 40 | availability_zone = data.aws_availability_zones.working.names[0] 41 | } 42 | 43 | resource "aws_default_subnet" "default_az2" { 44 | availability_zone = data.aws_availability_zones.working.names[1] 45 | } 46 | 47 | #------------------------------------------------------------------------------- 48 | resource "aws_security_group" "web" { 49 | name = "Web Security Group" 50 | vpc_id = aws_default_vpc.default.id 51 | dynamic "ingress" { 52 | for_each = ["80", "443"] 53 | content { 54 | from_port = ingress.value 55 | to_port = ingress.value 56 | protocol = "tcp" 57 | cidr_blocks = ["0.0.0.0/0"] 58 | } 59 | } 60 | egress { 61 | from_port = 0 62 | to_port = 0 63 | protocol = "-1" 64 | cidr_blocks = ["0.0.0.0/0"] 65 | } 66 | tags = { 67 | Name = "Web Security Group" 68 | } 69 | } 70 | 71 | #------------------------------------------------------------------------------- 72 | resource "aws_launch_template" "web" { 73 | name = "WebServer-Highly-Available-LT" 74 | image_id = data.aws_ami.latest_amazon_linux.id 75 | instance_type = "t3.micro" 76 | vpc_security_group_ids = [aws_security_group.web.id] 77 | user_data = filebase64("${path.module}/user_data.sh") 78 | } 79 | 80 | resource "aws_autoscaling_group" "web" { 81 | name = "WebServer-Highly-Available-ASG-Ver-${aws_launch_template.web.latest_version}" 82 | min_size = 2 83 | max_size = 2 84 | min_elb_capacity = 2 85 | health_check_type = "ELB" 86 | vpc_zone_identifier = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] 87 | target_group_arns = [aws_lb_target_group.web.arn] 88 | 89 | launch_template { 90 | id = aws_launch_template.web.id 91 | version = aws_launch_template.web.latest_version 92 | } 93 | 94 | dynamic "tag" { 95 | for_each = { 96 | Name = "WebServer in ASG-v${aws_launch_template.web.latest_version}" 97 | TAGKEY = "TAGVALUE" 98 | } 99 | content { 100 | key = tag.key 101 | value = tag.value 102 | propagate_at_launch = true 103 | } 104 | } 105 | lifecycle { 106 | create_before_destroy = true 107 | } 108 | } 109 | 110 | #------------------------------------------------------------------------------- 111 | resource "aws_lb" "web" { 112 | name = "WebServer-HighlyAvailable-ALB" 113 | load_balancer_type = "application" 114 | security_groups = [aws_security_group.web.id] 115 | subnets = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] 116 | } 117 | 118 | resource "aws_lb_target_group" "web" { 119 | name = "WebServer-HighlyAvailable-TG" 120 | vpc_id = aws_default_vpc.default.id 121 | port = 80 122 | protocol = "HTTP" 123 | deregistration_delay = 10 # seconds 124 | } 125 | 126 | resource "aws_lb_listener" "http" { 127 | load_balancer_arn = aws_lb.web.arn 128 | port = "80" 129 | protocol = "HTTP" 130 | 131 | default_action { 132 | type = "forward" 133 | target_group_arn = aws_lb_target_group.web.arn 134 | } 135 | } 136 | 137 | #------------------------------------------------------------------------------- 138 | output "web_loadbalancer_url" { 139 | value = aws_lb.web.dns_name 140 | } 141 | -------------------------------------------------------------------------------- /Lesson-11-ALB-LaunchTemplate/user_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | 5 | 6 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 7 | 8 | cat < /var/www/html/index.html 9 | 10 | 11 |

Build by Power of Terraform v0.12


12 | Server PrivateIP: $myip

13 | 14 | 15 | Version 3.0 16 | 17 | 18 | EOF 19 | 20 | sudo service httpd start 21 | chkconfig httpd on 22 | -------------------------------------------------------------------------------- /Lesson-11-ELB-LaunchConfiguration/main.tf: -------------------------------------------------------------------------------- 1 | #---------------------------------------------------------- 2 | # Provision Highly Availabe Web in any Region Default VPC 3 | # Create: 4 | # - Security Group for Web Server 5 | # - Launch Configuration with Auto AMI Lookup 6 | # - Auto Scaling Group using 2 Availability Zones 7 | # - Classic Load Balancer in 2 Availability Zones 8 | # 9 | # Made by Denis Astahov 11-June-2019 10 | #----------------------------------------------------------- 11 | 12 | provider "aws" { 13 | region = "eu-west-2" 14 | } 15 | 16 | resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id 17 | 18 | data "aws_availability_zones" "available" {} 19 | data "aws_ami" "latest_amazon_linux" { 20 | owners = ["amazon"] 21 | most_recent = true 22 | filter { 23 | name = "name" 24 | values = ["amzn2-ami-hvm-*-x86_64-gp2"] 25 | } 26 | } 27 | 28 | #-------------------------------------------------------------- 29 | resource "aws_security_group" "web" { 30 | name = "Dynamic Security Group" 31 | vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id 32 | 33 | dynamic "ingress" { 34 | for_each = ["80", "443"] 35 | content { 36 | from_port = ingress.value 37 | to_port = ingress.value 38 | protocol = "tcp" 39 | cidr_blocks = ["0.0.0.0/0"] 40 | } 41 | } 42 | egress { 43 | from_port = 0 44 | to_port = 0 45 | protocol = "-1" 46 | cidr_blocks = ["0.0.0.0/0"] 47 | } 48 | 49 | tags = { 50 | Name = "Dynamic SecurityGroup" 51 | Owner = "Denis Astahov" 52 | } 53 | } 54 | 55 | 56 | resource "aws_launch_configuration" "web" { 57 | // name = "WebServer-Highly-Available-LC" 58 | name_prefix = "WebServer-Highly-Available-LC-" 59 | image_id = data.aws_ami.latest_amazon_linux.id 60 | instance_type = "t3.micro" 61 | security_groups = [aws_security_group.web.id] 62 | user_data = file("user_data.sh") 63 | 64 | lifecycle { 65 | create_before_destroy = true 66 | } 67 | } 68 | 69 | 70 | 71 | resource "aws_autoscaling_group" "web" { 72 | name = "ASG-${aws_launch_configuration.web.name}" 73 | launch_configuration = aws_launch_configuration.web.name 74 | min_size = 2 75 | max_size = 2 76 | min_elb_capacity = 2 77 | health_check_type = "ELB" 78 | vpc_zone_identifier = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id] 79 | load_balancers = [aws_elb.web.name] 80 | 81 | dynamic "tag" { 82 | for_each = { 83 | Name = "WebServer in ASG" 84 | Owner = "Denis Astahov" 85 | TAGKEY = "TAGVALUE" 86 | } 87 | content { 88 | key = tag.key 89 | value = tag.value 90 | propagate_at_launch = true 91 | } 92 | } 93 | 94 | lifecycle { 95 | create_before_destroy = true 96 | } 97 | } 98 | 99 | 100 | resource "aws_elb" "web" { 101 | name = "WebServer-HA-ELB" 102 | availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]] 103 | security_groups = [aws_security_group.web.id] 104 | listener { 105 | lb_port = 80 106 | lb_protocol = "http" 107 | instance_port = 80 108 | instance_protocol = "http" 109 | } 110 | health_check { 111 | healthy_threshold = 2 112 | unhealthy_threshold = 2 113 | timeout = 3 114 | target = "HTTP:80/" 115 | interval = 10 116 | } 117 | tags = { 118 | Name = "WebServer-Highly-Available-ELB" 119 | } 120 | } 121 | 122 | 123 | resource "aws_default_subnet" "default_az1" { 124 | availability_zone = data.aws_availability_zones.available.names[0] 125 | } 126 | 127 | resource "aws_default_subnet" "default_az2" { 128 | availability_zone = data.aws_availability_zones.available.names[1] 129 | } 130 | 131 | #-------------------------------------------------- 132 | output "web_loadbalancer_url" { 133 | value = aws_elb.web.dns_name 134 | } 135 | -------------------------------------------------------------------------------- /Lesson-11-ELB-LaunchConfiguration/user_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | yum -y update 3 | yum -y install httpd 4 | 5 | 6 | myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4` 7 | 8 | cat < /var/www/html/index.html 9 | 10 | 11 |

Build by Power of Terraform v0.12


12 | Server PrivateIP: $myip

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