Full Code of adv4000/terraform-lessons for AI

master 0f1e1b970f13 cached
150 files
101.7 KB
33.5k tokens
2 symbols
1 requests
Download .txt
Repository: adv4000/terraform-lessons
Branch: master
Commit: 0f1e1b970f13
Files: 150
Total size: 101.7 KB

Directory structure:
gitextract_d5h_045t/

├── .gitignore
├── Lesson-01/
│   └── Lesson-1.tf
├── Lesson-02/
│   └── WebServer.tf
├── Lesson-03/
│   ├── WebServer.tf
│   └── user_data.sh
├── Lesson-04/
│   ├── WebServer.tf
│   └── user_data.sh.tpl
├── Lesson-05/
│   └── DynamicSecurityGroup.tf
├── Lesson-06/
│   ├── WebServer.tf
│   └── user_data.sh.tpl
├── Lesson-07/
│   ├── main.tf
│   ├── outputs.tf
│   └── user_data.sh.tpl
├── Lesson-08/
│   └── main.tf
├── Lesson-09/
│   └── main.tf
├── Lesson-10/
│   └── main.tf
├── Lesson-11-ALB-LaunchTemplate/
│   ├── main.tf
│   └── user_data.sh
├── Lesson-11-ELB-LaunchConfiguration/
│   ├── main.tf
│   └── user_data.sh
├── Lesson-12/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-13/
│   ├── dev.tfvars
│   ├── main.tf
│   ├── outputs.tf
│   ├── prod.tfvars
│   └── variables.tf
├── Lesson-14/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-15/
│   └── main.tf
├── Lesson-16/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-17/
│   ├── main.tf
│   └── variables.tf
├── Lesson-18/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-19/
│   └── main.tf
├── Lesson-20/
│   ├── Layer1-Network/
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── Layer2-Servers/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-21/
│   ├── modules/
│   │   ├── aws_network/
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   └── variables.tf
│   │   ├── aws_security_group/
│   │   │   └── main.tf
│   │   └── aws_something/
│   │       └── main.tf
│   └── projectA/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-22/
│   ├── ProjectXYZ/
│   │   ├── dev/
│   │   │   ├── kms/
│   │   │   │   └── main.tf
│   │   │   ├── network/
│   │   │   │   └── main.tf
│   │   │   ├── route53/
│   │   │   │   └── main.tf
│   │   │   ├── s3/
│   │   │   │   └── main.tf
│   │   │   └── vpc/
│   │   │       ├── applications/
│   │   │       │   ├── app1/
│   │   │       │   │   └── main.tf
│   │   │       │   └── app2/
│   │   │       │       └── main.tf
│   │   │       ├── databases/
│   │   │       │   └── main.tf
│   │   │       ├── ecs_cluster/
│   │   │       │   └── main.tf
│   │   │       └── vpn/
│   │   │           └── main.tf
│   │   ├── prod/
│   │   │   ├── kms/
│   │   │   │   └── main.tf
│   │   │   ├── network/
│   │   │   │   └── main.tf
│   │   │   ├── route53/
│   │   │   │   └── main.tf
│   │   │   ├── s3/
│   │   │   │   └── main.tf
│   │   │   └── vpc/
│   │   │       ├── applications/
│   │   │       │   ├── app1/
│   │   │       │   │   └── main.tf
│   │   │       │   └── app2/
│   │   │       │       └── main.tf
│   │   │       ├── databases/
│   │   │       │   └── main.tf
│   │   │       ├── ecs_cluster/
│   │   │       │   └── main.tf
│   │   │       └── vpn/
│   │   │           └── main.tf
│   │   └── staging/
│   │       ├── kms/
│   │       │   └── main.tf
│   │       ├── network/
│   │       │   └── main.tf
│   │       ├── route53/
│   │       │   └── main.tf
│   │       ├── s3/
│   │       │   └── main.tf
│   │       └── vpc/
│   │           ├── applications/
│   │           │   ├── app1/
│   │           │   │   └── main.tf
│   │           │   └── app2/
│   │           │       └── main.tf
│   │           ├── databases/
│   │           │   └── main.tf
│   │           ├── ecs_cluster/
│   │           │   └── main.tf
│   │           └── vpn/
│   │               └── main.tf
│   ├── README.MD
│   └── modules/
│       ├── aws_network/
│       │   └── main.tf
│       ├── aws_security_group/
│       │   └── main.tf
│       └── aws_something/
│           └── main.tf
├── Lesson-23/
│   ├── globalvars/
│   │   └── main.tf
│   ├── stack1/
│   │   └── main.tf
│   └── stack2/
│       └── main.tf
├── Lesson-24/
│   ├── main.tf
│   └── mygcp-creds.json
├── Lesson-25/
│   └── README.MD
├── Lesson-26/
│   ├── import-begin.tf
│   └── import-finish.tf
├── Lesson-27/
│   └── main.tf
├── Lesson-27-v0.15.2+/
│   └── main.tf
├── Lesson-28/
│   ├── new-prod/
│   │   ├── config.tf
│   │   ├── ip-prod.tf
│   │   ├── main.tf
│   │   └── web-prod.tf
│   ├── new-staging/
│   │   ├── config.tf
│   │   ├── ip-stag.tf
│   │   ├── main.tf
│   │   └── web-stag.tf
│   └── old-all/
│       ├── config.tf
│       ├── ip-prod.tf
│       ├── ip-stag.tf
│       ├── main.tf
│       ├── web-prod.tf
│       └── web-stag.tf
├── Lesson-29/
│   ├── config.tf
│   └── main.tf
├── Lesson-30/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-31/
│   ├── main.tf
│   ├── modules/
│   │   ├── aws_network/
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   └── variables.tf
│   │   ├── aws_security_group/
│   │   │   └── main.tf
│   │   └── aws_something/
│   │       └── main.tf
│   └── variables.tf
├── Lesson-32/
│   ├── main.tf
│   └── module_servers/
│       ├── main.tf
│       └── variables.tf
├── Lesson-33/
│   ├── iam_groups.tf
│   ├── iam_groups_policies.tf
│   └── variables.tf
├── Lesson-34/
│   └── main.tf
├── Lesson-35/
│   ├── deployments/
│   │   ├── dev/
│   │   │   ├── config.tf
│   │   │   └── main.tf
│   │   └── prod/
│   │       ├── config.tf
│   │       └── main.tf
│   ├── module-aws-rds/
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── module-aws-vpc/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-36/
│   ├── ephemeral/
│   │   └── main.tf
│   └── non-ephemeral/
│       └── main.tf
├── Lesson-37/
│   ├── action/
│   │   ├── lambda_function.py
│   │   ├── lambda_function.tf
│   │   ├── main.tf
│   │   └── variables.tf
│   └── non-action/
│       ├── lambda_function.py
│       ├── lambda_function.tf
│       ├── main.tf
│       └── variables.tf
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.terraform/
*.tfstate
*.tfstate.backup
*.terraform.lock.hcl


================================================
FILE: Lesson-01/Lesson-1.tf
================================================
provider "aws" {}


resource "aws_instance" "my_Ubuntu" {
  ami           = "ami-090f10efc254eaf55"
  instance_type = "t3.micro"

  tags = {
    Name    = "My Ubuntu Server"
    Owner   = "Denis Astahov"
    Project = "Terraform Lessons"
  }
}

resource "aws_instance" "my_Amazon" {
  ami           = "ami-03a71cec707bfc3d7"
  instance_type = "t3.small"

  tags = {
    Name    = "My Amazon Server"
    Owner   = "Denis Astahov"
    Project = "Terraform Lessons"
  }
}


================================================
FILE: Lesson-02/WebServer.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_instance" "my_webserver" {
  ami                         = "ami-03a71cec707bfc3d7"
  instance_type               = "t3.micro"
  vpc_security_group_ids      = [aws_security_group.my_webserver.id]
  user_data_replace_on_change = true   # This need to added!!!!  
  user_data                   = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "Web Server Build by Terraform"
    Owner = "Denis Astahov"
  }
}


resource "aws_security_group" "my_webserver" {
  name        = "WebServer Security Group"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-03/WebServer.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_instance" "my_webserver" {
  ami                    = "ami-03a71cec707bfc3d7"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]
  user_data              = file("user_data.sh")

  tags = {
    Name  = "Web Server Build by Terraform"
    Owner = "Denis Astahov"
  }
}


resource "aws_security_group" "my_webserver" {
  name        = "WebServer Security Group"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-03/user_data.sh
================================================
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>WebServer with IP: $myip</h2><br>Build by Terraform using External Script!"  >  /var/www/html/index.html
echo "<br><font color="blue">Hello World!!" >> /var/www/html/index.html
sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-04/WebServer.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_instance" "my_webserver" {
  ami                    = "ami-03a71cec707bfc3d7"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]
  user_data = templatefile("user_data.sh.tpl", {
    f_name = "Denis",
    l_name = "Astahov",
    names  = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha"]
  })

  tags = {
    Name  = "Web Server Build by Terraform"
    Owner = "Denis Astahov"
  }
}


resource "aws_security_group" "my_webserver" {
  name        = "WebServer Security Group"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-04/user_data.sh.tpl
================================================
#!/bin/bash
yum -y update
yum -y install httpd


myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`

cat <<EOF > /var/www/html/index.html
<html>
<h2>Build by Power of Terraform <font color="red"> v0.12</font></h2><br>
Owner ${f_name} ${l_name} <br>

%{ for x in names ~}
Hello to ${x} from ${f_name}<br>
%{ endfor ~}

</html>
EOF

sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-05/DynamicSecurityGroup.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_security_group" "my_webserver" {
  name   = "Dynamic Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id


  dynamic "ingress" {
    for_each = ["80", "443", "8080", "1541", "9092", "9093"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }


  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["10.10.0.0/16"]
  }



  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Dynamic SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-06/WebServer.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "ca-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_eip" "my_static_ip" {
  instance = aws_instance.my_webserver.id
  domain   = "vpc" # Need to add in new AWS Provider version
  tags = {
    Name  = "Web Server IP"
    Owner = "Denis Astahov"
  }
}


resource "aws_instance" "my_webserver" {
  ami                    = "ami-07ab3281411d31d04"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]
  user_data = templatefile("user_data.sh.tpl", {
    f_name = "Denis",
    l_name = "Astahov",
    names  = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"]
  })
  user_data_replace_on_change = true # Added in the new AWS provider!!!

  tags = {
    Name  = "Web Server Build by Terraform"
    Owner = "Denis Astahov"
  }

  lifecycle {
    create_before_destroy = true
  }
}


resource "aws_security_group" "my_webserver" {
  name        = "WebServer Security Group"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  dynamic "ingress" {
    for_each = ["80", "443"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }


  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-06/user_data.sh.tpl
================================================
#!/bin/bash
yum -y update
yum -y install httpd


myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`

cat <<EOF > /var/www/html/index.html
<html>
<h2>Build by Power of Terraform <font color="red"> v0.12</font></h2><br>
Owner ${f_name} ${l_name} <br>

%{ for x in names ~}
Hello to ${x} from ${f_name}<br>
%{ endfor ~}
<p>
Server IP: $myip<br>
</html>
EOF

sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-07/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Build WebServer during Bootstrap
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "ca-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_eip" "my_static_ip" {
  vpc      = true # Need to add in new AWS Provider version
  instance = aws_instance.my_webserver.id
  tags = {
    Name  = "Web Server IP"
    Owner = "Denis Astahov"
  }
}


resource "aws_instance" "my_webserver" {
  ami                    = "ami-07ab3281411d31d04"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]
  user_data = templatefile("user_data.sh.tpl", {
    f_name = "Denis",
    l_name = "Astahov",
    names  = ["Vasya", "Kolya", "Petya", "John", "Donald", "Masha", "Lena", "Katya"]
  })

  tags = {
    Name  = "Web Server Build by Terraform"
    Owner = "Denis Astahov"
  }

  lifecycle {
    create_before_destroy = true
  }

}


resource "aws_security_group" "my_webserver" {
  name        = "WebServer Security Group"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id


  dynamic "ingress" {
    for_each = ["80", "443"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }


  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-07/outputs.tf
================================================
output "my_web_site_ip" {
  description = "Elatic IP address assigned to our WebSite"
  value       = aws_eip.my_static_ip.public_ip
}

output "my_instance_id" {
  description = "InstanceID of our WebSite"
  value       = aws_instance.my_webserver.id
}

output "my_instance_arn" {
  description = "InstanceARN of our WebSite"
  value       = aws_instance.my_webserver.arn
}

output "my_sg_id" {
  description = "SecurityGroup of our WebSite"
  value       = aws_security_group.my_webserver.id
}


================================================
FILE: Lesson-07/user_data.sh.tpl
================================================
#!/bin/bash
yum -y update
yum -y install httpd


myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`

cat <<EOF > /var/www/html/index.html
<html>
<h2>Build by Power of Terraform <font color="red"> v0.12</font></h2><br>
Owner ${f_name} ${l_name} <br>

%{ for x in names ~}
Hello to ${x} from ${f_name}<br>
%{ endfor ~}
<p>
Server IP: $myip<br>
</html>
EOF

sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-08/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Made by Denis Astahov
#----------------------------------------------------------

provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_instance" "my_server_web" {
  ami                    = "ami-03a71cec707bfc3d7"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]

  tags = {
    Name = "Server-Web"
  }
  depends_on = [aws_instance.my_server_db, aws_instance.my_server_app]
}

resource "aws_instance" "my_server_app" {
  ami                    = "ami-03a71cec707bfc3d7"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]

  tags = {
    Name = "Server-Application"
  }

  depends_on = [aws_instance.my_server_db]
}


resource "aws_instance" "my_server_db" {
  ami                    = "ami-03a71cec707bfc3d7"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.my_webserver.id]

  tags = {
    Name = "Server-Database"
  }
}



resource "aws_security_group" "my_webserver" {
  name   = "My Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id


  dynamic "ingress" {
    for_each = ["80", "443", "22"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "My SecurityGroup"
  }
}


================================================
FILE: Lesson-09/main.tf
================================================
provider "aws" {}


data "aws_availability_zones" "working" {}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
data "aws_vpcs" "my_vpcs" {}


data "aws_vpc" "prod_vpc" {
  tags = {
    Name = "prod"
  }
}


resource "aws_subnet" "prod_subnet_1" {
  vpc_id            = data.aws_vpc.prod_vpc.id
  availability_zone = data.aws_availability_zones.working.names[0]
  cidr_block        = "10.10.1.0/24"
  tags = {
    Name    = "Subnet-1 in ${data.aws_availability_zones.working.names[0]}"
    Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}"
    Region  = data.aws_region.current.description
  }
}

resource "aws_subnet" "prod_subnet_2" {
  vpc_id            = data.aws_vpc.prod_vpc.id
  availability_zone = data.aws_availability_zones.working.names[1]
  cidr_block        = "10.10.2.0/24"
  tags = {
    Name    = "Subnet-2 in ${data.aws_availability_zones.working.names[1]}"
    Account = "Subnet in Account ${data.aws_caller_identity.current.account_id}"
    Region  = data.aws_region.current.description
  }
}



output "prod_vpc_id" {
  value = data.aws_vpc.prod_vpc.id
}

output "prod_vpc_cidr" {
  value = data.aws_vpc.prod_vpc.cidr_block
}

output "aws_vpcs" {
  value = data.aws_vpcs.my_vpcs.ids
}


output "data_aws_availability_zones" {
  value = data.aws_availability_zones.working.names
}


output "data_aws_caller_identity" {
  value = data.aws_caller_identity.current.account_id
}

output "data_aws_region_name" {
  value = data.aws_region.current.region
}

output "data_aws_region_description" {
  value = data.aws_region.current.description
}


================================================
FILE: Lesson-10/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Find Latest AMI id of:
#    - Ubuntu 18.04
#    - Amazon Linux 2
#    - Windows Server 2016 Base
#
# Made by Denis Astahov
#-----------------------------------------------------------


provider "aws" {
  region = "ap-southeast-2"
}

data "aws_ami" "latest_ubuntu" {
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }
}


data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


data "aws_ami" "latest_windows_2016" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["Windows_Server-2016-English-Full-Base-*"]
  }

}

// How to use
/*
resource "aws_instance" "my_webserver_with_latest_ubuntu_ami" {
  ami           = data.aws_ami.latest_ubuntu.id
  instance_type = "t3.micro"
}
*/


output "latest_windows_2016_ami_id" {
  value = data.aws_ami.latest_windows_2016.id
}

output "latest_windows_2016_ami_name" {
  value = data.aws_ami.latest_windows_2016.name
}


output "latest_amazon_linux_ami_id" {
  value = data.aws_ami.latest_amazon_linux.id
}

output "latest_amazon_linux_ami_name" {
  value = data.aws_ami.latest_amazon_linux.name
}


output "latest_ubuntu_ami_id" {
  value = data.aws_ami.latest_ubuntu.id
}

output "latest_ubuntu_ami_name" {
  value = data.aws_ami.latest_ubuntu.name
}


================================================
FILE: Lesson-11-ALB-LaunchTemplate/main.tf
================================================
#----------------------------------------------------------
# Provision Highly Availabe Web in any Region Default VPC
# Create:
#    - Security Group for Web Server and ALB
#    - Launch Template with Auto AMI Lookup
#    - Auto Scaling Group using 2 Availability Zones
#    - Application Load Balancer in 2 Availability Zones
#    - Application Load Balancer TargetGroup
# Update to Web Servers will be via Green/Blue Deployment Strategy
# Made by Denis Astahov 07-March-2023
#-----------------------------------------------------------

provider "aws" {
  region = "ca-central-1"

  default_tags {
    tags = {
      Owner     = "Denis Astahov"
      CreatedBy = "Terraform"
      Course    = "From Zero to Certified Professional"
    }
  }
}


data "aws_availability_zones" "working" {}
data "aws_ami" "latest_amazon_linux" {
  owners      = ["137112412989"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

#-------------------------------------------------------------------------------
resource "aws_default_vpc" "default" {}

resource "aws_default_subnet" "default_az1" {
  availability_zone = data.aws_availability_zones.working.names[0]
}

resource "aws_default_subnet" "default_az2" {
  availability_zone = data.aws_availability_zones.working.names[1]
}

#-------------------------------------------------------------------------------
resource "aws_security_group" "web" {
  name   = "Web Security Group"
  vpc_id = aws_default_vpc.default.id
  dynamic "ingress" {
    for_each = ["80", "443"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "Web Security Group"
  }
}

#-------------------------------------------------------------------------------
resource "aws_launch_template" "web" {
  name                   = "WebServer-Highly-Available-LT"
  image_id               = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web.id]
  user_data              = filebase64("${path.module}/user_data.sh")
}

resource "aws_autoscaling_group" "web" {
  name                = "WebServer-Highly-Available-ASG-Ver-${aws_launch_template.web.latest_version}"
  min_size            = 2
  max_size            = 2
  min_elb_capacity    = 2
  health_check_type   = "ELB"
  vpc_zone_identifier = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id]
  target_group_arns   = [aws_lb_target_group.web.arn]

  launch_template {
    id      = aws_launch_template.web.id
    version = aws_launch_template.web.latest_version
  }

  dynamic "tag" {
    for_each = {
      Name   = "WebServer in ASG-v${aws_launch_template.web.latest_version}"
      TAGKEY = "TAGVALUE"
    }
    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }
  lifecycle {
    create_before_destroy = true
  }
}

#-------------------------------------------------------------------------------
resource "aws_lb" "web" {
  name               = "WebServer-HighlyAvailable-ALB"
  load_balancer_type = "application"
  security_groups    = [aws_security_group.web.id]
  subnets            = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id]
}

resource "aws_lb_target_group" "web" {
  name                 = "WebServer-HighlyAvailable-TG"
  vpc_id               = aws_default_vpc.default.id
  port                 = 80
  protocol             = "HTTP"
  deregistration_delay = 10 # seconds
}

resource "aws_lb_listener" "http" {
  load_balancer_arn = aws_lb.web.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.web.arn
  }
}

#-------------------------------------------------------------------------------
output "web_loadbalancer_url" {
  value = aws_lb.web.dns_name
}


================================================
FILE: Lesson-11-ALB-LaunchTemplate/user_data.sh
================================================
#!/bin/bash
yum -y update
yum -y install httpd


myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`

cat <<EOF > /var/www/html/index.html
<html>
<body bgcolor="black">
<h2><font color="gold">Build by Power of Terraform <font color="red"> v0.12</font></h2><br><p>
<font color="green">Server PrivateIP: <font color="aqua">$myip<br><br>

<font color="magenta">
<b>Version 3.0</b>
</body>
</html>
EOF

sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-11-ELB-LaunchConfiguration/main.tf
================================================
#----------------------------------------------------------
# Provision Highly Availabe Web in any Region Default VPC
# Create:
#    - Security Group for Web Server
#    - Launch Configuration with Auto AMI Lookup
#    - Auto Scaling Group using 2 Availability Zones
#    - Classic Load Balancer in 2 Availability Zones
#
# Made by Denis Astahov 11-June-2019
#-----------------------------------------------------------

provider "aws" {
  region = "eu-west-2"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

data "aws_availability_zones" "available" {}
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

#--------------------------------------------------------------
resource "aws_security_group" "web" {
  name   = "Dynamic Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  dynamic "ingress" {
    for_each = ["80", "443"]
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Dynamic SecurityGroup"
    Owner = "Denis Astahov"
  }
}


resource "aws_launch_configuration" "web" {
  //  name            = "WebServer-Highly-Available-LC"
  name_prefix     = "WebServer-Highly-Available-LC-"
  image_id        = data.aws_ami.latest_amazon_linux.id
  instance_type   = "t3.micro"
  security_groups = [aws_security_group.web.id]
  user_data       = file("user_data.sh")

  lifecycle {
    create_before_destroy = true
  }
}



resource "aws_autoscaling_group" "web" {
  name                 = "ASG-${aws_launch_configuration.web.name}"
  launch_configuration = aws_launch_configuration.web.name
  min_size             = 2
  max_size             = 2
  min_elb_capacity     = 2
  health_check_type    = "ELB"
  vpc_zone_identifier  = [aws_default_subnet.default_az1.id, aws_default_subnet.default_az2.id]
  load_balancers       = [aws_elb.web.name]

  dynamic "tag" {
    for_each = {
      Name   = "WebServer in ASG"
      Owner  = "Denis Astahov"
      TAGKEY = "TAGVALUE"
    }
    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }

  lifecycle {
    create_before_destroy = true
  }
}


resource "aws_elb" "web" {
  name               = "WebServer-HA-ELB"
  availability_zones = [data.aws_availability_zones.available.names[0], data.aws_availability_zones.available.names[1]]
  security_groups    = [aws_security_group.web.id]
  listener {
    lb_port           = 80
    lb_protocol       = "http"
    instance_port     = 80
    instance_protocol = "http"
  }
  health_check {
    healthy_threshold   = 2
    unhealthy_threshold = 2
    timeout             = 3
    target              = "HTTP:80/"
    interval            = 10
  }
  tags = {
    Name = "WebServer-Highly-Available-ELB"
  }
}


resource "aws_default_subnet" "default_az1" {
  availability_zone = data.aws_availability_zones.available.names[0]
}

resource "aws_default_subnet" "default_az2" {
  availability_zone = data.aws_availability_zones.available.names[1]
}

#--------------------------------------------------
output "web_loadbalancer_url" {
  value = aws_elb.web.dns_name
}


================================================
FILE: Lesson-11-ELB-LaunchConfiguration/user_data.sh
================================================
#!/bin/bash
yum -y update
yum -y install httpd


myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`

cat <<EOF > /var/www/html/index.html
<html>
<body bgcolor="black">
<h2><font color="gold">Build by Power of Terraform <font color="red"> v0.12</font></h2><br><p>
<font color="green">Server PrivateIP: <font color="aqua">$myip<br><br>

<font color="magenta">
<b>Version 3.0</b>
</body>
</html>
EOF

sudo service httpd start
chkconfig httpd on


================================================
FILE: Lesson-12/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Variables
#
# Made by Denis Astahov
#----------------------------------------------------------



provider "aws" {
  region = var.region
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


resource "aws_eip" "my_static_ip" {
  vpc      = true # Need to add in new AWS Provider version
  instance = aws_instance.my_server.id
  //tags     = var.common_tags
  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server IP" })

  /*
  tags = {
    Name    = "Server IP"
    Owner   = "Denis Astahov"
    Project = "Phoenix"
  }
*/

}



resource "aws_instance" "my_server" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.my_server.id]
  monitoring             = var.enable_detailed_monitoring

  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server Build by Terraform" })

}


resource "aws_security_group" "my_server" {
  name   = "My Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  dynamic "ingress" {
    for_each = var.allow_ports
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server SecurityGroup" })

}


================================================
FILE: Lesson-12/outputs.tf
================================================
output "my_server_ip" {
  value = aws_eip.my_static_ip.public_ip
}

output "my_instance_id" {
  value = aws_instance.my_server.id
}

output "my_sg_id" {
  value = aws_security_group.my_server.id
}


================================================
FILE: Lesson-12/variables.tf
================================================

variable "region" {
  description = "Please Enter AWS Region to deploy Server"
  type        = string
  default     = "ca-central-1"
}

variable "instance_type" {
  description = "Enter Instance Type"
  type        = string
  default     = "t3.small"
}


variable "allow_ports" {
  description = "List of Ports to open for server"
  type        = list
  default     = ["80", "443", "22", "8080"]
}

variable "enable_detailed_monitoring" {
  type    = bool
  default = false
}


variable "common_tags" {
  description = "Common Tags to apply to all resources"
  type        = map
  default = {
    Owner       = "Denis Astahov"
    Project     = "Phoenix"
    CostCenter  = "12345"
    Environment = "development"
  }
}


================================================
FILE: Lesson-13/dev.tfvars
================================================
# Auto Fill variables for DEV

#File names can be  as:
# terraform.tfvars
# prod.auto.tfvars
# dev.auto.tfvars


region                     = "ca-central-1"
instance_type              = "t2.micro"
enable_detailed_monitoring = false

allow_ports = ["80", "22", "8080"]

common_tags = {
  Owner       = "Denis Astahov"
  Project     = "Phoenix"
  CostCenter  = "12345"
  Environment = "dev"
}


================================================
FILE: Lesson-13/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Autofill Variables
#
# Made by Denis Astahov
#----------------------------------------------------------



provider "aws" {
  region = var.region
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


resource "aws_eip" "my_static_ip" {
  vpc      = true # Need to add in new AWS Provider version
  instance = aws_instance.my_server.id
  //tags     = var.common_tags
  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server IP" })

  /*
  tags = {
    Name    = "Server IP"
    Owner   = "Denis Astahov"
    Project = "Phoenix"
  }
*/

}



resource "aws_instance" "my_server" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.my_server.id]
  monitoring             = var.enable_detailed_monitoring

  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server Build by Terraform" })

}


resource "aws_security_group" "my_server" {
  name   = "My Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  dynamic "ingress" {
    for_each = var.allow_ports
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = merge(var.common_tags, { Name = "${var.common_tags["Environment"]} Server SecurityGroup" })

}


================================================
FILE: Lesson-13/outputs.tf
================================================
output "my_server_ip" {
  value = aws_eip.my_static_ip.public_ip
}

output "my_instance_id" {
  value = aws_instance.my_server.id
}

output "my_sg_id" {
  value = aws_security_group.my_server.id
}


================================================
FILE: Lesson-13/prod.tfvars
================================================
# Auto Fill variables for PROD

#File names can be  as:
# terraform.tfvars
# prod.auto.tfvars
# dev.auto.tfvars


region                     = "ca-central-1"
instance_type              = "t2.small"
enable_detailed_monitoring = true

allow_ports = ["80", "443"]

common_tags = {
  Owner       = "Denis Astahov"
  Project     = "Phoenix"
  CostCenter  = "123477"
  Environment = "prod"
}


================================================
FILE: Lesson-13/variables.tf
================================================

variable "region" {
  description = "Please Enter AWS Region to deploy Server"
  type        = string
  default     = "ca-central-1"
}

variable "instance_type" {
  description = "Enter Instance Type"
  type        = string
  default     = "t3.small"
}


variable "allow_ports" {
  description = "List of Ports to open for server"
  type        = list
  default     = ["80", "443", "22", "8080"]
}

variable "enable_detailed_monitoring" {
  type    = bool
  default = false
}


variable "common_tags" {
  description = "Common Tags to apply to all resources"
  type        = map
  default = {
    Owner       = "Denis Astahov"
    Project     = "Phoenix"
    CostCenter  = "12345"
    Environment = "development"
  }
}


================================================
FILE: Lesson-14/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Local Variables
#
# Made by Denis Astahov
#----------------------------------------------------------

provider "aws" {
  region = "ca-central-1"
}


data "aws_region" "current" {}
data "aws_availability_zones" "available" {}

locals {
  full_project_name = "${var.environment}-${var.project_name}"
  project_owner     = "${var.owner} owner of ${var.project_name}"
}


locals {
  country  = "Canada"
  city     = "Deadmonton"
  az_list  = join(",", data.aws_availability_zones.available.names)
  region   = data.aws_region.current.description
  location = "In ${local.region} there are AZ: ${local.az_list}"
}

resource "aws_eip" "my_static_ip" {
  vpc = true # Need to add in new AWS Provider version
  tags = {
    Name       = "Static IP"
    Owner      = var.owner
    Project    = local.full_project_name
    proj_owner = local.project_owner
    city       = local.city
    region_azs = local.az_list
    location   = local.location
  }
}


================================================
FILE: Lesson-14/outputs.tf
================================================
output "my_static_ip" {
  value = aws_eip.my_static_ip.public_ip
}


================================================
FILE: Lesson-14/variables.tf
================================================

variable "environment" {
  default = "DEV"
}

variable "project_name" {
  default = "ANDESA"
}

variable "owner" {
  default = "Denis Astahov"
}


================================================
FILE: Lesson-15/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Execute Local Commands on Computer with Terraform
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" {
  region = "ca-central-1"
}


resource "null_resource" "command1" {
  provisioner "local-exec" {
    command = "echo Terraform START: $(date) >> log.txt"
  }
}



resource "null_resource" "command2" {
  provisioner "local-exec" {
    command = "ping -c 5 www.google.com"
  }
}


resource "null_resource" "command3" {
  provisioner "local-exec" {
    command     = "print('Hello World!')"
    interpreter = ["python", "-c"]
  }
}


resource "null_resource" "command4" {
  provisioner "local-exec" {
    command = "echo $NAME1 $NAME2 $NAME3 >> names.txt"
    environment = {
      NAME1 = "Vasya"
      NAME2 = "Petya"
      NAME3 = "Kolya"
    }
  }
}


resource "aws_instance" "myserver" {
  ami           = "ami-08a9b721ecc5b0a53"
  instance_type = "t3.micro"
  provisioner "local-exec" {
    command = "echo Hello from AWS Instance Creations!"
  }
}


resource "null_resource" "command6" {
  provisioner "local-exec" {
    command = "echo Terraform END: $(date) >> log.txt"
  }
  depends_on = [null_resource.command1, null_resource.command2, null_resource.command3, null_resource.command4, aws_instance.myserver]
}


================================================
FILE: Lesson-16/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Genarate Password
# Store Password in SSM Parameter Store
# Get Password from SSM Parameter Store
# Example of Use Password in RDS
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-central-1"
}

// Generate Password
resource "random_string" "rds_password" {
  length           = 12
  special          = true
  override_special = "!#$&"

  keepers = {
    kepeer1 = var.name
    //keperr2 = var.something
  }
}

// Store Password in SSM Parameter Store
resource "aws_ssm_parameter" "rds_password" {
  name        = "/prod/mysql"
  description = "Master Password for RDS MySQL"
  type        = "SecureString"
  value       = random_string.rds_password.result
}

// Get Password from SSM Parameter Store
data "aws_ssm_parameter" "my_rds_password" {
  name       = "/prod/mysql"
  depends_on = [aws_ssm_parameter.rds_password]
}


// Example of Use Password in RDS
resource "aws_db_instance" "default" {
  identifier           = "prod-rds"
  allocated_storage    = 20
  storage_type         = "gp2"
  engine               = "mysql"
  engine_version       = "5.7"
  instance_class       = "db.t2.micro"
  name                 = "prod"
  username             = "administrator"
  password             = data.aws_ssm_parameter.my_rds_password.value
  parameter_group_name = "default.mysql5.7"
  skip_final_snapshot  = true
  apply_immediately    = true
}


================================================
FILE: Lesson-16/outputs.tf
================================================
output "rds_password" {
  value = data.aws_ssm_parameter.my_rds_password.value
}


================================================
FILE: Lesson-16/variables.tf
================================================
variable "name" {
  default = "petya"
}


================================================
FILE: Lesson-17/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Terraform Conditions and Lookups
#
# Made by Denis Astahov
#----------------------------------------------------------

provider "aws" {
  region = "eu-central-1"
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

// Use of Condition
resource "aws_instance" "my_webserver1" {
  ami = "ami-03a71cec707bfc3d7"
  //instance_type = (var.env == "prod" ? "t2.large" : "t2.micro")
  instance_type = var.env == "prod" ? var.ec2_size["prod"] : var.ec2_size["dev"]

  tags = {
    Name  = "${var.env}-server"
    Owner = var.env == "prod" ? var.prod_onwer : var.noprod_owner
  }
}

// Use of LOOKUP
resource "aws_instance" "my_webserver2" {
  ami           = "ami-03a71cec707bfc3d7"
  instance_type = lookup(var.ec2_size, var.env)

  tags = {
    Name  = "${var.env}-server"
    Owner = var.env == "prod" ? var.prod_onwer : var.noprod_owner
  }
}


// Create Bastion ONLY for if "dev" environment
resource "aws_instance" "my_dev_bastion" {
  count         = var.env == "dev" ? 1 : 0
  ami           = "ami-03a71cec707bfc3d7"
  instance_type = "t2.micro"

  tags = {
    Name = "Bastion Server for Dev-server"
  }
}



resource "aws_security_group" "my_webserver" {
  name   = "Dynamic Security Group"
  vpc_id = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  dynamic "ingress" {
    for_each = lookup(var.allow_port_list, var.env)
    content {
      from_port   = ingress.value
      to_port     = ingress.value
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Dynamic SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-17/variables.tf
================================================
variable "env" {
  default = "dev"
}

variable "prod_onwer" {
  default = "Denis Astahov"
}

variable "noprod_owner" {
  default = "Dyadya Vasya"
}

variable "ec2_size" {
  default = {
    "prod"    = "t3.medium"
    "dev"     = "t3.micro"
    "staging" = "t2.small"
  }
}

variable "allow_port_list" {
  default = {
    "prod" = ["80", "443"]
    "dev"  = ["80", "443", "8080", "22"]
  }
}


================================================
FILE: Lesson-18/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Terraform Loops: Count and For if
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-central-1"
}


resource "aws_iam_user" "user1" {
  name = "pushkin"
}

resource "aws_iam_user" "users" {
  count = length(var.aws_users)
  name  = element(var.aws_users, count.index)
}

#----------------------------------------------------------------

resource "aws_instance" "servers" {
  count         = 3
  ami           = "ami-07ab3281411d31d04"
  instance_type = "t3.micro"
  tags = {
    Name = "Server Number ${count.index + 1}"
  }
}


================================================
FILE: Lesson-18/outputs.tf
================================================
// Print all details
output "created_iam_users_all" {
  value = aws_iam_user.users
}

//Print only ID of users
output "created_iam_users_ids" {
  value = aws_iam_user.users[*].id
}

//Print my Custom output list
output "created_iam_users_custom" {
  value = [
    for user in aws_iam_user.users :
    "Username: ${user.name} has ARN: ${user.arn}"
  ]
}

//Print My Custom output MAP
output "created_iam_users_map" {
  value = {
    for user in aws_iam_user.users :
    user.unique_id => user.id // "AIDA4BML4STW22K74HQFF" : "vasya"
  }
}

// Print List of users with name 4 characters ONLY
output "custom_if_length" {
  value = [
    for x in aws_iam_user.users :
    x.name
    if length(x.name) == 4
  ]
}

#===================================================================

// Print nice MAP of InstanceID: PublicIP
output "server_all" {
  value = {
    for server in aws_instance.servers :
    server.id => server.public_ip // "i-0490f049844513179" = "99.79.58.22"
  }
}


================================================
FILE: Lesson-18/variables.tf
================================================
variable "aws_users" {
  description = "List of IAM Users to create"
  default     = ["vasya", "petya", "kolya", "lena", "masha", "misha", "vova", "donald"]
}


================================================
FILE: Lesson-19/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Provision Resources in Multiply AWS Regions / Accounts
#
# Made by Denis Astahov
#----------------------------------------------------------


provider "aws" { // This is example to use Another AWS Account
  alias      = "ANOTHER_AWS_ACCOUNT"
  region     = "ca-central-1"
  access_key = "xxxxxxxxxxxx"
  secret_key = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"

  assume_role {
    role_arn     = "arn:aws:iam::1234567890:role/RemoteAdministrators"
    session_name = "TERRAFROM_SESSION"
  }
}

provider "aws" {
  region = "ca-central-1"
}

provider "aws" {
  region = "us-east-1"
  alias  = "USA"
}

provider "aws" {
  region = "eu-central-1"
  alias  = "GER"
}
#==================================================================

data "aws_ami" "defaut_latest_ubuntu" {
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }
}

data "aws_ami" "usa_latest_ubuntu" {
  provider    = aws.USA
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }
}

data "aws_ami" "ger_latest_ubuntu" {
  provider    = aws.GER
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
  }
}

#============================================================================
resource "aws_instance" "my_default_server" {
  instance_type = "t3.micro"
  ami           = data.aws_ami.defaut_latest_ubuntu.id
  tags = {
    Name = "Default Server"
  }
}

resource "aws_instance" "my_usa_server" {
  provider      = aws.USA
  instance_type = "t3.micro"
  ami           = data.aws_ami.usa_latest_ubuntu.id
  tags = {
    Name = "USA Server"
  }
}

resource "aws_instance" "my_ger_server" {
  provider      = aws.GER
  instance_type = "t3.micro"
  ami           = data.aws_ami.ger_latest_ubuntu.id
  tags = {
    Name = "GERMANY Server"
  }
}


================================================
FILE: Lesson-20/Layer1-Network/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Remote State on S3
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-central-1"
}

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State
    key    = "dev/network/terraform.tfstate"             // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                 // Region where bycket created
  }
}

#==============================================================

data "aws_availability_zones" "available" {}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  tags = {
    Name = "${var.env}-vpc"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "${var.env}-igw"
  }
}


resource "aws_subnet" "public_subnets" {
  count                   = length(var.public_subnet_cidrs)
  vpc_id                  = aws_vpc.main.id
  cidr_block              = element(var.public_subnet_cidrs, count.index)
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
  tags = {
    Name = "${var.env}-puvlic-${count.index + 1}"
  }
}


resource "aws_route_table" "public_subnets" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "${var.env}-route-public-subnets"
  }
}

resource "aws_route_table_association" "public_routes" {
  count          = length(aws_subnet.public_subnets[*].id)
  route_table_id = aws_route_table.public_subnets.id
  subnet_id      = element(aws_subnet.public_subnets[*].id, count.index)
}

#==============================================================


================================================
FILE: Lesson-20/Layer1-Network/outputs.tf
================================================
output "vpc_id" {
  value = aws_vpc.main.id
}

output "vpc_cidr" {
  value = aws_vpc.main.cidr_block
}

output "public_subnet_ids" {
  value = aws_subnet.public_subnets[*].id
}


================================================
FILE: Lesson-20/Layer1-Network/variables.tf
================================================
variable "vpc_cidr" {
  default = "10.0.0.0/16"
}

variable "env" {
  default = "dev"
}

variable "public_subnet_cidrs" {
  default = [
    "10.0.1.0/24",
    "10.0.2.0/24",
  ]
}


================================================
FILE: Lesson-20/Layer2-Servers/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Remote State on S3
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-central-1"
}

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state" // Bucket where to SAVE Terraform State
    key    = "dev/servers/terraform.tfstate"             // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                 // Region where bycket created
  }
}
#====================================================================


data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "denis-astahov-project-kgb-terraform-state" // Bucket from where to GET Terraform State
    key    = "dev/network/terraform.tfstate"             // Object name in the bucket to GET Terraform state
    region = "us-east-1"                                 // Region where bycket created
  }
}

data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}
#===============================================================


resource "aws_instance" "web_server" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.webserver.id]
  subnet_id              = data.terraform_remote_state.network.outputs.public_subnet_ids[0]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>WebServer with IP: $myip</h2><br>Build by Terraform with Remote State"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF
  tags = {
    Name = "${var.env}-WebServer"
  }
}

resource "aws_security_group" "webserver" {
  name = "WebServer Security Group"
  vpc_id = data.terraform_remote_state.network.outputs.vpc_id

  ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = [data.terraform_remote_state.network.outputs.vpc_cidr]
  }
  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.env}-web-server-sg"
    Owner = "Denis Astahov"
  }
}

#=================================================================


================================================
FILE: Lesson-20/Layer2-Servers/outputs.tf
================================================
output "webserver_sg_id" {
  value = aws_security_group.webserver.id
}

output "web_server_public_ip" {
  value = aws_instance.web_server.public_ip
}


================================================
FILE: Lesson-20/Layer2-Servers/variables.tf
================================================
variable "env" {
  default = "dev"
}


================================================
FILE: Lesson-21/modules/aws_network/main.tf
================================================
#----------------------------------------------------------
# My Terraform
# Provision:
#  - VPC
#  - Internet Gateway
#  - XX Public Subnets
#  - XX Private Subnets
#  - XX NAT Gateways in Public Subnets to give access to Internet from Private Subnets
#
# Made by Denis Astahov. Summer 2019
#----------------------------------------------------------

#==============================================================

data "aws_availability_zones" "available" {}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  tags = {
    Name = "${var.env}-vpc"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "${var.env}-igw"
  }
}

#-------------Public Subnets and Routing----------------------------------------
resource "aws_subnet" "public_subnets" {
  count                   = length(var.public_subnet_cidrs)
  vpc_id                  = aws_vpc.main.id
  cidr_block              = element(var.public_subnet_cidrs, count.index)
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
  tags = {
    Name = "${var.env}-public-${count.index + 1}"
  }
}


resource "aws_route_table" "public_subnets" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "${var.env}-route-public-subnets"
  }
}

resource "aws_route_table_association" "public_routes" {
  count          = length(aws_subnet.public_subnets[*].id)
  route_table_id = aws_route_table.public_subnets.id
  subnet_id      = element(aws_subnet.public_subnets[*].id, count.index)
}


#-----NAT Gateways with Elastic IPs--------------------------


resource "aws_eip" "nat" {
  count   = length(var.private_subnet_cidrs)
  domain = "vpc"
  tags = {
    Name = "${var.env}-nat-gw-${count.index + 1}"
  }
}

resource "aws_nat_gateway" "nat" {
  count         = length(var.private_subnet_cidrs)
  allocation_id = aws_eip.nat[count.index].id
  subnet_id     = element(aws_subnet.public_subnets[*].id, count.index)
  tags = {
    Name = "${var.env}-nat-gw-${count.index + 1}"
  }
}


#--------------Private Subnets and Routing-------------------------

resource "aws_subnet" "private_subnets" {
  count             = length(var.private_subnet_cidrs)
  vpc_id            = aws_vpc.main.id
  cidr_block        = element(var.private_subnet_cidrs, count.index)
  availability_zone = data.aws_availability_zones.available.names[count.index]
  tags = {
    Name = "${var.env}-private-${count.index + 1}"
  }
}

resource "aws_route_table" "private_subnets" {
  count  = length(var.private_subnet_cidrs)
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.nat[count.index].id
  }
  tags = {
    Name = "${var.env}-route-private-subnet-${count.index + 1}"
  }
}

resource "aws_route_table_association" "private_routes" {
  count          = length(aws_subnet.private_subnets[*].id)
  route_table_id = aws_route_table.private_subnets[count.index].id
  subnet_id      = element(aws_subnet.private_subnets[*].id, count.index)
}

#==============================================================


================================================
FILE: Lesson-21/modules/aws_network/outputs.tf
================================================
output "vpc_id" {
  value = aws_vpc.main.id
}

output "vpc_cidr" {
  value = aws_vpc.main.cidr_block
}

output "public_subnet_ids" {
  value = aws_subnet.public_subnets[*].id
}

output "private_subnet_ids" {
  value = aws_subnet.private_subnets[*].id
}


================================================
FILE: Lesson-21/modules/aws_network/variables.tf
================================================
variable "vpc_cidr" {
  default = "10.0.0.0/16"
}

variable "env" {
  default = "dev"
}

variable "public_subnet_cidrs" {
  default = [
    "10.0.1.0/24",
    "10.0.2.0/24",
    "10.0.3.0/24"
  ]
}

variable "private_subnet_cidrs" {
  default = [
    "10.0.11.0/24",
    "10.0.22.0/24",
    "10.0.33.0/24"
  ]
}


================================================
FILE: Lesson-21/modules/aws_security_group/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-21/modules/aws_something/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-21/projectA/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Use Our Terraform Module to create AWS VPC Networks
#
# Made by Denis Astahov. Summer 2019
#----------------------------------------------------------
provider "aws" {
  region = var.region
}

module "vpc-default" {
  source = "../modules/aws_network"
  //  source               = "git@github.com:adv4000/terraform-modules.git//aws_network"
}

module "vpc-dev" {
  source = "../modules/aws_network"
  //  source               = "git@github.com:adv4000/terraform-modules.git//aws_network"
  env                  = "dev"
  vpc_cidr             = "10.100.0.0/16"
  public_subnet_cidrs  = ["10.100.1.0/24", "10.100.2.0/24"]
  private_subnet_cidrs = []
}

module "vpc-prod" {
  source = "../modules/aws_network"
  // source               = "git@github.com:adv4000/terraform-modules.git//aws_network"
  env                  = "prod"
  vpc_cidr             = "10.10.0.0/16"
  public_subnet_cidrs  = ["10.10.1.0/24", "10.10.2.0/24", "10.10.3.0/24"]
  private_subnet_cidrs = ["10.10.11.0/24", "10.10.22.0/24", "10.10.33.0/24"]
}

module "vpc-test" {
  source = "../modules/aws_network"
  // source               = "git@github.com:adv4000/terraform-modules.git//aws_network"
  env                  = "staging"
  vpc_cidr             = "10.10.0.0/16"
  public_subnet_cidrs  = ["10.10.1.0/24", "10.10.2.0/24"]
  private_subnet_cidrs = ["10.10.11.0/24", "10.10.22.0/24"]
}
#===============================================


================================================
FILE: Lesson-21/projectA/outputs.tf
================================================

output "prod_public_subnet_ids" {
  value = module.vpc-prod.public_subnet_ids
}

output "prod_private_subnet_ids" {
  value = module.vpc-prod.private_subnet_ids
}

output "dev_public_subnet_ids" {
  value = module.vpc-dev.public_subnet_ids
}

output "dev_private_subnet_ids" {
  value = module.vpc-dev.private_subnet_ids
}


================================================
FILE: Lesson-21/projectA/variables.tf
================================================
variable "region" {
  description = "AWS Region where to provision VPC Network"
  default     = "eu-north-1"
}


================================================
FILE: Lesson-22/ProjectXYZ/dev/kms/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/network/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/route53/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/s3/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/vpc/applications/app1/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "dev/vpc/applications/app1/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/dev/vpc/applications/app2/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "dev/vpc/applications/app2/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/dev/vpc/databases/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/vpc/ecs_cluster/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/dev/vpc/vpn/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/kms/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/network/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/route53/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/s3/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/vpc/applications/app1/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "prod/vpc/applications/app1/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/prod/vpc/applications/app2/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "prod/vpc/applications/app2/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/prod/vpc/databases/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/vpc/ecs_cluster/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/prod/vpc/vpn/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/kms/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/network/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/route53/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/s3/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/vpc/applications/app1/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "staging/vpc/applications/app1/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/staging/vpc/applications/app2/main.tf
================================================
Future Terraform Code :)

Do it yourself!

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"      // Bucket where to SAVE Terraform State
    key    = "staging/vpc/applications/app2/terraform.tfstate"    // Object name in the bucket to SAVE Terraform State
    region = "us-east-1"                                      // Region where bycket created
  }
}


================================================
FILE: Lesson-22/ProjectXYZ/staging/vpc/databases/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/vpc/ecs_cluster/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/ProjectXYZ/staging/vpc/vpn/main.tf
================================================
Future Terraform Code :)

Do it yourself!


================================================
FILE: Lesson-22/README.MD
================================================
# Terraform Folder Hierarchy for Multi Environment example


Terraform Modules better to keep in GitHub or BitBucket, otherwise in separate folder.
```
.
├── modules
│   ├── aws_network
│   ├── aws_security_group
│   └── aws_something
└── ProjectXYZ
    ├── dev
    │   ├── kms
    │   ├── network
    │   ├── route53
    │   ├── s3
    │   └── vpc
    │       ├── applications
    │       │   ├── app1
    │       │   └── app2
    │       ├── databases
    │       ├── ecs_cluster
    │       └── vpn
    ├── prod
    │   ├── kms
    │   ├── network
    │   ├── route53
    │   ├── s3
    │   └── vpc
    │       ├── applications
    │       │   ├── app1
    │       │   └── app2
    │       ├── databases
    │       ├── ecs_cluster
    │       └── vpn
    └── staging
        ├── kms
        ├── network
        ├── route53
        ├── s3
        └── vpc
            ├── applications
            │   ├── app1
            │   └── app2
            ├── databases
            ├── ecs_cluster
            └── vpn
```

# ----------------------------


================================================
FILE: Lesson-22/modules/aws_network/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-22/modules/aws_security_group/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-22/modules/aws_something/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-23/globalvars/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Global Variables in Remote State on S3
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-central-1"
}

terraform {
  backend "s3" {
    bucket = "denis-astahov-project-kgb-terraform-state"
    key    = "globalvars/terraform.tfstate"
    region = "us-east-1"
  }
}

#==================================================

output "company_name" {
  value = "ANDESA Soft International"
}

output "owner" {
  value = "Denis Astahov"
}

output "tags" {
  value = {
    Project    = "Assembly-2020"
    CostCenter = "R&D"
    Country    = "Canada"
  }
}


================================================
FILE: Lesson-23/stack1/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Use Global Variables from Remote State
#
# Made by Denis Astahov
#----------------------------------------------------------

provider "aws" {
  region = "ca-central-1"
}

data "terraform_remote_state" "global" {
  backend = "s3"
  config = {
    bucket = "denis-astahov-project-kgb-terraform-state"
    key    = "globalvars/terraform.tfstate"
    region = "us-east-1"
  }
}

locals {
  company_name = data.terraform_remote_state.global.outputs.company_name
  owner        = data.terraform_remote_state.global.outputs.owner
  common_tags  = data.terraform_remote_state.global.outputs.tags
}
#---------------------------------------------------------------------

resource "aws_vpc" "vpc1" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name    = "Stack1-VPC1"
    Company = local.company_name
    Owner   = local.owner
  }
}


resource "aws_vpc" "vpc2" {
  cidr_block = "10.0.0.0/16"
  tags       = merge(local.common_tags, { Name = "Stack1-VPC2" })
}


================================================
FILE: Lesson-23/stack2/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Use Global Variables from Remote State
#
# Made by Denis Astahov
#----------------------------------------------------------

provider "aws" {
  region = "ca-central-1"
}

data "terraform_remote_state" "global" {
  backend = "s3"
  config = {
    bucket = "denis-astahov-project-kgb-terraform-state"
    key    = "globalvars/terraform.tfstate"
    region = "us-east-1"
  }
}

locals {
  company_name = data.terraform_remote_state.global.outputs.company_name
  owner        = data.terraform_remote_state.global.outputs.owner
  common_tags  = data.terraform_remote_state.global.outputs.tags
}
#---------------------------------------------------------------------

resource "aws_vpc" "vpc1" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name    = "Stack2-VPC1"
    Company = local.company_name
    Owner   = local.owner
  }
}


resource "aws_vpc" "vpc2" {
  cidr_block = "10.0.0.0/16"
  tags       = merge(local.common_tags, { Name = "Stack2-VPC2" })
}


================================================
FILE: Lesson-24/main.tf
================================================
#----------------------------------------------------------
# My Terraform
#
# Use Terraform with GCP - Google Cloud Platform
#
# Made by Denis Astahov
#
#-----------------------------------------------------------
//export GOOGLE_CLOUD_KEYFILE_JSON="gcp-creds.json"

provider "google" {
  credentials = file("mygcp-creds.json")
  project     = "my-gcp-project-238521"
  region      = "us-west1"
  zone        = "us-west1-c"
}

resource "google_compute_instance" "my_server" {
  name         = "my-gcp-server"
  machine_type = "f1-micro"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"
  }
}


================================================
FILE: Lesson-24/mygcp-creds.json
================================================
// Fake Credentials file, but should look like this
{
  "type": "service_account",
  "project_id": "my-gcp-project-xyzxyz",
  "private_key_id": "d6fasdasfasfasf935f7",
  "private_key": "-----BEGIN PRIVATE KEY-----\nA0xFAafq5visBkpMBDscO5YIQ+w=\n-----END PRIVATE KEY-----\n",
  "client_email": "tf-22-677@my-gcp-project-xyzxyz.iam.gserviceaccount.com",
  "client_id": "34623523523523523",
  "auth_uri": "https://accounts.astahov.com/o/oauth2/auth",
  "token_uri": "https://oauth2.astahov.com/token",
  "auth_provider_x509_cert_url": "https://www.astahov.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.astahov.com/robot/v1/metadata/x509/tf-22-677%40my-gcp-project-xyzxyz.iam.gserviceaccount.com"
}


================================================
FILE: Lesson-25/README.MD
================================================

## Officail Terraform website
https://www.terraform.io/

## A Comprehensive Guide to Terraform - blog
https://blog.gruntwork.io/a-comprehensive-guide-to-terraform-b3d32832baca

## Terraform: Up & Running: Writing Infrastructure as Code - book
https://www.amazon.ca/Terraform-Running-Writing-Infrastructure-Code/dp/1492046906/

## Collection of Terraform AWS modules supported by the community
https://github.com/terraform-aws-modules

## Source Code for All Terraform Lessons
https://github.com/adv4000/terraform-lessons


================================================
FILE: Lesson-26/import-begin.tf
================================================
# terraform import aws_instance.node1 i-0417da3dfcfd6e059
# terraform import aws_instance.node2 i-0b92baf1fa014b3e2
# terraform import aws_instance.node3 i-0ca6e4b3d52437673
# terraform import aws_security_group.nomad sg-0bb76870a0cbc887a

resource "aws_instance" "node1" {

}

resource "aws_instance" "node2" {

}

resource "aws_instance" "node3" {

}

resource "aws_security_group" "nomad" {

}


================================================
FILE: Lesson-26/import-finish.tf
================================================
resource "aws_instance" "node1" {
  ami                    = "ami-0a634ae95e11c6f91"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.nomad.id]
  ebs_optimized          = true
  tags = {
    Name  = "Nomad Ubuntu Node-1"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node2" {
  ami                    = "ami-0a634ae95e11c6f91"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.nomad.id]
  ebs_optimized          = true
  tags = {
    Name  = "Nomad Ubuntu Node-2"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node3" {
  ami                    = "ami-0a634ae95e11c6f91"
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.nomad.id]
  ebs_optimized          = true
  tags = {
    Name  = "Nomad Ubuntu Node-3"
    Owner = "Denis Astahov"
  }
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id
resource "aws_security_group" "nomad" {
  description = "Nomad"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name  = "Nomad Cluster"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-27/main.tf
================================================
# Up to Terraform v0.15.1
# terraform taint aws_instance.node2
#
provider "aws" {
  region = "us-west-1"
}

resource "aws_instance" "node1" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-1"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node2" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-2"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node3" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-3"
    Owner = "Denis Astahov"
  }
  depends_on = [aws_instance.node2]
}


================================================
FILE: Lesson-27-v0.15.2+/main.tf
================================================
# Since Terraform v0.15.2
# terraform apply -replace aws_instance.node2
#
provider "aws" {
  region = "us-west-1"
}

resource "aws_instance" "node1" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-1"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node2" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-2"
    Owner = "Denis Astahov"
  }
}

resource "aws_instance" "node3" {
  ami           = "ami-05655c267c89566dd"
  instance_type = "t3.micro"
  tags = {
    Name  = "Node-3"
    Owner = "Denis Astahov"
  }
  depends_on = [aws_instance.node2]
}


================================================
FILE: Lesson-28/new-prod/config.tf
================================================
provider "aws" {
  region = "us-west-2" // Region where to Create Resources
}

terraform {
  backend "s3" {
    bucket = "adv-it-terraform-state"     // Bucket where to SAVE Terraform State
    key    = "new-prod/terraform.tfstate" // Object name in the bucket to SAVE Terraform State
    region = "us-west-2"                  // Region where bucket is created
  }
}


================================================
FILE: Lesson-28/new-prod/ip-prod.tf
================================================
resource "aws_eip" "prod-ip1" { domain = "vpc" } # Need to add in new AWS Provider version
resource "aws_eip" "prod-ip2" { domain = "vpc" } # Need to add in new AWS Provider version


================================================
FILE: Lesson-28/new-prod/main.tf
================================================
data "aws_availability_zones" "available" {}
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


================================================
FILE: Lesson-28/new-prod/web-prod.tf
================================================
resource "aws_instance" "web-prod" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web-prod.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>PROD WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "PROD WebServer"
    Owner = "Denis Astahov"
  }
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_security_group" "web-prod" {
  name        = "WebServer SG Prod"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-28/new-staging/config.tf
================================================
provider "aws" {
  region = "us-west-2" // Region where to Create Resources
}

terraform {
  backend "s3" {
    bucket = "adv-it-terraform-state"        // Bucket where to SAVE Terraform State
    key    = "new-staging/terraform.tfstate" // Object name in the bucket to SAVE Terraform State
    region = "us-west-2"                     // Region where bucket is created
  }
}


================================================
FILE: Lesson-28/new-staging/ip-stag.tf
================================================
resource "aws_eip" "stag-ip1" { vpc = true } # Need to add in new AWS Provider version
resource "aws_eip" "stag-ip2" { vpc = true } # Need to add in new AWS Provider version


================================================
FILE: Lesson-28/new-staging/main.tf
================================================
data "aws_availability_zones" "available" {}
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


================================================
FILE: Lesson-28/new-staging/web-stag.tf
================================================
resource "aws_instance" "web-stag" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web-stag.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>STAG WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "STAG WebServer"
    Owner = "Denis Astahov"
  }
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_security_group" "web-stag" {
  name        = "WebServer SG Stag"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-28/old-all/config.tf
================================================
provider "aws" {
  region = "us-west-2" // Region where to Create Resources
}

terraform {
  backend "s3" {
    bucket = "adv-it-terraform-state"    // Bucket where to SAVE Terraform State
    key    = "old-all/terraform.tfstate" // Object name in the bucket to SAVE Terraform State
    region = "us-west-2"                 // Region where bucket is created
  }
}


================================================
FILE: Lesson-28/old-all/ip-prod.tf
================================================
resource "aws_eip" "prod-ip1" { domain = "vpc" }  # Need to add in new AWS Provider version
resource "aws_eip" "prod-ip2" { domain = "vpc" }  # Need to add in new AWS Provider version


================================================
FILE: Lesson-28/old-all/ip-stag.tf
================================================
resource "aws_eip" "stag-ip1" { domain = "vpc" }  # Need to add in new AWS Provider version
resource "aws_eip" "stag-ip2" { domain = "vpc" }  # Need to add in new AWS Provider version


================================================
FILE: Lesson-28/old-all/main.tf
================================================
data "aws_availability_zones" "available" {}
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}


resource "aws_eip" "myip-prod" {}
resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id


================================================
FILE: Lesson-28/old-all/web-prod.tf
================================================
resource "aws_instance" "web-prod" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web-prod.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>PROD WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "PROD WebServer"
    Owner = "Denis Astahov"
  }
}

resource "aws_security_group" "web-prod" {
  name        = "WebServer SG Prod"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-28/old-all/web-stag.tf
================================================
resource "aws_instance" "web-stag" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web-stag.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>STAG WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "STAG WebServer"
    Owner = "Denis Astahov"
  }
}

resource "aws_security_group" "web-stag" {
  name        = "WebServer SG Stag"
  description = "My First SecurityGroup"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-29/config.tf
================================================
provider "aws" {
  region = "us-west-2" // Region where to Create Resources
}

terraform {
  backend "s3" {
    bucket = "adv-it-terraform-state" // Bucket where to SAVE Terraform State
    key    = "prod/terraform.tfstate" // Object name in the bucket to SAVE Terraform State
    region = "us-west-2"              // Region where bucket is created
  }
}


================================================
FILE: Lesson-29/main.tf
================================================
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "web" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = "t3.micro"
  vpc_security_group_ids = [aws_security_group.web.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>PROD WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "PROD WebServer - ${terraform.workspace}"
    Owner = "Denis Astahov"
  }
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_security_group" "web" {
  name_prefix = "WebServer SG Prod"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "Web Server SecurityGroup - ${terraform.workspace}"
    Owner = "Denis Astahov"
  }
}

resource "aws_eip" "web" {
  vpc      = true # Need to add in new AWS Provider version
  instance = aws_instance.web.id
  tags = {
    Name  = "PROD WebServer IP - ${terraform.workspace}"
    Owner = "Denis Astahov"
  }
}

####################################
output "web_public_ip" {
  value = aws_eip.web.public_ip
}


================================================
FILE: Lesson-30/main.tf
================================================
data "aws_ami" "latest_amazon_linux" {
  owners      = ["amazon"]
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "web" {
  ami                    = data.aws_ami.latest_amazon_linux.id
  instance_type          = var.server_size
  vpc_security_group_ids = [aws_security_group.web.id]
  user_data              = <<EOF
#!/bin/bash
yum -y update
yum -y install httpd
myip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`
echo "<h2>${var.server_name}-WebServer with IP: $myip</h2><br>Build by Terraform!"  >  /var/www/html/index.html
sudo service httpd start
chkconfig httpd on
EOF

  tags = {
    Name  = "${var.server_name}-WebServer"
    Owner = "Denis Astahov"
  }
}

resource "aws_default_vpc" "default" {} # This need to be added since AWS Provider v4.29+ to get VPC id

resource "aws_security_group" "web" {
  name_prefix = "${var.server_name}-WebServer-SG"
  vpc_id      = aws_default_vpc.default.id # This need to be added since AWS Provider v4.29+ to set VPC id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name  = "${var.server_name}-WebServer SecurityGroup"
    Owner = "Denis Astahov"
  }
}

resource "aws_eip" "web" {
 domain    = "vpc" # Need to add in new AWS Provider version
  instance = aws_instance.web.id
  tags = {
    Name  = "${var.server_name}-WebServer-IP"
    Owner = "Denis Astahov"
  }
}


================================================
FILE: Lesson-30/outputs.tf
================================================
output "web_public_ip" {
  value = aws_eip.web.public_ip
}


================================================
FILE: Lesson-30/variables.tf
================================================
variable "server_name" {
  description = "Name for WebServer"
  type        = string
  default     = "demo"
}


variable "server_size" {
  description = "Server Size for WebServer"
  type        = string
  default     = "t3.micro"
}


================================================
FILE: Lesson-31/main.tf
================================================
provider "aws" {
  region = var.region
}


module "vpc-dev" {
  source   = "./modules/aws_network"
  env      = "dev"
  vpc_cidr = var.vpc_settings["dev"]
}

module "vpc-staging" {
  source   = "./modules/aws_network"
  env      = "stag"
  vpc_cidr = var.vpc_settings["stag"]
}

module "vpc-prod" {
  source   = "./modules/aws_network"
  env      = "prod"
  vpc_cidr = var.vpc_settings["prod"]

  depends_on = [module.vpc-dev, module.vpc-staging] # <--Supported only in Terraform 0.13+
}

module "vpc" {
  count  = 2 # <--Supported only in Terraform 0.13+
  source = "./modules/aws_network"
  env    = "demo-${count.index + 1}"
}

module "vpc_list" {
  for_each = var.vpc_settings # <--Supported only in Terraform 0.13+
  source   = "./modules/aws_network"
  env      = each.key
  vpc_cidr = each.value
}


================================================
FILE: Lesson-31/modules/aws_network/main.tf
================================================
#----------------------------------------------------------
# My Terraform
# Provision:
#  - VPC
#  - Internet Gateway

# Made by Denis Astahov. Summer 2020
#----------------------------------------------------------

#==============================================================

data "aws_availability_zones" "available" {}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  tags = {
    Name = "${var.env}-vpc"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "${var.env}-igw"
  }
}


================================================
FILE: Lesson-31/modules/aws_network/outputs.tf
================================================
output "vpc_id" {
  value = aws_vpc.main.id
}

output "vpc_cidr" {
  value = aws_vpc.main.cidr_block
}


================================================
FILE: Lesson-31/modules/aws_network/variables.tf
================================================
variable "vpc_cidr" {
  default = "10.0.0.0/16"
}

variable "env" {
  default = "demo"
}


================================================
FILE: Lesson-31/modules/aws_security_group/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-31/modules/aws_something/main.tf
================================================
Future Terraform Module :)

Do it yourself!


================================================
FILE: Lesson-31/variables.tf
================================================
variable "vpc_settings" {
  default = {
    prod = "10.10.0.0/16",
    stag = "10.20.0.0/16"
    dev  = "10.30.0.0/16"
  }
}

variable "region" {
  type    = string
  default = "eu-west-1"

  validation {
    condition     = substr(var.region, 0, 3) == "eu-"
    error_message = "Must be an EUROPE AWS Region, like \"eu-\"."
  }
}


================================================
FILE: Lesson-32/main.tf
================================================
provider "aws" { // My Root Account
  region = "us-west-2"
}

provider "aws" { // My DEV Account
  region = "us-west-1"
  alias  = "dev"

  assume_role {
    role_arn = "arn:aws:iam::639130796919:role/TerraformRole"
  }
}

provider "aws" { // My PROD Account
  region = "ca-central-1"
  alias  = "prod"

  assume_role {
    role_arn = "arn:aws:iam::032823347814:role/TerraformRole"
  }
}
#--------------------------------------------------------------

module "servers" {
  source        = "./module_servers"
  instance_type = "t3.small"
  providers = {
    aws.root = aws
    aws.prod = aws.prod
    aws.dev  = aws.dev
  }
}


================================================
FILE: Lesson-32/module_servers/main.tf
================================================
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      configuration_aliases = [
        aws.root,
        aws.prod,
        aws.dev
      ]
    }
  }
}
#----------------------------------------------
data "aws_ami" "latest_ubuntu20_root" {
  provider    = aws.root
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

data "aws_ami" "latest_ubuntu20_prod" {
  provider    = aws.prod
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

data "aws_ami" "latest_ubuntu20_dev" {
  provider    = aws.dev
  owners      = ["099720109477"]
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}


#-------------------------------------------------------------------
resource "aws_instance" "server_root" {
  provider      = aws.root
  ami           = data.aws_ami.latest_ubuntu20_root.id
  instance_type = var.instance_type
  tags          = { Name = "Server-ROOT" }
}

resource "aws_instance" "server_prod" {
  provider      = aws.prod
  ami           = data.aws_ami.latest_ubuntu20_prod.id
  instance_type = var.instance_type
  tags          = { Name = "Server-PROD" }
}

resource "aws_instance" "server_dev" {
  provider      = aws.dev
  ami           = data.aws_ami.latest_ubuntu20_dev.id
  instance_type = var.instance_type
  tags          = { Name = "Server-DEV" }
}


================================================
FILE: Lesson-32/module_servers/variables.tf
================================================
variable "instance_type" {
  default = "t3.micro"
}


================================================
FILE: Lesson-33/iam_groups.tf
================================================
#----------------------------------------------------------
#  Terraform - From Zero to Certified Professional
#
# Create IAM Groups from the map
#
# Made by Denis Astahov
#----------------------------------------------------------

locals {
  group_map_with_key = { for item in var.iam_group_map : item.group_name => item }
}

#===============================================================================
output "iam_group_map_with_key" {
  value = local.group_map_with_key
}

#===============================================================================
resource "aws_iam_group" "this" {
  for_each = local.group_map_with_key
  name     = each.key
}
#===============================================================================


================================================
FILE: Lesson-33/iam_groups_policies.tf
================================================
#----------------------------------------------------------
#  Terraform - From Zero to Certified Professional
#
# Create IAM Group Policies from the map
#
# Made by Denis Astahov
#----------------------------------------------------------

locals {
  group_policy_map_setproduct = [
    for item in var.iam_group_map :
    setproduct([item.group_name], item.group_policies)
  ]

  group_policy_map_setproduct_pairs = [
    for item in var.iam_group_map : [
      for pair in setproduct([item.group_name], item.group_policies) : {
        group_name   = pair[0]
        group_policy = pair[1]
      }
    ]
  ]

  group_policy_map_setproduct_pairs_flatten = flatten(local.group_policy_map_setproduct_pairs)

  group_policy_map_setproduct_pairs_flatten_with_key = {
    for item in local.group_policy_map_setproduct_pairs_flatten :
    "${item.group_name}__${item.group_policy}" => item
  }


  group_map_converted = {
    for flatitem in flatten([
      for item in var.iam_group_map : [
        for pair in setproduct([item.group_name], item.group_policies) : {
          group_name   = pair[0]
          group_policy = pair[1]
        }
      ]
    ]) :
    "${flatitem.group_name}__${flatitem.group_policy}" => flatitem
  }
}

#===============================================================================
output "map_setproduct" {
  value = local.group_policy_map_setproduct
}

output "map_setproduct_pairs" {
  value = local.group_policy_map_setproduct_pairs
}

output "map_setproduct_pairs_flatten" {
  value = local.group_policy_map_setproduct_pairs_flatten
}

output "map_setproduct_pairs_flatten_with_key" {
  value = local.group_policy_map_setproduct_pairs_flatten_with_key
}

output "map_xconverted" {
  value = local.group_map_converted
}
#===============================================================================
resource "aws_iam_group_policy_attachment" "this" {
  for_each   = local.group_map_converted
  group      = each.value.group_name
  policy_arn = each.value.group_policy
  depends_on = [aws_iam_group.this]
}
#===============================================================================


================================================
FILE: Lesson-33/variables.tf
================================================
variable "iam_group_map" {
  default = [
    {
      group_name = "Developers"
      group_policies = [
        "arn:aws:iam::aws:policy/AWSProtonDeveloperAccess",
        "arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess"
      ]
    },
    {
      group_name = "SysOps"
      group_policies = [
        "arn:aws:iam::aws:policy/job-function/SystemAdministrator",
        "arn:aws:iam::aws:policy/job-function/NetworkAdministrator",
        "arn:aws:iam::aws:policy/AWSSecurityHubReadOnlyAccess"
      ]
    },
    {
      group_name     = "Administrators"
      group_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"]
    },
    {
      group_name = "SecurityAuditors"
      group_policies = [
        "arn:aws:iam::aws:policy/SecurityAudit",
        "arn:aws:iam::aws:policy/AWSSecurityHubReadOnlyAccess"
      ]
    }
  ]
}


================================================
FILE: Lesson-34/main.tf
================================================
#----------------------------------------------------------
# Build EC2 Instace using AWS Provider VS AWSCC Provider
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "us-west-2"
}

provider "awscc" {
  region = "us-west-2"
}

variable "tags" {
  description = "Tags to apply"
  type        = map(any)
  default = {
    Owner   = "Denis Astahov"
    Project = "Phoenix"
  }
}


# Reformat Tags from MAP(ANY) to List of MAPS
locals {
  awscc_reformat_tags = [
    for tagKey, tagValue in var.tags :
    {
      key   = tagKey
      value = tagValue
    }
  ]
}

# Create EC2 Instance using AWS Provider
resource "aws_instance" "my_ubuntu" {
  ami           = "ami-06e54d05255faf8f6"
  instance_type = "t3.micro"
  tags = merge(
    {
      Name = "Server-created-by-AWS-Provider"
    },
  var.tags)
}

# Create EC2 Instance using AWSCC Provider
resource "awscc_ec2_instance" "my_ubuntu" {
  image_id      = "ami-06e54d05255faf8f6"
  instance_type = "t3.micro"
  tags = concat(
    [
      {
        key   = "Name",
        value = "Server-created-by-AWSCC-Provider"
      }
    ],
  local.awscc_reformat_tags)
}


================================================
FILE: Lesson-35/deployments/dev/config.tf
================================================
terraform {
  backend "s3" {
    bucket       = "astahov-terraform-remote-state" # Bucket where to SAVE Terraform State
    key          = "dev/terraform.tfstate"          # Object name in the bucket to SAVE Terraform State
    region       = "ca-west-1"                      # Region where bucket created
    use_lockfile = true
  }
}

provider "aws" {
  region = "ca-west-1" # Region where to create resources

  default_tags {
    tags = {
      Owner   = "Denis Astahov"
      Project = "Terraform From Zero to Professional"
    }
  }
}


================================================
FILE: Lesson-35/deployments/dev/main.tf
================================================
module "vpc" {
  source = "../../module-aws-vpc"

  environment = "dev"
  vpc_cidr    = "10.10.0.0/16"
  subnet_cidrs = [
    "10.10.1.0/24",
    "10.10.2.0/24"
  ]
}

module "database" {
  source = "../../module-aws-rds"

  environment               = "dev"
  name                      = "astahov-db"
  engine                    = "mysql"
  engine_version            = "8.4"
  db_cluster_instance_class = "db.t3.micro"
  db_name                   = "mydatabase"
  username                  = "dbadmin"
  multi_az                  = false
  allocated_storage         = 20
  port                      = 1433
  vpc_id                    = module.vpc.vpc_id
  subnet_ids                = module.vpc.subnet_ids
  cidr_blocks               = [module.vpc.vpc_cidr]
  tags = {
    ProjectCode = "5674848"
  }
}


================================================
FILE: Lesson-35/deployments/prod/config.tf
================================================
terraform {
  backend "s3" {
    bucket       = "astahov-terraform-remote-state" # Bucket where to SAVE Terraform State
    key          = "prod/terraform.tfstate"         # Object name in the bucket to SAVE Terraform State
    region       = "ca-west-1"                      # Region where bucket created
    use_lockfile = true
  }
}

provider "aws" {
  region = "ca-west-1" # Region where to create resources

  default_tags {
    tags = {
      Owner   = "Denis Astahov"
      Project = "Terraform From Zero to Professional"
    }
  }
}


================================================
FILE: Lesson-35/deployments/prod/main.tf
================================================
module "vpc" {
  source = "../../module-aws-vpc"

  environment = "prod"
  vpc_cidr    = "10.20.0.0/16"
  subnet_cidrs = [
    "10.20.1.0/24",
    "10.20.2.0/24"
  ]
}

module "database" {
  source = "../../module-aws-rds"

  environment               = "prod"
  name                      = "astahov-db"
  engine                    = "mysql"
  engine_version            = "8.4"
  db_cluster_instance_class = "db.t3.small"
  db_name                   = "mydatabase"
  username                  = "dbadmin"
  multi_az                  = true
  allocated_storage         = 20
  port                      = 1433
  vpc_id                    = module.vpc.vpc_id
  subnet_ids                = module.vpc.subnet_ids
  cidr_blocks               = [module.vpc.vpc_cidr]
}


================================================
FILE: Lesson-35/module-aws-rds/main.tf
================================================
resource "aws_db_instance" "this" {
  identifier              = "${var.environment}-${var.name}"
  allocated_storage       = var.allocated_storage
  max_allocated_storage   = var.max_allocated_storage
  engine                  = var.engine
  engine_version          = var.engine_version
  instance_class          = var.db_cluster_instance_class
  storage_type            = var.storage_type
  username                = var.username
  password                = random_password.rds_password.result
  skip_final_snapshot     = true
  copy_tags_to_snapshot   = true
  vpc_security_group_ids  = [aws_security_group.rds_sg.id]
  db_subnet_group_name    = aws_db_subnet_group.rds_subnet_group.name
  port                    = var.port
  backup_retention_period = var.backup_retention_period
  storage_encrypted       = var.storage_encrypted
  multi_az                = var.multi_az
  db_name                 = var.db_name
  tags                    = var.tags
}

resource "random_password" "rds_password" {
  length  = var.password_length
  special = false
  upper   = true
  lower   = true
  numeric = true
}

resource "aws_security_group" "rds_sg" {
  name        = "${var.environment}-${var.name}-rds-sg"
  vpc_id      = var.vpc_id
  description = "Security group for RDS instance"

  ingress {
    from_port   = var.port
    to_port     = var.port
    protocol    = "tcp"
    cidr_blocks = var.cidr_blocks
  }

  tags = merge(var.tags, { "Name" = "${var.environment}-${var.name}-rds-sg" })
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_db_subnet_group" "rds_subnet_group" {
  name       = "${var.environment}-${var.name}-subnet-group"
  subnet_ids = var.subnet_ids
  tags       = var.tags
  lifecycle {
    create_before_destroy = true
  }
}


resource "aws_ssm_parameter" "rds_instance_host" {
  name  = "/${var.environment}/rds/${var.name}/db_host"
  type  = "String"
  value = aws_db_instance.this.address
  tags  = var.tags
}

resource "aws_ssm_parameter" "rds_instance_port" {
  name  = "/${var.environment}/rds/${var.name}/db_port"
  type  = "String"
  value = aws_db_instance.this.port
  tags  = var.tags
}

resource "aws_ssm_parameter" "rds_instance_username" {
  name  = "/${var.environment}/rds/${var.name}/db_username"
  type  = "String"
  value = aws_db_instance.this.username
  tags  = var.tags
}

resource "aws_ssm_parameter" "rds_instance_password" {
  name  = "/${var.environment}/rds/${var.name}/db_password"
  type  = "SecureString"
  value = random_password.rds_password.result
  tags  = var.tags
}


================================================
FILE: Lesson-35/module-aws-rds/outputs.tf
================================================

output "rds_instance_endpoint" {
  value = aws_db_instance.this.endpoint
}

output "rds_instance_port" {
  value = aws_db_instance.this.port
}

output "rds_instance_username" {
  value = aws_db_instance.this.username
}

output "rds_instance_password_ssm_arn" {
  value = aws_ssm_parameter.rds_instance_password.arn
}

output "rds_instance_identifier" {
  value = aws_db_instance.this.identifier
}


================================================
FILE: Lesson-35/module-aws-rds/variables.tf
================================================
variable "name" {
  description = "A unique identifier for the RDS instance"
  type        = string
}

variable "engine" {
  description = "The name of the database engine to be used for this DB instance"
}

variable "engine_version" {
  description = "The version number of the database engine to use"
}

variable "username" {
  description = "Master username for the database"
}

variable "port" {
  description = "The port on which the DB accepts connections"
}

variable "backup_retention_period" {
  description = "The number of days during which automatic DB snapshots are retained"
  default     = 0
}

variable "storage_encrypted" {
  description = "Specifies whether the DB instance is encrypted"
  default     = true
}

variable "multi_az" {
  description = "Is the RDS MultiAZ or SingleAZ. False for Single AZ and True for MultiAZ"
  default     = false
}

variable "password_length" {
  description = "Length of the randomly generated password"
  default     = 16
}

variable "tags" {
  type    = map(any)
  default = {}
}

variable "environment" {
  description = "The name of the environment"
  type        = string
}

variable "db_cluster_instance_class" {
  description = "The instance type of the RDS instance"
  type        = string
}

variable "storage_type" {
  description = "One of 'standard' (magnetic), 'gp3' (general purpose SSD), or 'io1' (provisioned IOPS SSD). The default is 'io1' if iops is specified, 'standard' if not. Note that this behavior is different from the AWS web console, where the default is 'gp2'."
  type        = string
  default     = "gp3"
}

variable "vpc_id" {
  description = "The ID of the VPC where the RDS Single-AZ/MultiAZ instance will be created"
}

variable "subnet_ids" {
  description = "The IDs of the subnets for the RDS Single-AZ/MultiAZ instance"
  type        = list(string)
}

variable "allocated_storage" {
  description = "Size of the storage"
  default     = 20
}

variable "max_allocated_storage" {
  description = "Enable AutoScaling up to"
  default     = null
}

variable "cidr_blocks" {
  description = "ingress CIDR "
  default     = ["0.0.0.0/0"]
  type        = list(string)
}

variable "db_name" {
  description = "value of the initial database name"
  type        = string
  default     = ""
}


================================================
FILE: Lesson-35/module-aws-vpc/main.tf
================================================
data "aws_availability_zones" "available" {}

resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr
  tags = {
    Name = "${var.environment}-vpc"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "${var.environment}-igw"
  }
}


resource "aws_subnet" "public_subnets" {
  count                   = length(var.subnet_cidrs)
  vpc_id                  = aws_vpc.main.id
  cidr_block              = element(var.subnet_cidrs, count.index)
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
  tags = {
    Name = "${var.environment}-public-${count.index + 1}"
  }
}

resource "aws_route_table" "public_subnets" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  tags = {
    Name = "${var.environment}-route-public-subnets"
  }
}

resource "aws_route_table_association" "public_routes" {
  count          = length(aws_subnet.public_subnets[*].id)
  route_table_id = aws_route_table.public_subnets.id
  subnet_id      = element(aws_subnet.public_subnets[*].id, count.index)
}


================================================
FILE: Lesson-35/module-aws-vpc/outputs.tf
================================================
output "vpc_id" {
  value = aws_vpc.main.id
}

output "vpc_cidr" {
  value = aws_vpc.main.cidr_block
}

output "igw_id" {
  value = aws_internet_gateway.main.id
}

output "subnet_ids" {
  value = aws_subnet.public_subnets[*].id
}


================================================
FILE: Lesson-35/module-aws-vpc/variables.tf
================================================
variable "tags" {
  type    = map(any)
  default = {}
}

variable "environment" {
  description = "The name of the environment"
  type        = string
}

variable "vpc_cidr" {
  default = "10.0.0.0/16"
}


variable "subnet_cidrs" {
  default = [
    "10.0.1.0/24",
    "10.0.2.0/24"
  ]
}


================================================
FILE: Lesson-36/ephemeral/main.tf
================================================
#----------------------------------------------------------
#  Terraform - From Zero to Certified Professional
#
# New way of Secrets management using Ephemeral block
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-west-1"
}

ephemeral "random_password" "masterdb" { #---> Generate Password
  length           = 16
  special          = true
  override_special = "!$%#"
}

resource "aws_ssm_parameter" "masterdb_password" { #---> Store Password
  name             = "/prod/masterdb/password"
  type             = "SecureString"
  value_wo         = ephemeral.random_password.masterdb.result
  value_wo_version = 1
}

ephemeral "aws_ssm_parameter" "masterdb_password" { #---> Get Password
  arn = aws_ssm_parameter.masterdb_password.arn
}

resource "aws_db_instance" "masterdb" { #---> Use Password
  identifier          = "prod-master-db"
  db_name             = "master"
  allocated_storage   = 20
  instance_class      = "db.t3.micro"
  engine              = "mysql"
  engine_version      = "8.0"
  username            = "admin"
  skip_final_snapshot = true
  password_wo         = ephemeral.aws_ssm_parameter.masterdb_password.value
  password_wo_version = 1
}


================================================
FILE: Lesson-36/non-ephemeral/main.tf
================================================
#----------------------------------------------------------
#  Terraform - From Zero to Certified Professional
#
# Old way of Secrets management NOT using Ephemeral block
#
# Made by Denis Astahov
#----------------------------------------------------------
provider "aws" {
  region = "ca-west-1"
}

resource "random_password" "masterdb" { #---> Generate Password
  length           = 16
  special          = true
  override_special = "!$%#"
}

resource "aws_ssm_parameter" "masterdb_password" { #---> Store Password
  name  = "/prod/masterdb/password"
  type  = "SecureString"
  value = random_password.masterdb.result
}

data "aws_ssm_parameter" "masterdb_password" { #---> Get Password
  name = aws_ssm_parameter.masterdb_password.name
}

resource "aws_db_instance" "masterdb" { #---> Use Password
  identifier          = "prod-master-db"
  db_name             = "master"
  allocated_storage   = 20
  instance_class      = "db.t3.micro"
  engine              = "mysql"
  engine_version      = "8.0"
  username            = "admin"
  skip_final_snapshot = true
  password            = data.aws_ssm_parameter.masterdb_password.value
}


================================================
FILE: Lesson-37/action/lambda_function.py
================================================
# ------------------------------------------------------------------------------
# Simple Lambda Function which print payload
#  
# Version  Date               Name            Info
# 1.0      15-October-2025    Denis Astahov   Initial Version
#
# ------------------------------------------------------------------------------

def lambda_handler(event, context):
    print("Incoming Event:")
    print(event)

    message = {
         "message": "Lambda got this Payload:",
         "payload": event
    }

    return message


================================================
FILE: Lesson-37/action/lambda_function.tf
================================================
resource "aws_lambda_function" "this" {
  function_name    = var.name
  description      = "Created by Terraform"
  role             = aws_iam_role.lambda.arn
  runtime          = "python3.13"
  handler          = "lambda_function.lambda_handler"
  filename         = data.archive_file.lambda_zip.output_path
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  tags             = var.tags

  lifecycle {
    action_trigger {
      events  = [after_create, after_update]
      actions = [action.aws_lambda_invoke.this]
    }
  }
}

action "aws_lambda_invoke" "this" {
  config {
    function_name = aws_lambda_function.this.function_name
    payload = jsonencode({
      Message = "Triggered by Terraform Action"
    })
  }
}

# terraform apply -invoke action.aws_lambda_invoke.count
action "aws_lambda_invoke" "count" {
  count = 5
  config {
    function_name = aws_lambda_function.this.function_name
    payload = jsonencode({
      Message      = "Triggered by Terraform Action"
      InvokeNumber = count.index + 1
    })
  }
}


================================================
FILE: Lesson-37/action/main.tf
================================================
# -----Lambda Package
data "archive_file" "lambda_zip" {
  type        = "zip"
  output_path = "lambda_function.zip"
  source {
    filename = "lambda_function.py"
    content  = file("${path.module}/lambda_function.py")
  }
}

#--------------- Lambda IAM Permissions
resource "aws_iam_role" "lambda" {
  name               = "${var.name}-iam-role"
  tags               = var.tags
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": ["lambda.amazonaws.com"]
      },
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy" "lambda_policy" {
  name   = "${var.name}-iam-role-policy"
  tags   = var.tags
  policy = <<EOF
{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid"   : "LoggingPermissions",
              "Effect": "Allow",
              "Action": [
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": [
                  "arn:aws:logs:*:*:*"
              ]
          }
      ]
}
EOF
}

resource "aws_iam_policy_attachment" "lambda" {
  name       = "${var.name}-iam-policy-attachment"
  roles      = [aws_iam_role.lambda.name]
  policy_arn = aws_iam_policy.lambda_policy.arn
}


================================================
FILE: Lesson-37/action/variables.tf
================================================
variable "tags" {
  description = "Tags to apply to Resources"
  default = {
    Owner   = "Denis Astahov"
    Company = "ADV-IT"
    Corp    = "ANDESA Soft International"
  }
}

variable "name" {
  description = "Name to use for Resources"
  default     = "My-LambdaFunction"
}


================================================
FILE: Lesson-37/non-action/lambda_function.py
================================================
# ------------------------------------------------------------------------------
# Simple Lambda Function which print payload
#
# Version  Date               Name            Info
# 1.0      15-October-2025    Denis Astahov   Initial Version
#
# ------------------------------------------------------------------------------

def lambda_handler(event, context):
    print("Incoming Event:")
    print(event)

    message = {
         "message": "Lambda got this Payload:",
         "payload": event
    }

    return message


================================================
FILE: Lesson-37/non-action/lambda_function.tf
================================================
resource "aws_lambda_function" "this" {
  function_name    = var.name
  description      = "Created by Terraform"
  role             = aws_iam_role.lambda.arn
  runtime          = "python3.13"
  handler          = "lambda_function.lambda_handler"
  filename         = data.archive_file.lambda_zip.output_path
  source_code_hash = data.archive_file.lambda_zip.output_base64sha256
  tags             = var.tags
}

resource "null_resource" "invoke_lambda" {
  provisioner "local-exec" {
    command = "aws lambda invoke --function-name ${aws_lambda_function.this.function_name} --cli-binary-format raw-in-base64-out --payload '{\"Message\": \"Triggered by Terraform local-exec\"}' /dev/stdout"
  }

  triggers = {
    source_code_hash = aws_lambda_function.this.source_code_hash
  }

  depends_on = [aws_lambda_function.this]
}



================================================
FILE: Lesson-37/non-action/main.tf
================================================
# -----Lambda Package
data "archive_file" "lambda_zip" {
  type        = "zip"
  output_path = "lambda_function.zip"
  source {
    filename = "lambda_function.py"
    content  = file("${path.module}/lambda_function.py")
  }
}

#--------------- Lambda IAM Permissions
resource "aws_iam_role" "lambda" {
  name               = "${var.name}-iam-role"
  tags               = var.tags
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": ["lambda.amazonaws.com"]
      },
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_policy" "lambda_policy" {
  name   = "${var.name}-iam-role-policy"
  tags   = var.tags
  policy = <<EOF
{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid"   : "LoggingPermissions",
              "Effect": "Allow",
              "Action": [
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": [
                  "arn:aws:logs:*:*:*"
              ]
          }
      ]
}
EOF
}

resource "aws_iam_policy_attachment" "lambda" {
  name       = "${var.name}-iam-policy-attachment"
  roles      = [aws_iam_role.lambda.name]
  policy_arn = aws_iam_policy.lambda_policy.arn
}


================================================
FILE: Lesson-37/non-action/variables.tf
================================================
variable "tags" {
  description = "Tags to apply to Resources"
  default = {
    Owner   = "Denis Astahov"
    Company = "ADV-IT"
    Corp    = "ANDESA Soft International"
  }
}

variable "name" {
  description = "Name to use for Resources"
  default     = "My-LambdaFunction"
}


================================================
FILE: README.md
================================================
<img src="terraform.jpg"><br>

Course covering all features of Terraform v0.12, v0.13, v0.14, v0.15 and  v1.x
# Terraform Lessons by Denis Astahov


### Set AWS Credentials in Windows PowerShell:
```
$env:AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxx"
$env:AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
$env:AWS_DEFAULT_REGION="zzzzzzzzz"
```

### Set AWS Credentials in Linux Shell:
```
export AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxx"
export AWS_SECRET_ACCESS_KEY="yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
export AWS_DEFAULT_REGION="zzzzzzzzz"
```

### Terraform Commands
```
terraform init
terraform plan
terraform apply
terraform destroy

terraform show
terraform output
terraform console
terraform import
terraform taint
```

### Terraform State Commands
```
terraform state show
terraform state list
terraform state pull
terraform state rm
terraform state mv
terraform state push
```
`for x in $(terraform state list | grep xyz); do terraform state mv -state-out=”terraform.tfstate”  $x $x; done`



### Terraform Workspace Commands
```
terraform workspace show
terraform workspace list
terraform workspace new
terraform workspace select
terraform workspace delete
```
`${terraform.workspace}`
Download .txt
gitextract_d5h_045t/

├── .gitignore
├── Lesson-01/
│   └── Lesson-1.tf
├── Lesson-02/
│   └── WebServer.tf
├── Lesson-03/
│   ├── WebServer.tf
│   └── user_data.sh
├── Lesson-04/
│   ├── WebServer.tf
│   └── user_data.sh.tpl
├── Lesson-05/
│   └── DynamicSecurityGroup.tf
├── Lesson-06/
│   ├── WebServer.tf
│   └── user_data.sh.tpl
├── Lesson-07/
│   ├── main.tf
│   ├── outputs.tf
│   └── user_data.sh.tpl
├── Lesson-08/
│   └── main.tf
├── Lesson-09/
│   └── main.tf
├── Lesson-10/
│   └── main.tf
├── Lesson-11-ALB-LaunchTemplate/
│   ├── main.tf
│   └── user_data.sh
├── Lesson-11-ELB-LaunchConfiguration/
│   ├── main.tf
│   └── user_data.sh
├── Lesson-12/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-13/
│   ├── dev.tfvars
│   ├── main.tf
│   ├── outputs.tf
│   ├── prod.tfvars
│   └── variables.tf
├── Lesson-14/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-15/
│   └── main.tf
├── Lesson-16/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-17/
│   ├── main.tf
│   └── variables.tf
├── Lesson-18/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-19/
│   └── main.tf
├── Lesson-20/
│   ├── Layer1-Network/
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── Layer2-Servers/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-21/
│   ├── modules/
│   │   ├── aws_network/
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   └── variables.tf
│   │   ├── aws_security_group/
│   │   │   └── main.tf
│   │   └── aws_something/
│   │       └── main.tf
│   └── projectA/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-22/
│   ├── ProjectXYZ/
│   │   ├── dev/
│   │   │   ├── kms/
│   │   │   │   └── main.tf
│   │   │   ├── network/
│   │   │   │   └── main.tf
│   │   │   ├── route53/
│   │   │   │   └── main.tf
│   │   │   ├── s3/
│   │   │   │   └── main.tf
│   │   │   └── vpc/
│   │   │       ├── applications/
│   │   │       │   ├── app1/
│   │   │       │   │   └── main.tf
│   │   │       │   └── app2/
│   │   │       │       └── main.tf
│   │   │       ├── databases/
│   │   │       │   └── main.tf
│   │   │       ├── ecs_cluster/
│   │   │       │   └── main.tf
│   │   │       └── vpn/
│   │   │           └── main.tf
│   │   ├── prod/
│   │   │   ├── kms/
│   │   │   │   └── main.tf
│   │   │   ├── network/
│   │   │   │   └── main.tf
│   │   │   ├── route53/
│   │   │   │   └── main.tf
│   │   │   ├── s3/
│   │   │   │   └── main.tf
│   │   │   └── vpc/
│   │   │       ├── applications/
│   │   │       │   ├── app1/
│   │   │       │   │   └── main.tf
│   │   │       │   └── app2/
│   │   │       │       └── main.tf
│   │   │       ├── databases/
│   │   │       │   └── main.tf
│   │   │       ├── ecs_cluster/
│   │   │       │   └── main.tf
│   │   │       └── vpn/
│   │   │           └── main.tf
│   │   └── staging/
│   │       ├── kms/
│   │       │   └── main.tf
│   │       ├── network/
│   │       │   └── main.tf
│   │       ├── route53/
│   │       │   └── main.tf
│   │       ├── s3/
│   │       │   └── main.tf
│   │       └── vpc/
│   │           ├── applications/
│   │           │   ├── app1/
│   │           │   │   └── main.tf
│   │           │   └── app2/
│   │           │       └── main.tf
│   │           ├── databases/
│   │           │   └── main.tf
│   │           ├── ecs_cluster/
│   │           │   └── main.tf
│   │           └── vpn/
│   │               └── main.tf
│   ├── README.MD
│   └── modules/
│       ├── aws_network/
│       │   └── main.tf
│       ├── aws_security_group/
│       │   └── main.tf
│       └── aws_something/
│           └── main.tf
├── Lesson-23/
│   ├── globalvars/
│   │   └── main.tf
│   ├── stack1/
│   │   └── main.tf
│   └── stack2/
│       └── main.tf
├── Lesson-24/
│   ├── main.tf
│   └── mygcp-creds.json
├── Lesson-25/
│   └── README.MD
├── Lesson-26/
│   ├── import-begin.tf
│   └── import-finish.tf
├── Lesson-27/
│   └── main.tf
├── Lesson-27-v0.15.2+/
│   └── main.tf
├── Lesson-28/
│   ├── new-prod/
│   │   ├── config.tf
│   │   ├── ip-prod.tf
│   │   ├── main.tf
│   │   └── web-prod.tf
│   ├── new-staging/
│   │   ├── config.tf
│   │   ├── ip-stag.tf
│   │   ├── main.tf
│   │   └── web-stag.tf
│   └── old-all/
│       ├── config.tf
│       ├── ip-prod.tf
│       ├── ip-stag.tf
│       ├── main.tf
│       ├── web-prod.tf
│       └── web-stag.tf
├── Lesson-29/
│   ├── config.tf
│   └── main.tf
├── Lesson-30/
│   ├── main.tf
│   ├── outputs.tf
│   └── variables.tf
├── Lesson-31/
│   ├── main.tf
│   ├── modules/
│   │   ├── aws_network/
│   │   │   ├── main.tf
│   │   │   ├── outputs.tf
│   │   │   └── variables.tf
│   │   ├── aws_security_group/
│   │   │   └── main.tf
│   │   └── aws_something/
│   │       └── main.tf
│   └── variables.tf
├── Lesson-32/
│   ├── main.tf
│   └── module_servers/
│       ├── main.tf
│       └── variables.tf
├── Lesson-33/
│   ├── iam_groups.tf
│   ├── iam_groups_policies.tf
│   └── variables.tf
├── Lesson-34/
│   └── main.tf
├── Lesson-35/
│   ├── deployments/
│   │   ├── dev/
│   │   │   ├── config.tf
│   │   │   └── main.tf
│   │   └── prod/
│   │       ├── config.tf
│   │       └── main.tf
│   ├── module-aws-rds/
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   └── module-aws-vpc/
│       ├── main.tf
│       ├── outputs.tf
│       └── variables.tf
├── Lesson-36/
│   ├── ephemeral/
│   │   └── main.tf
│   └── non-ephemeral/
│       └── main.tf
├── Lesson-37/
│   ├── action/
│   │   ├── lambda_function.py
│   │   ├── lambda_function.tf
│   │   ├── main.tf
│   │   └── variables.tf
│   └── non-action/
│       ├── lambda_function.py
│       ├── lambda_function.tf
│       ├── main.tf
│       └── variables.tf
└── README.md
Download .txt
SYMBOL INDEX (2 symbols across 2 files)

FILE: Lesson-37/action/lambda_function.py
  function lambda_handler (line 9) | def lambda_handler(event, context):

FILE: Lesson-37/non-action/lambda_function.py
  function lambda_handler (line 9) | def lambda_handler(event, context):
Condensed preview — 150 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (121K chars).
[
  {
    "path": ".gitignore",
    "chars": 60,
    "preview": ".terraform/\n*.tfstate\n*.tfstate.backup\n*.terraform.lock.hcl\n"
  },
  {
    "path": "Lesson-01/Lesson-1.tf",
    "chars": 469,
    "preview": "provider \"aws\" {}\n\n\nresource \"aws_instance\" \"my_Ubuntu\" {\n  ami           = \"ami-090f10efc254eaf55\"\n  instance_type = \"t"
  },
  {
    "path": "Lesson-02/WebServer.tf",
    "chars": 1673,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-03/WebServer.tf",
    "chars": 1351,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-03/user_data.sh",
    "chars": 341,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\necho \"<h2>"
  },
  {
    "path": "Lesson-04/WebServer.tf",
    "chars": 1471,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-04/user_data.sh.tpl",
    "chars": 387,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\n\n\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\n\ncat <<E"
  },
  {
    "path": "Lesson-05/DynamicSecurityGroup.tf",
    "chars": 1087,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-06/WebServer.tf",
    "chars": 1799,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-06/user_data.sh.tpl",
    "chars": 411,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\n\n\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\n\ncat <<E"
  },
  {
    "path": "Lesson-07/main.tf",
    "chars": 1728,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Build WebServer during Bootstrap\n#\n# Made"
  },
  {
    "path": "Lesson-07/outputs.tf",
    "chars": 495,
    "preview": "output \"my_web_site_ip\" {\n  description = \"Elatic IP address assigned to our WebSite\"\n  value       = aws_eip.my_static_"
  },
  {
    "path": "Lesson-07/user_data.sh.tpl",
    "chars": 411,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\n\n\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\n\ncat <<E"
  },
  {
    "path": "Lesson-08/main.tf",
    "chars": 1707,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Made by Denis Astahov\n#------------------"
  },
  {
    "path": "Lesson-09/main.tf",
    "chars": 1607,
    "preview": "provider \"aws\" {}\n\n\ndata \"aws_availability_zones\" \"working\" {}\ndata \"aws_caller_identity\" \"current\" {}\ndata \"aws_region\""
  },
  {
    "path": "Lesson-10/main.tf",
    "chars": 1542,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Find Latest AMI id of:\n#    - Ubuntu 18.0"
  },
  {
    "path": "Lesson-11-ALB-LaunchTemplate/main.tf",
    "chars": 4108,
    "preview": "#----------------------------------------------------------\n# Provision Highly Availabe Web in any Region Default VPC\n# "
  },
  {
    "path": "Lesson-11-ALB-LaunchTemplate/user_data.sh",
    "chars": 454,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\n\n\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\n\ncat <<E"
  },
  {
    "path": "Lesson-11-ELB-LaunchConfiguration/main.tf",
    "chars": 3507,
    "preview": "#----------------------------------------------------------\n# Provision Highly Availabe Web in any Region Default VPC\n# "
  },
  {
    "path": "Lesson-11-ELB-LaunchConfiguration/user_data.sh",
    "chars": 454,
    "preview": "#!/bin/bash\nyum -y update\nyum -y install httpd\n\n\nmyip=`curl http://169.254.169.254/latest/meta-data/local-ipv4`\n\ncat <<E"
  },
  {
    "path": "Lesson-12/main.tf",
    "chars": 1836,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Variables\n#\n# Made by Denis Astahov\n#----"
  },
  {
    "path": "Lesson-12/outputs.tf",
    "chars": 197,
    "preview": "output \"my_server_ip\" {\n  value = aws_eip.my_static_ip.public_ip\n}\n\noutput \"my_instance_id\" {\n  value = aws_instance.my_"
  },
  {
    "path": "Lesson-12/variables.tf",
    "chars": 720,
    "preview": "\nvariable \"region\" {\n  description = \"Please Enter AWS Region to deploy Server\"\n  type        = string\n  default     = \""
  },
  {
    "path": "Lesson-13/dev.tfvars",
    "chars": 391,
    "preview": "# Auto Fill variables for DEV\n\n#File names can be  as:\n# terraform.tfvars\n# prod.auto.tfvars\n# dev.auto.tfvars\n\n\nregion "
  },
  {
    "path": "Lesson-13/main.tf",
    "chars": 1845,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Autofill Variables\n#\n# Made by Denis Asta"
  },
  {
    "path": "Lesson-13/outputs.tf",
    "chars": 197,
    "preview": "output \"my_server_ip\" {\n  value = aws_eip.my_static_ip.public_ip\n}\n\noutput \"my_instance_id\" {\n  value = aws_instance.my_"
  },
  {
    "path": "Lesson-13/prod.tfvars",
    "chars": 386,
    "preview": "# Auto Fill variables for PROD\n\n#File names can be  as:\n# terraform.tfvars\n# prod.auto.tfvars\n# dev.auto.tfvars\n\n\nregion"
  },
  {
    "path": "Lesson-13/variables.tf",
    "chars": 720,
    "preview": "\nvariable \"region\" {\n  description = \"Please Enter AWS Region to deploy Server\"\n  type        = string\n  default     = \""
  },
  {
    "path": "Lesson-14/main.tf",
    "chars": 1023,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Local Variables\n#\n# Made by Denis Astahov"
  },
  {
    "path": "Lesson-14/outputs.tf",
    "chars": 67,
    "preview": "output \"my_static_ip\" {\n  value = aws_eip.my_static_ip.public_ip\n}\n"
  },
  {
    "path": "Lesson-14/variables.tf",
    "chars": 146,
    "preview": "\nvariable \"environment\" {\n  default = \"DEV\"\n}\n\nvariable \"project_name\" {\n  default = \"ANDESA\"\n}\n\nvariable \"owner\" {\n  de"
  },
  {
    "path": "Lesson-15/main.tf",
    "chars": 1351,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Execute Local Commands on Computer with T"
  },
  {
    "path": "Lesson-16/main.tf",
    "chars": 1494,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Genarate Password\n# Store Password in SSM"
  },
  {
    "path": "Lesson-16/outputs.tf",
    "chars": 81,
    "preview": "output \"rds_password\" {\n  value = data.aws_ssm_parameter.my_rds_password.value\n}\n"
  },
  {
    "path": "Lesson-16/variables.tf",
    "chars": 40,
    "preview": "variable \"name\" {\n  default = \"petya\"\n}\n"
  },
  {
    "path": "Lesson-17/main.tf",
    "chars": 1848,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Terraform Conditions and Lookups\n#\n# Made"
  },
  {
    "path": "Lesson-17/variables.tf",
    "chars": 391,
    "preview": "variable \"env\" {\n  default = \"dev\"\n}\n\nvariable \"prod_onwer\" {\n  default = \"Denis Astahov\"\n}\n\nvariable \"noprod_owner\" {\n "
  },
  {
    "path": "Lesson-18/main.tf",
    "chars": 674,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Terraform Loops: Count and For if\n#\n# Mad"
  },
  {
    "path": "Lesson-18/outputs.tf",
    "chars": 977,
    "preview": "// Print all details\noutput \"created_iam_users_all\" {\n  value = aws_iam_user.users\n}\n\n//Print only ID of users\noutput \"c"
  },
  {
    "path": "Lesson-18/variables.tf",
    "chars": 159,
    "preview": "variable \"aws_users\" {\n  description = \"List of IAM Users to create\"\n  default     = [\"vasya\", \"petya\", \"kolya\", \"lena\","
  },
  {
    "path": "Lesson-19/main.tf",
    "chars": 2100,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Provision Resources in Multiply AWS Regio"
  },
  {
    "path": "Lesson-20/Layer1-Network/main.tf",
    "chars": 1829,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Remote State on S3\n#\n# Made by Denis Asta"
  },
  {
    "path": "Lesson-20/Layer1-Network/outputs.tf",
    "chars": 177,
    "preview": "output \"vpc_id\" {\n  value = aws_vpc.main.id\n}\n\noutput \"vpc_cidr\" {\n  value = aws_vpc.main.cidr_block\n}\n\noutput \"public_s"
  },
  {
    "path": "Lesson-20/Layer1-Network/variables.tf",
    "chars": 180,
    "preview": "variable \"vpc_cidr\" {\n  default = \"10.0.0.0/16\"\n}\n\nvariable \"env\" {\n  default = \"dev\"\n}\n\nvariable \"public_subnet_cidrs\" "
  },
  {
    "path": "Lesson-20/Layer2-Servers/main.tf",
    "chars": 2538,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Remote State on S3\n#\n# Made by Denis Asta"
  },
  {
    "path": "Lesson-20/Layer2-Servers/outputs.tf",
    "chars": 150,
    "preview": "output \"webserver_sg_id\" {\n  value = aws_security_group.webserver.id\n}\n\noutput \"web_server_public_ip\" {\n  value = aws_in"
  },
  {
    "path": "Lesson-20/Layer2-Servers/variables.tf",
    "chars": 37,
    "preview": "variable \"env\" {\n  default = \"dev\"\n}\n"
  },
  {
    "path": "Lesson-21/modules/aws_network/main.tf",
    "chars": 3175,
    "preview": "#----------------------------------------------------------\n# My Terraform\n# Provision:\n#  - VPC\n#  - Internet Gateway\n#"
  },
  {
    "path": "Lesson-21/modules/aws_network/outputs.tf",
    "chars": 253,
    "preview": "output \"vpc_id\" {\n  value = aws_vpc.main.id\n}\n\noutput \"vpc_cidr\" {\n  value = aws_vpc.main.cidr_block\n}\n\noutput \"public_s"
  },
  {
    "path": "Lesson-21/modules/aws_network/variables.tf",
    "chars": 312,
    "preview": "variable \"vpc_cidr\" {\n  default = \"10.0.0.0/16\"\n}\n\nvariable \"env\" {\n  default = \"dev\"\n}\n\nvariable \"public_subnet_cidrs\" "
  },
  {
    "path": "Lesson-21/modules/aws_security_group/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-21/modules/aws_something/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-21/projectA/main.tf",
    "chars": 1488,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Use Our Terraform Module to create AWS VP"
  },
  {
    "path": "Lesson-21/projectA/outputs.tf",
    "chars": 324,
    "preview": "\noutput \"prod_public_subnet_ids\" {\n  value = module.vpc-prod.public_subnet_ids\n}\n\noutput \"prod_private_subnet_ids\" {\n  v"
  },
  {
    "path": "Lesson-21/projectA/variables.tf",
    "chars": 111,
    "preview": "variable \"region\" {\n  description = \"AWS Region where to provision VPC Network\"\n  default     = \"eu-north-1\"\n}\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/kms/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/network/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/route53/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/s3/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/vpc/applications/app1/main.tf",
    "chars": 388,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/vpc/applications/app2/main.tf",
    "chars": 388,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/vpc/databases/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/vpc/ecs_cluster/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/dev/vpc/vpn/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/kms/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/network/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/route53/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/s3/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/vpc/applications/app1/main.tf",
    "chars": 389,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/vpc/applications/app2/main.tf",
    "chars": 389,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/vpc/databases/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/vpc/ecs_cluster/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/prod/vpc/vpn/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/kms/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/network/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/route53/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/s3/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/vpc/applications/app1/main.tf",
    "chars": 392,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/vpc/applications/app2/main.tf",
    "chars": 392,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n\nterraform {\n  backend \"s3\" {\n    bucket = \"denis-astahov-project-kgb-terrafor"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/vpc/databases/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/vpc/ecs_cluster/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/ProjectXYZ/staging/vpc/vpn/main.tf",
    "chars": 42,
    "preview": "Future Terraform Code :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/README.MD",
    "chars": 1047,
    "preview": "# Terraform Folder Hierarchy for Multi Environment example\n\n\nTerraform Modules better to keep in GitHub or BitBucket, ot"
  },
  {
    "path": "Lesson-22/modules/aws_network/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/modules/aws_security_group/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-22/modules/aws_something/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-23/globalvars/main.tf",
    "chars": 692,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Global Variables in Remote State on S3\n#\n"
  },
  {
    "path": "Lesson-23/stack1/main.tf",
    "chars": 1030,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Use Global Variables from Remote State\n#\n"
  },
  {
    "path": "Lesson-23/stack2/main.tf",
    "chars": 1030,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Use Global Variables from Remote State\n#\n"
  },
  {
    "path": "Lesson-24/main.tf",
    "chars": 677,
    "preview": "#----------------------------------------------------------\n# My Terraform\n#\n# Use Terraform with GCP - Google Cloud Pla"
  },
  {
    "path": "Lesson-24/mygcp-creds.json",
    "chars": 710,
    "preview": "// Fake Credentials file, but should look like this\n{\n  \"type\": \"service_account\",\n  \"project_id\": \"my-gcp-project-xyzxy"
  },
  {
    "path": "Lesson-25/README.MD",
    "chars": 522,
    "preview": "\n## Officail Terraform website\nhttps://www.terraform.io/\n\n## A Comprehensive Guide to Terraform - blog\nhttps://blog.grun"
  },
  {
    "path": "Lesson-26/import-begin.tf",
    "chars": 397,
    "preview": "# terraform import aws_instance.node1 i-0417da3dfcfd6e059\n# terraform import aws_instance.node2 i-0b92baf1fa014b3e2\n# te"
  },
  {
    "path": "Lesson-26/import-finish.tf",
    "chars": 1451,
    "preview": "resource \"aws_instance\" \"node1\" {\n  ami                    = \"ami-0a634ae95e11c6f91\"\n  instance_type          = \"t3.micr"
  },
  {
    "path": "Lesson-27/main.tf",
    "chars": 659,
    "preview": "# Up to Terraform v0.15.1\n# terraform taint aws_instance.node2\n#\nprovider \"aws\" {\n  region = \"us-west-1\"\n}\n\nresource \"aw"
  },
  {
    "path": "Lesson-27-v0.15.2+/main.tf",
    "chars": 668,
    "preview": "# Since Terraform v0.15.2\n# terraform apply -replace aws_instance.node2\n#\nprovider \"aws\" {\n  region = \"us-west-1\"\n}\n\nres"
  },
  {
    "path": "Lesson-28/new-prod/config.tf",
    "chars": 367,
    "preview": "provider \"aws\" {\n  region = \"us-west-2\" // Region where to Create Resources\n}\n\nterraform {\n  backend \"s3\" {\n    bucket ="
  },
  {
    "path": "Lesson-28/new-prod/ip-prod.tf",
    "chars": 182,
    "preview": "resource \"aws_eip\" \"prod-ip1\" { domain = \"vpc\" } # Need to add in new AWS Provider version\nresource \"aws_eip\" \"prod-ip2\""
  },
  {
    "path": "Lesson-28/new-prod/main.tf",
    "chars": 213,
    "preview": "data \"aws_availability_zones\" \"available\" {}\ndata \"aws_ami\" \"latest_amazon_linux\" {\n  owners      = [\"amazon\"]\n  most_re"
  },
  {
    "path": "Lesson-28/new-prod/web-prod.tf",
    "chars": 1206,
    "preview": "resource \"aws_instance\" \"web-prod\" {\n  ami                    = data.aws_ami.latest_amazon_linux.id\n  instance_type     "
  },
  {
    "path": "Lesson-28/new-staging/config.tf",
    "chars": 376,
    "preview": "provider \"aws\" {\n  region = \"us-west-2\" // Region where to Create Resources\n}\n\nterraform {\n  backend \"s3\" {\n    bucket ="
  },
  {
    "path": "Lesson-28/new-staging/ip-stag.tf",
    "chars": 174,
    "preview": "resource \"aws_eip\" \"stag-ip1\" { vpc = true } # Need to add in new AWS Provider version\nresource \"aws_eip\" \"stag-ip2\" { v"
  },
  {
    "path": "Lesson-28/new-staging/main.tf",
    "chars": 213,
    "preview": "data \"aws_availability_zones\" \"available\" {}\ndata \"aws_ami\" \"latest_amazon_linux\" {\n  owners      = [\"amazon\"]\n  most_re"
  },
  {
    "path": "Lesson-28/new-staging/web-stag.tf",
    "chars": 1206,
    "preview": "resource \"aws_instance\" \"web-stag\" {\n  ami                    = data.aws_ami.latest_amazon_linux.id\n  instance_type     "
  },
  {
    "path": "Lesson-28/old-all/config.tf",
    "chars": 364,
    "preview": "provider \"aws\" {\n  region = \"us-west-2\" // Region where to Create Resources\n}\n\nterraform {\n  backend \"s3\" {\n    bucket ="
  },
  {
    "path": "Lesson-28/old-all/ip-prod.tf",
    "chars": 184,
    "preview": "resource \"aws_eip\" \"prod-ip1\" { domain = \"vpc\" }  # Need to add in new AWS Provider version\nresource \"aws_eip\" \"prod-ip2"
  },
  {
    "path": "Lesson-28/old-all/ip-stag.tf",
    "chars": 184,
    "preview": "resource \"aws_eip\" \"stag-ip1\" { domain = \"vpc\" }  # Need to add in new AWS Provider version\nresource \"aws_eip\" \"stag-ip2"
  },
  {
    "path": "Lesson-28/old-all/main.tf",
    "chars": 353,
    "preview": "data \"aws_availability_zones\" \"available\" {}\ndata \"aws_ami\" \"latest_amazon_linux\" {\n  owners      = [\"amazon\"]\n  most_re"
  },
  {
    "path": "Lesson-28/old-all/web-prod.tf",
    "chars": 1101,
    "preview": "resource \"aws_instance\" \"web-prod\" {\n  ami                    = data.aws_ami.latest_amazon_linux.id\n  instance_type     "
  },
  {
    "path": "Lesson-28/old-all/web-stag.tf",
    "chars": 1101,
    "preview": "resource \"aws_instance\" \"web-stag\" {\n  ami                    = data.aws_ami.latest_amazon_linux.id\n  instance_type     "
  },
  {
    "path": "Lesson-29/config.tf",
    "chars": 355,
    "preview": "provider \"aws\" {\n  region = \"us-west-2\" // Region where to Create Resources\n}\n\nterraform {\n  backend \"s3\" {\n    bucket ="
  },
  {
    "path": "Lesson-29/main.tf",
    "chars": 1688,
    "preview": "data \"aws_ami\" \"latest_amazon_linux\" {\n  owners      = [\"amazon\"]\n  most_recent = true\n  filter {\n    name   = \"name\"\n  "
  },
  {
    "path": "Lesson-30/main.tf",
    "chars": 1596,
    "preview": "data \"aws_ami\" \"latest_amazon_linux\" {\n  owners      = [\"amazon\"]\n  most_recent = true\n  filter {\n    name   = \"name\"\n  "
  },
  {
    "path": "Lesson-30/outputs.tf",
    "chars": 59,
    "preview": "output \"web_public_ip\" {\n  value = aws_eip.web.public_ip\n}\n"
  },
  {
    "path": "Lesson-30/variables.tf",
    "chars": 233,
    "preview": "variable \"server_name\" {\n  description = \"Name for WebServer\"\n  type        = string\n  default     = \"demo\"\n}\n\n\nvariable"
  },
  {
    "path": "Lesson-31/main.tf",
    "chars": 805,
    "preview": "provider \"aws\" {\n  region = var.region\n}\n\n\nmodule \"vpc-dev\" {\n  source   = \"./modules/aws_network\"\n  env      = \"dev\"\n  "
  },
  {
    "path": "Lesson-31/modules/aws_network/main.tf",
    "chars": 544,
    "preview": "#----------------------------------------------------------\n# My Terraform\n# Provision:\n#  - VPC\n#  - Internet Gateway\n\n"
  },
  {
    "path": "Lesson-31/modules/aws_network/outputs.tf",
    "chars": 103,
    "preview": "output \"vpc_id\" {\n  value = aws_vpc.main.id\n}\n\noutput \"vpc_cidr\" {\n  value = aws_vpc.main.cidr_block\n}\n"
  },
  {
    "path": "Lesson-31/modules/aws_network/variables.tf",
    "chars": 89,
    "preview": "variable \"vpc_cidr\" {\n  default = \"10.0.0.0/16\"\n}\n\nvariable \"env\" {\n  default = \"demo\"\n}\n"
  },
  {
    "path": "Lesson-31/modules/aws_security_group/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-31/modules/aws_something/main.tf",
    "chars": 44,
    "preview": "Future Terraform Module :)\n\nDo it yourself!\n"
  },
  {
    "path": "Lesson-31/variables.tf",
    "chars": 331,
    "preview": "variable \"vpc_settings\" {\n  default = {\n    prod = \"10.10.0.0/16\",\n    stag = \"10.20.0.0/16\"\n    dev  = \"10.30.0.0/16\"\n "
  },
  {
    "path": "Lesson-32/main.tf",
    "chars": 626,
    "preview": "provider \"aws\" { // My Root Account\n  region = \"us-west-2\"\n}\n\nprovider \"aws\" { // My DEV Account\n  region = \"us-west-1\"\n"
  },
  {
    "path": "Lesson-32/module_servers/main.tf",
    "chars": 1595,
    "preview": "terraform {\n  required_providers {\n    aws = {\n      source = \"hashicorp/aws\"\n      configuration_aliases = [\n        aw"
  },
  {
    "path": "Lesson-32/module_servers/variables.tf",
    "chars": 52,
    "preview": "variable \"instance_type\" {\n  default = \"t3.micro\"\n}\n"
  },
  {
    "path": "Lesson-33/iam_groups.tf",
    "chars": 739,
    "preview": "#----------------------------------------------------------\n#  Terraform - From Zero to Certified Professional\n#\n# Creat"
  },
  {
    "path": "Lesson-33/iam_groups_policies.tf",
    "chars": 2122,
    "preview": "#----------------------------------------------------------\n#  Terraform - From Zero to Certified Professional\n#\n# Creat"
  },
  {
    "path": "Lesson-33/variables.tf",
    "chars": 840,
    "preview": "variable \"iam_group_map\" {\n  default = [\n    {\n      group_name = \"Developers\"\n      group_policies = [\n        \"arn:aws"
  },
  {
    "path": "Lesson-34/main.tf",
    "chars": 1175,
    "preview": "#----------------------------------------------------------\n# Build EC2 Instace using AWS Provider VS AWSCC Provider\n#\n#"
  },
  {
    "path": "Lesson-35/deployments/dev/config.tf",
    "chars": 541,
    "preview": "terraform {\n  backend \"s3\" {\n    bucket       = \"astahov-terraform-remote-state\" # Bucket where to SAVE Terraform State\n"
  },
  {
    "path": "Lesson-35/deployments/dev/main.tf",
    "chars": 804,
    "preview": "module \"vpc\" {\n  source = \"../../module-aws-vpc\"\n\n  environment = \"dev\"\n  vpc_cidr    = \"10.10.0.0/16\"\n  subnet_cidrs = "
  },
  {
    "path": "Lesson-35/deployments/prod/config.tf",
    "chars": 541,
    "preview": "terraform {\n  backend \"s3\" {\n    bucket       = \"astahov-terraform-remote-state\" # Bucket where to SAVE Terraform State\n"
  },
  {
    "path": "Lesson-35/deployments/prod/main.tf",
    "chars": 762,
    "preview": "module \"vpc\" {\n  source = \"../../module-aws-vpc\"\n\n  environment = \"prod\"\n  vpc_cidr    = \"10.20.0.0/16\"\n  subnet_cidrs ="
  },
  {
    "path": "Lesson-35/module-aws-rds/main.tf",
    "chars": 2535,
    "preview": "resource \"aws_db_instance\" \"this\" {\n  identifier              = \"${var.environment}-${var.name}\"\n  allocated_storage    "
  },
  {
    "path": "Lesson-35/module-aws-rds/outputs.tf",
    "chars": 398,
    "preview": "\noutput \"rds_instance_endpoint\" {\n  value = aws_db_instance.this.endpoint\n}\n\noutput \"rds_instance_port\" {\n  value = aws_"
  },
  {
    "path": "Lesson-35/module-aws-rds/variables.tf",
    "chars": 2273,
    "preview": "variable \"name\" {\n  description = \"A unique identifier for the RDS instance\"\n  type        = string\n}\n\nvariable \"engine\""
  },
  {
    "path": "Lesson-35/module-aws-vpc/main.tf",
    "chars": 1155,
    "preview": "data \"aws_availability_zones\" \"available\" {}\n\nresource \"aws_vpc\" \"main\" {\n  cidr_block = var.vpc_cidr\n  tags = {\n    Nam"
  },
  {
    "path": "Lesson-35/module-aws-vpc/outputs.tf",
    "chars": 230,
    "preview": "output \"vpc_id\" {\n  value = aws_vpc.main.id\n}\n\noutput \"vpc_cidr\" {\n  value = aws_vpc.main.cidr_block\n}\n\noutput \"igw_id\" "
  },
  {
    "path": "Lesson-35/module-aws-vpc/variables.tf",
    "chars": 289,
    "preview": "variable \"tags\" {\n  type    = map(any)\n  default = {}\n}\n\nvariable \"environment\" {\n  description = \"The name of the envir"
  },
  {
    "path": "Lesson-36/ephemeral/main.tf",
    "chars": 1233,
    "preview": "#----------------------------------------------------------\n#  Terraform - From Zero to Certified Professional\n#\n# New w"
  },
  {
    "path": "Lesson-36/non-ephemeral/main.tf",
    "chars": 1136,
    "preview": "#----------------------------------------------------------\n#  Terraform - From Zero to Certified Professional\n#\n# Old w"
  },
  {
    "path": "Lesson-37/action/lambda_function.py",
    "chars": 526,
    "preview": "# ------------------------------------------------------------------------------\n# Simple Lambda Function which print pa"
  },
  {
    "path": "Lesson-37/action/lambda_function.tf",
    "chars": 1052,
    "preview": "resource \"aws_lambda_function\" \"this\" {\n  function_name    = var.name\n  description      = \"Created by Terraform\"\n  role"
  },
  {
    "path": "Lesson-37/action/main.tf",
    "chars": 1347,
    "preview": "# -----Lambda Package\ndata \"archive_file\" \"lambda_zip\" {\n  type        = \"zip\"\n  output_path = \"lambda_function.zip\"\n  s"
  },
  {
    "path": "Lesson-37/action/variables.tf",
    "chars": 279,
    "preview": "variable \"tags\" {\n  description = \"Tags to apply to Resources\"\n  default = {\n    Owner   = \"Denis Astahov\"\n    Company ="
  },
  {
    "path": "Lesson-37/non-action/lambda_function.py",
    "chars": 524,
    "preview": "# ------------------------------------------------------------------------------\n# Simple Lambda Function which print pa"
  },
  {
    "path": "Lesson-37/non-action/lambda_function.tf",
    "chars": 826,
    "preview": "resource \"aws_lambda_function\" \"this\" {\n  function_name    = var.name\n  description      = \"Created by Terraform\"\n  role"
  },
  {
    "path": "Lesson-37/non-action/main.tf",
    "chars": 1347,
    "preview": "# -----Lambda Package\ndata \"archive_file\" \"lambda_zip\" {\n  type        = \"zip\"\n  output_path = \"lambda_function.zip\"\n  s"
  },
  {
    "path": "Lesson-37/non-action/variables.tf",
    "chars": 279,
    "preview": "variable \"tags\" {\n  description = \"Tags to apply to Resources\"\n  default = {\n    Owner   = \"Denis Astahov\"\n    Company ="
  },
  {
    "path": "README.md",
    "chars": 1183,
    "preview": "<img src=\"terraform.jpg\"><br>\n\nCourse covering all features of Terraform v0.12, v0.13, v0.14, v0.15 and  v1.x\n# Terrafor"
  }
]

About this extraction

This page contains the full source code of the adv4000/terraform-lessons GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 150 files (101.7 KB), approximately 33.5k tokens, and a symbol index with 2 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!