diff --git a/01/homework.md b/01/homework.md new file mode 100644 index 00000000..b09c14ce --- /dev/null +++ b/01/homework.md @@ -0,0 +1,66 @@ +### Версия установленного terraform + +![Screenshot 2024-10-30 155047](https://github.com/user-attachments/assets/ffd8717e-d155-40ce-831e-61ec8efb55aa) + +## Задание 1 + +### Пункт 2 + +Логины,пароли,ключи,токены итд, судя по gitignore, будем хранить в personal.auto.tfvars. А так-же сгенерированные терраформом пароли могут проскальзывать в .tfstate файлах. + +### Пункт 3 + +Cекретное содержимое созданного ресурса random_password + +"result": "9I8fijfVDWdzfB3R", + +### Пункт 4 + +"1nginx" name не может начинаться с цифр + +Переменная random_password.random_string_FAKE.resulT написана с ошибками. мы не задавали имя random_string_FAKE в resource "random_password", а так-же в переменной resulT допущена синтаксическая ошибка. Правильное написание переменных наглядно можно увидеть в файле terraform.tfstate в виде ключей и значений + +resource "docker_container" не сможет найти image, который мы указали ему в качесте переменных из resource "docker_image", ведь мы его не раскомментировали (он выше 29 строки). Плюсом ко всему в resource "docker_image" следует указать имя, которое мы указали в качестве переменной в resource "docker_container" + +### Пункт 5 + +[Исправленный код (ссылка на github)](https://github.com/gaidarvu/ter-homeworks/blob/main/01/src/main.tf) + +![alt text](image.png) + +### Пункт 6 + +При выполнении команды terraform apply с флагом -auto-approve может привести к неожиданным последствиям. Этот флаг автоматически одобряет все изменения, которые terraform собирается внести. Выполняя команду с данным флагом, мы должны чётко понимать какие изменения последуют после выполнения кода. В противном случае есть большая вероятность случайных изменений или удалений ресурсов. В любом случае лучше применять конфигурацию с подтверждением ручного ввода без флага -auto-approve или перед выполнением кода сделать terraform plan + +Данный флаг может быть полезен тем, что убирает необходимость ручного подтверждения, команда будет выполняться быстрее. Это полезно в разработческих средах или в тестовых пайплайнах, где скорость является важным фактором. В некоторых случаях развертывание может быть заранее запланировано и протестировано. Использование -auto-approve может быть частью четкого процесса, где все изменения уже были проверены, и нет необходимости в дополнительных подтверждениях. + +![alt text](image-1.png) + +### Пункт 7 + +Cодержимое файла terraform.tfstate + +```js +{ + "version": 4, + "terraform_version": "1.9.8", + "serial": 11, + "lineage": "8eb799a7-e4ab-2dad-4396-1f2911fa3e5f", + "outputs": {}, + "resources": [], + "check_results": null +} +``` + +### Пункт 8 + +В resource "docker_image" мы явно указали значение keep_locally = true. Это значит что после завершения работы с ресурсом имадж Docker должен оставаться на локальной машине, а не удаляться автоматически. + +Цитата от провайдера docker: +>keep_locally (Boolean) If true, then the Docker image won't be deleted on destroy operation. If this is false, it will delete the image from the docker local storage on destroy operation. + +## Задание 2 + +[Финальный код main.tf (ссылка на github)](https://github.com/gaidarvu/ter-homeworks/blob/main/01/src_ycloud/main.tf) + +![alt text](image-3.png) \ No newline at end of file diff --git a/01/image-1.png b/01/image-1.png new file mode 100644 index 00000000..c036b734 Binary files /dev/null and b/01/image-1.png differ diff --git a/01/image-3.png b/01/image-3.png new file mode 100644 index 00000000..2f570b26 Binary files /dev/null and b/01/image-3.png differ diff --git a/01/image.png b/01/image.png new file mode 100644 index 00000000..4a33149c Binary files /dev/null and b/01/image.png differ diff --git a/01/src/.terraformrc b/01/src/.terraformrc index 9bc77282..17415e3e 100644 --- a/01/src/.terraformrc +++ b/01/src/.terraformrc @@ -6,4 +6,4 @@ provider_installation { direct { exclude = ["registry.terraform.io/*/*"] } -} \ No newline at end of file +} diff --git a/01/src/main.tf b/01/src/main.tf index a5fd2f46..9f9d8a6d 100644 --- a/01/src/main.tf +++ b/01/src/main.tf @@ -5,7 +5,7 @@ terraform { version = "~> 3.0.1" } } - required_version = "~>1.8.4" /*Многострочный комментарий. + required_version = ">=1.8.4" /*Многострочный комментарий. Требуемая версия terraform */ } provider "docker" {} @@ -20,19 +20,19 @@ resource "random_password" "random_string" { min_numeric = 1 } -/* -resource "docker_image" { +resource "docker_image" "nginx" { name = "nginx:latest" keep_locally = true } -resource "docker_container" "1nginx" { +resource "docker_container" "nginx" { image = docker_image.nginx.image_id - name = "example_${random_password.random_string_FAKE.resulT}" + name = "hello_world" + # name = "example_${random_password.random_string.result}" ports { internal = 80 external = 9090 } } -*/ + diff --git a/01/src_ycloud/.gitignore b/01/src_ycloud/.gitignore new file mode 100644 index 00000000..df429d22 --- /dev/null +++ b/01/src_ycloud/.gitignore @@ -0,0 +1,12 @@ +# Local .terraform directories and files +**/.terraform/* +.terraform* + +!.terraformrc + +# .tfstate files +*.tfstate +*.tfstate.* + +# own secret vars store. +personal.auto.tfvars \ No newline at end of file diff --git a/01/src_ycloud/main.tf b/01/src_ycloud/main.tf new file mode 100644 index 00000000..00691486 --- /dev/null +++ b/01/src_ycloud/main.tf @@ -0,0 +1,54 @@ +terraform { + required_providers { + docker = { + source = "kreuzwerker/docker" + version = "~> 3.0.1" + } + } + required_version = ">=1.8.4" +} +provider "docker" { + host = "ssh://gaidar@130.193.44.141:22" + ssh_opts = ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"] + /* + авторизация по ключу, ключ прибит в ~/.ssh/id_rsa + на облачной тачке пользователь добавлен в группу docker + */ +} + +resource "random_password" "root_pwd" { + length = 16 + special = false + min_upper = 1 + min_lower = 1 + min_numeric = 1 +} + +resource "random_password" "user_pwd" { + length = 16 + special = false + min_upper = 1 + min_lower = 1 + min_numeric = 1 +} + +resource "docker_image" "mysql" { + name = "mysql:8" +} + +resource "docker_container" "mysql" { + image = docker_image.mysql.image_id + name = "mysql" + env = [ + "MYSQL_ROOT_PASSWORD=${random_password.root_pwd.result}", + "MYSQL_DATABASE=wordpress", + "MYSQL_USER=wordpress", + "MYSQL_PASSWORD=${random_password.user_pwd.result}", + "MYSQL_ROOT_HOST=%" + ] + + ports { + internal = 3306 + external = 3306 + } +} diff --git a/02/homework.md b/02/homework.md new file mode 100644 index 00000000..8655b9de --- /dev/null +++ b/02/homework.md @@ -0,0 +1,33 @@ +## Задание 1 + +cloud_id и folder_id обозначил в personal.auto.tfvars + +В boot_disk всё-же указал размер и тип создаваемого диска, чтобы не создавал по умолчанию. + +В platform_id = "standart-v4" явно допущена ошибка. Правильно standard. Опции v4 пока не существует. +На всех платформах в яндекс облаке можно выбрать минимум 2 ядра vCPU +А так-же производительность vCPU в 5% обеспечивается только на standard-v1 и standard-v2 +С точки зрения экономии выбираем standard-v2 +Конечная запись будет выглядеть platform_id = "standard-v2" +А параметры производительности будут такими: +```js + resources { + cores = 2 + memory = 1 + core_fraction = 5 + } +``` + +Для авторизации закомментировал token и сгенерировал authorized_key.json + +![alt text](image-2.png) + +![alt text](image-3.png) + +Параметры preemptible = true и core_fraction=5 в процессе обучения могут пригодиться для экономии средств, которых должно хватить на весь срок обучения. Урезая параметры процессора и выставляя прерывание виртуалке мы получаем идеальный вариант для обучения. Делать постоянные terraform apply и затем через какое-то время terraform destroy на производительных тачках расточительно + +## Задание 4 + +![alt text](image.png) + +[Финальный код (ссылка на github repo)](https://github.com/gaidarvu/ter-homeworks/tree/main/02/src) diff --git a/02/image-2.png b/02/image-2.png new file mode 100644 index 00000000..a58fde3d Binary files /dev/null and b/02/image-2.png differ diff --git a/02/image-3.png b/02/image-3.png new file mode 100644 index 00000000..cbcfe261 Binary files /dev/null and b/02/image-3.png differ diff --git a/02/image.png b/02/image.png new file mode 100644 index 00000000..7f1d4a9b Binary files /dev/null and b/02/image.png differ diff --git a/02/src/locals.tf b/02/src/locals.tf index e69de29b..9e6aead8 100644 --- a/02/src/locals.tf +++ b/02/src/locals.tf @@ -0,0 +1,11 @@ +locals { + + test = [ + { + "vm-web" = "netology-${var.vpc_name}-${var.vm_web_yandex_compute_instance_platform_id}-${var.vm_web_zone}-web" + }, + { + "vm-db" = "netology-${var.vpc_name}-${var.vm_db_yandex_compute_instance_platform_id}-${var.vm_db_zone}-db" + }, + ] +} diff --git a/02/src/main.tf b/02/src/main.tf index 49baf600..c9ab0b31 100644 --- a/02/src/main.tf +++ b/02/src/main.tf @@ -3,39 +3,81 @@ resource "yandex_vpc_network" "develop" { } resource "yandex_vpc_subnet" "develop" { name = var.vpc_name - zone = var.default_zone + zone = var.vm_web_zone network_id = yandex_vpc_network.develop.id v4_cidr_blocks = var.default_cidr } - +resource "yandex_vpc_subnet" "develop-b" { + name = var.subnet_name_b + zone = var.vm_db_zone + network_id = yandex_vpc_network.develop.id + v4_cidr_blocks = var.default_cidr_for_b +} data "yandex_compute_image" "ubuntu" { - family = "ubuntu-2004-lts" + family = var.vm_web_yandex_compute_image } + resource "yandex_compute_instance" "platform" { - name = "netology-develop-platform-web" - platform_id = "standart-v4" + # name = var.vm_web_yandex_compute_instance_name + name = local.test[0].vm-web + hostname = local.test[0].vm-web + platform_id = var.vm_web_yandex_compute_instance_platform_id + zone = var.vm_web_zone resources { - cores = 1 - memory = 1 - core_fraction = 5 + cores = var.vm_resources.web.cores + memory = var.vm_resources.web.memory + core_fraction = var.vm_resources.web.core_fraction } boot_disk { initialize_params { image_id = data.yandex_compute_image.ubuntu.image_id + type = var.vm_resources.web.type + size = var.vm_resources.web.size } } scheduling_policy { - preemptible = true + preemptible = var.vm_web_scheduling_policy } network_interface { subnet_id = yandex_vpc_subnet.develop.id - nat = true + nat = var.vm_web_network_interface } metadata = { - serial-port-enable = 1 - ssh-keys = "ubuntu:${var.vms_ssh_root_key}" + serial-port-enable = var.metadata.serial-port-enable + ssh-keys = var.metadata.ssh-keys } +} +resource "yandex_compute_instance" "platform2" { + # name = var.vm_db_yandex_compute_instance_name + name = local.test[1].vm-db + hostname = local.test[1].vm-db + platform_id = var.vm_db_yandex_compute_instance_platform_id + zone = var.vm_db_zone + resources { + cores = var.vm_resources.db.cores + memory = var.vm_resources.db.memory + core_fraction = var.vm_resources.db.core_fraction + } + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.image_id + type = var.vm_resources.db.type + size = var.vm_resources.db.size + } + } + scheduling_policy { + preemptible = var.vm_db_scheduling_policy + } + network_interface { + subnet_id = yandex_vpc_subnet.develop-b.id + nat = var.vm_db_network_interface + } + + metadata = { + serial-port-enable = var.metadata.serial-port-enable + ssh-keys = var.metadata.ssh-keys + } } diff --git a/02/src/outputs.tf b/02/src/outputs.tf index e69de29b..b4797823 100644 --- a/02/src/outputs.tf +++ b/02/src/outputs.tf @@ -0,0 +1,7 @@ +output "test" { + + value = [ + { vm-web = ["instance name ${yandex_compute_instance.platform.name}", "external ip ${yandex_compute_instance.platform.network_interface[0].nat_ip_address}", "fqdn ${yandex_compute_instance.platform.fqdn}"] }, + { vm-db = ["instance name ${yandex_compute_instance.platform2.name}", "external ip ${yandex_compute_instance.platform2.network_interface[0].nat_ip_address}", "fqdn ${yandex_compute_instance.platform2.fqdn}"] } + ] +} \ No newline at end of file diff --git a/02/src/providers.tf b/02/src/providers.tf index fae4dc37..1482db44 100644 --- a/02/src/providers.tf +++ b/02/src/providers.tf @@ -4,7 +4,7 @@ terraform { source = "yandex-cloud/yandex" } } - required_version = ">=1.5" + required_version = "<=1.9.8" } provider "yandex" { @@ -13,4 +13,4 @@ provider "yandex" { folder_id = var.folder_id zone = var.default_zone service_account_key_file = file("~/.authorized_key.json") -} +} \ No newline at end of file diff --git a/02/src/variables.tf b/02/src/variables.tf index 8e1bb4f1..eba10acc 100644 --- a/02/src/variables.tf +++ b/02/src/variables.tf @@ -28,11 +28,96 @@ variable "vpc_name" { description = "VPC network & subnet name" } +variable "vm_web_yandex_compute_image"{ + type = string + default = "ubuntu-2004-lts" + description = "Image name for VM" +} -###ssh vars +variable "vm_web_yandex_compute_instance_name" { + type = string + default = "netology-develop-platform-web" + description = "Name and hostname for VM" +} + +variable "vm_web_yandex_compute_instance_platform_id" { + type = string + default = "standard-v2" + description = "Platform type of VM" +} + +# variable "vm_web_resources" { +# type = object({ cores = number, memory = number, core_fraction = number }) +# default = { cores = 2, memory = 1, core_fraction = 5 } +# description = "Resources of yandex compute image" +# } + +# variable "vm_web_initialize_params" { +# type = object({ type = string, size = number }) +# default = { type = "network-hdd", size = 10 } +# description = "Params for yandex VM disk" +# } + +variable "vm_web_scheduling_policy" { + type = bool + default = true +} +variable "vm_web_network_interface" { + type = bool + default = true +} -variable "vms_ssh_root_key" { +variable "vm_web_zone" { type = string - default = "" - description = "ssh-keygen -t ed25519" + default = "ru-central1-a" + description = "https://cloud.yandex.ru/docs/overview/concepts/geo-scope" +} + + +# provider "yandex" { +# token = "auth_token_here" +# cloud_id = "b1gebvnp4l01pjj94h8g" +# folder_id = "b1gll1nj110e9uebdvrq" +# zone = "ru-central1-a" +# } + +variable "vm_resources" { + type = map(object({ + cores = number + memory = number + core_fraction = number + type = string + size = number + })) + default = { + "web" = { + cores = 2 + memory = 1 + core_fraction = 5 + type = "network-hdd" + size = 10 + }, + "db" = { + cores = 2 + memory = 2 + core_fraction = 20 + type = "network-hdd" + size = 10 + } + } +} + + +###ssh vars + +# variable "vms_ssh_root_key" { +# type = string +# default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEF1s4DWFbHRG8VeGu9PXvAdkLp7SPsbklk63Soan+RC" +# description = "ssh-keygen -t ed25519" +# } + +variable "metadata" { + type = object({ serial-port-enable = number, ssh-keys = string }) + default = { serial-port-enable = 1, ssh-keys = "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEF1s4DWFbHRG8VeGu9PXvAdkLp7SPsbklk63Soan+RC" } + description = "Common ssh params" } diff --git a/02/src/vms_platform.tf b/02/src/vms_platform.tf new file mode 100644 index 00000000..f81f3719 --- /dev/null +++ b/02/src/vms_platform.tf @@ -0,0 +1,57 @@ +###cloud vars + +variable "default_cidr_for_b" { + type = list(string) + default = ["10.0.2.0/24"] + description = "https://cloud.yandex.ru/docs/vpc/operations/subnet-create" +} +variable "subnet_name_b" { + type = string + default = "develop-b" + description = "VPC network & subnet name" +} + +variable "vm_db_yandex_compute_image"{ + type = string + default = "ubuntu-2004-lts" + description = "Image name for VM" +} + +variable "vm_db_yandex_compute_instance_name" { + type = string + default = "netology-develop-platform-db" + description = "Name and hostname for VM" +} + +variable "vm_db_yandex_compute_instance_platform_id" { + type = string + default = "standard-v2" + description = "Platform type of VM" +} + +# variable "vm_db_resources" { +# type = object({ cores = number, memory = number, core_fraction = number }) +# default = { cores = 2, memory = 2, core_fraction = 20 } +# description = "Resources of yandex compute image" +# } + +# variable "vm_db_initialize_params" { +# type = object({ type = string, size = number }) +# default = { type = "network-hdd", size = 10 } +# description = "Params for yandex VM disk" +# } + +variable "vm_db_scheduling_policy" { + type = bool + default = true +} +variable "vm_db_network_interface" { + type = bool + default = true +} + +variable "vm_db_zone" { + type = string + default = "ru-central1-b" + description = "https://cloud.yandex.ru/docs/overview/concepts/geo-scope" +} diff --git a/03/homework.md b/03/homework.md new file mode 100644 index 00000000..82798df8 --- /dev/null +++ b/03/homework.md @@ -0,0 +1,9 @@ +## Задание 1 + +![alt text](image.png) + +## Задание 4 + +![alt text](image-1.png) + +[Финальный код (ссылка на github repo)](https://github.com/gaidarvu/ter-homeworks/tree/terraform-03/03/src) diff --git a/03/image-1.png b/03/image-1.png new file mode 100644 index 00000000..fbc25649 Binary files /dev/null and b/03/image-1.png differ diff --git a/03/image.png b/03/image.png new file mode 100644 index 00000000..3039d3a0 Binary files /dev/null and b/03/image.png differ diff --git a/03/src/ansible.tf b/03/src/ansible.tf new file mode 100644 index 00000000..ceb49052 --- /dev/null +++ b/03/src/ansible.tf @@ -0,0 +1,10 @@ +resource "local_file" "hosts_templatefile" { + content = templatefile("${path.module}/hosts.tftpl", + { + webservers = yandex_compute_instance.web + databases = yandex_compute_instance.db + storage = length(yandex_compute_instance.storage) > 0 ? [yandex_compute_instance.storage] : [] + }) + + filename = "${abspath(path.module)}/hosts.cfg" +} \ No newline at end of file diff --git a/03/src/count-vm.tf b/03/src/count-vm.tf new file mode 100644 index 00000000..54907e66 --- /dev/null +++ b/03/src/count-vm.tf @@ -0,0 +1,32 @@ +resource "yandex_compute_instance" "web" { + depends_on = [ yandex_compute_instance.db ] + count = 2 + name = "web-${count.index + 1}" + hostname = "web-${count.index + 1}" + platform_id = var.vm_web_yandex_compute_instance_platform_id + zone = var.default_zone + resources { + cores = var.vm_resources.web.cores + memory = var.vm_resources.web.memory + core_fraction = var.vm_resources.web.core_fraction + } + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.image_id + type = var.vm_resources.web.type + size = var.vm_resources.web.size + } + } + scheduling_policy { + preemptible = var.vm_web_scheduling_policy + } + network_interface { + subnet_id = yandex_vpc_subnet.develop.id + security_group_ids = [yandex_vpc_security_group.example.id] + nat = var.vm_web_network_interface + } + metadata = { + serial-port-enable = var.serial-port + ssh-keys = var.ssh-key + } +} \ No newline at end of file diff --git a/03/src/disk_vm.tf b/03/src/disk_vm.tf new file mode 100644 index 00000000..c91470cc --- /dev/null +++ b/03/src/disk_vm.tf @@ -0,0 +1,44 @@ +resource "yandex_compute_disk" "hdd" { + count = 3 + name = "disk-${count.index + 1}" + zone = var.default_zone + size = var.disk_size + type = var.disk_type +} + +resource "yandex_compute_instance" "storage" { + name = var.storage_vm_name + hostname = var.storage_vm_name + platform_id = var.vm_web_yandex_compute_instance_platform_id + zone = var.default_zone + resources { + cores = var.vm_resources.web.cores + memory = var.vm_resources.web.memory + core_fraction = var.vm_resources.web.core_fraction + } + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.image_id + type = var.vm_resources.web.type + size = var.vm_resources.web.size + } + } + dynamic "secondary_disk" { + for_each = yandex_compute_disk.hdd[*].id + content { + disk_id = secondary_disk.value + } + } + scheduling_policy { + preemptible = var.vm_web_scheduling_policy + } + network_interface { + subnet_id = yandex_vpc_subnet.develop.id + security_group_ids = [yandex_vpc_security_group.example.id] + nat = var.vm_web_network_interface + } + metadata = { + serial-port-enable = var.serial-port + ssh-keys = var.ssh-key + } +} \ No newline at end of file diff --git a/03/src/for_each-vm.tf b/03/src/for_each-vm.tf new file mode 100644 index 00000000..f84386db --- /dev/null +++ b/03/src/for_each-vm.tf @@ -0,0 +1,31 @@ +resource "yandex_compute_instance" "db" { + for_each = var.each_vm + name = each.value.vm_name + hostname = each.value.vm_name + platform_id = each.value.platform_id + zone = var.default_zone + resources { + cores = each.value.cpu + memory = each.value.ram + core_fraction = each.value.core_fraction + } + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.image_id + type = each.value.type + size = each.value.disk_volume + } + } + scheduling_policy { + preemptible = each.value.scheduling_policy + } + network_interface { + subnet_id = yandex_vpc_subnet.develop.id + security_group_ids = [yandex_vpc_security_group.example.id] + nat = each.value.network_interface + } + metadata = { + serial-port-enable = var.serial-port + ssh-keys = var.ssh-key + } +} diff --git a/03/src/hosts.tftpl b/03/src/hosts.tftpl new file mode 100644 index 00000000..dbf358a5 --- /dev/null +++ b/03/src/hosts.tftpl @@ -0,0 +1,23 @@ +[webservers] + +%{~ for i in webservers ~} + +${i["name"]} ansible_host=${i["network_interface"][0]["nat_ip_address"] } ansible_fqdn=${i["fqdn"]} + +%{~ endfor ~} + +[databases] + +%{~ for i in databases ~} + +${i["name"]} ansible_host=${i["network_interface"][0]["nat_ip_address"] } ansible_fqdn=${i["fqdn"]} + +%{~ endfor ~} + +[storage] + +%{~ for i in storage ~} + +${i["name"]} ansible_host=${i["network_interface"][0]["nat_ip_address"] } ansible_fqdn=${i["fqdn"]} + +%{~ endfor ~} \ No newline at end of file diff --git a/03/src/main.tf b/03/src/main.tf index 123fe0c7..ab5490a7 100644 --- a/03/src/main.tf +++ b/03/src/main.tf @@ -6,4 +6,7 @@ resource "yandex_vpc_subnet" "develop" { zone = var.default_zone network_id = yandex_vpc_network.develop.id v4_cidr_blocks = var.default_cidr +} +data "yandex_compute_image" "ubuntu" { + family = var.vm_web_yandex_compute_image } \ No newline at end of file diff --git a/03/src/personal.auto.tfvars_example b/03/src/personal.auto.tfvars_example deleted file mode 100644 index 22c0272d..00000000 --- a/03/src/personal.auto.tfvars_example +++ /dev/null @@ -1,3 +0,0 @@ -token = "" -cloud_id = "" -folder_id = "" diff --git a/03/src/providers.tf b/03/src/providers.tf index 1f337849..c6ec9065 100644 --- a/03/src/providers.tf +++ b/03/src/providers.tf @@ -4,7 +4,7 @@ terraform { source = "yandex-cloud/yandex" } } - required_version = "~>1.8.4" + required_version = "1.9.8" } provider "yandex" { diff --git a/03/src/variables.tf b/03/src/variables.tf index 79970105..e9ed0b97 100644 --- a/03/src/variables.tf +++ b/03/src/variables.tf @@ -29,4 +29,112 @@ variable "vpc_name" { type = string default = "develop" description = "VPC network&subnet name" +} + +variable "vm_web_yandex_compute_image"{ + type = string + default = "ubuntu-2004-lts" + description = "Image name for VM" +} + +variable "vm_web_yandex_compute_instance_platform_id" { + type = string + default = "standard-v2" + description = "Platform type of VM" +} + +variable "vm_web_scheduling_policy" { + type = bool + default = true +} + +variable "vm_web_network_interface" { + type = bool + default = true +} + +variable "vm_resources" { + type = map(object({ + cores = number + memory = number + core_fraction = number + type = string + size = number + })) + default = { + "web" = { + cores = 2 + memory = 1 + core_fraction = 5 + type = "network-hdd" + size = 10 + } + } +} + +variable "each_vm" { + type = map(object({ + platform_id=string + vm_name=string + cpu=number + ram=number + core_fraction=number + type=string + disk_volume=number + network_interface=bool + scheduling_policy=bool + })) + default = { + "main" = { + platform_id="standard-v2" + vm_name="main" + cpu=2 + ram=1 + core_fraction=5 + type="network-hdd" + disk_volume=10 + network_interface=true + scheduling_policy=true + } + "replica" = { + platform_id="standard-v3" + vm_name="replica" + cpu=4 + ram=2 + core_fraction=20 + type="network-hdd" + disk_volume=20 + network_interface=true + scheduling_policy=true + } + } +} + +variable "serial-port" { + type = number + default = 1 + description = "Common ssh params" +} + +variable "ssh-key" { + type = string + description = "Common ssh params" +} + +variable "disk_size" { + type = number + default = 1 + description = "HDD size (GB)" +} + +variable "disk_type" { + type = string + default = "network-hdd" + description = "HDD type" +} + +variable "storage_vm_name" { + type = string + default = "storage" + description = "Name of Storage VM" } \ No newline at end of file diff --git a/04/homework.md b/04/homework.md new file mode 100644 index 00000000..841e308f --- /dev/null +++ b/04/homework.md @@ -0,0 +1,27 @@ +## Задание 1 + +![alt text](image.png) + +![alt text](image-1.png) + +![alt text](image-2.png) + +## Задание 2 + +![alt text](image-4.png) + +[Документация terraform-docs (ссылка на github repo)](https://github.com/gaidarvu/ter-homeworks/blob/terraform-04/04/src/spec.md) + +## Задание 3 + +Смотрим модули, цепляем id модулей, которые будем удалять и удаляем +![alt text](image-3.png) + +Импортируем обратно модули +![alt text](image-5.png) +![alt text](image-6.png) + +Смотрим terraform plan +![alt text](image-7.png) + +[Финальный код (ссылка на github repo)](https://github.com/gaidarvu/ter-homeworks/tree/terraform-04/04/src) diff --git a/04/image-1.png b/04/image-1.png new file mode 100644 index 00000000..5a6358c3 Binary files /dev/null and b/04/image-1.png differ diff --git a/04/image-2.png b/04/image-2.png new file mode 100644 index 00000000..e9b43700 Binary files /dev/null and b/04/image-2.png differ diff --git a/04/image-3.png b/04/image-3.png new file mode 100644 index 00000000..bf685f12 Binary files /dev/null and b/04/image-3.png differ diff --git a/04/image-4.png b/04/image-4.png new file mode 100644 index 00000000..6244ff8c Binary files /dev/null and b/04/image-4.png differ diff --git a/04/image-5.png b/04/image-5.png new file mode 100644 index 00000000..df792f3b Binary files /dev/null and b/04/image-5.png differ diff --git a/04/image-6.png b/04/image-6.png new file mode 100644 index 00000000..65b50591 Binary files /dev/null and b/04/image-6.png differ diff --git a/04/image-7.png b/04/image-7.png new file mode 100644 index 00000000..d7b2861b Binary files /dev/null and b/04/image-7.png differ diff --git a/04/image.png b/04/image.png new file mode 100644 index 00000000..e5be504d Binary files /dev/null and b/04/image.png differ diff --git a/04/src/.tflint.hcl b/04/src/.tflint.hcl new file mode 100644 index 00000000..427121c3 --- /dev/null +++ b/04/src/.tflint.hcl @@ -0,0 +1,4 @@ +plugin "terraform" { + enabled = true + preset = "recommended" +} diff --git a/04/src/cloud-init.yml b/04/src/cloud-init.yml new file mode 100644 index 00000000..e7c9eebb --- /dev/null +++ b/04/src/cloud-init.yml @@ -0,0 +1,13 @@ +#cloud-config +users: + - name: ubuntu + groups: sudo + shell: /bin/bash + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + ssh_authorized_keys: + - ${ssh_authorized_keys} +package_update: true +package_upgrade: false +packages: + - vim + - nginx diff --git a/04/src/main.tf b/04/src/main.tf index 5e807eef..8179fdb2 100644 --- a/04/src/main.tf +++ b/04/src/main.tf @@ -1,5 +1,5 @@ resource "yandex_vpc_network" "develop" { - name = var.vpc_name + name = var.vpc_name } resource "yandex_vpc_subnet" "develop" { name = var.vpc_name @@ -8,3 +8,67 @@ resource "yandex_vpc_subnet" "develop" { v4_cidr_blocks = var.default_cidr } +module "marketing_vm" { + source = "git::https://github.com/udjin10/yandex_compute_instance.git?ref=main" + env_name = "develop" + network_id = yandex_vpc_network.develop.id + subnet_zones = ["ru-central1-a", "ru-central1-b"] + subnet_ids = [yandex_vpc_subnet.develop.id] + instance_name = "webs" + image_family = "ubuntu-2004-lts" + public_ip = true + + labels = { + owner = "gaidar_vu", + project = "marketing" + } + + metadata = { + user-data = data.template_file.cloudinit.rendered + serial-port-enable = 1 + } + +} + +module "analytics_vm" { + source = "git::https://github.com/udjin10/yandex_compute_instance.git?ref=main" + env_name = "stage" + network_id = yandex_vpc_network.develop.id + subnet_zones = ["ru-central1-a"] + subnet_ids = [yandex_vpc_subnet.develop.id] + instance_name = "web-stage" + instance_count = 1 + image_family = "ubuntu-2004-lts" + public_ip = true + + labels = { + owner= "gaidar_vu", + project = "analytics" + } + + metadata = { + user-data = data.template_file.cloudinit.rendered + serial-port-enable = 1 + } + +} + +module "devops" { + source = "./vps" + default_zone = "ru-central1-a" + default_cidr = ["10.0.2.0/24"] + vpc_name = "net_dev" + + metadata = { + user-data = data.template_file.cloudinit.rendered + serial-port-enable = 1 + } + +} + +data "template_file" "cloudinit" { + template = file("./cloud-init.yml") + vars = { + ssh_authorized_keys = var.vms_ssh_root_key + } +} \ No newline at end of file diff --git a/04/src/outputs.tf b/04/src/outputs.tf index e69de29b..3a1b6782 100644 --- a/04/src/outputs.tf +++ b/04/src/outputs.tf @@ -0,0 +1,12 @@ +output "vpc_subnet_id" { + value = module.devops.vpc_subnet_id +} +output "vpc_subnet_name" { + value = module.devops.vpc_subnet_name +} +output "vpc_subnet_zone" { + value = module.devops.vpc_subnet_zone +} +output "vpc_subnet_v4_cidr_blocks" { + value = module.devops.vpc_subnet_v4_cidr_blocks +} \ No newline at end of file diff --git a/04/src/personal.auto.tfvars_example b/04/src/personal.auto.tfvars_example deleted file mode 100644 index 2fac9aad..00000000 --- a/04/src/personal.auto.tfvars_example +++ /dev/null @@ -1,3 +0,0 @@ -token = "" -cloud_id = "" -folder_id = "" \ No newline at end of file diff --git a/04/src/providers.tf b/04/src/providers.tf index 1f337849..3b40f8f6 100644 --- a/04/src/providers.tf +++ b/04/src/providers.tf @@ -5,6 +5,23 @@ terraform { } } required_version = "~>1.8.4" + + backend "s3" { + endpoints = { + s3 = "https://storage.yandexcloud.net" + } + bucket = "tfstate-lock" + region = "ru-central1" + key = "terraform.tfstate" + + skip_region_validation = true + skip_credentials_validation = true + skip_requesting_account_id = true + skip_s3_checksum = true + + dynamodb_endpoint = "https://docapi.serverless.yandexcloud.net/ru-central1/b1gebvnp4l01pjj94h8g/etnkv8m3sqd6cfnpkg00" + dynamodb_table = "tfstate-lock" + } } provider "yandex" { diff --git a/04/src/spec.md b/04/src/spec.md new file mode 100644 index 00000000..f7540abb --- /dev/null +++ b/04/src/spec.md @@ -0,0 +1,49 @@ +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~>1.8.4 | + +## Providers + +| Name | Version | +|------|---------| +| [template](#provider\_template) | 2.2.0 | +| [yandex](#provider\_yandex) | 0.132.0 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [analytics\_vm](#module\_analytics\_vm) | git::https://github.com/udjin10/yandex_compute_instance.git | main | +| [devops](#module\_devops) | ./vps | n/a | +| [marketing\_vm](#module\_marketing\_vm) | git::https://github.com/udjin10/yandex_compute_instance.git | main | + +## Resources + +| Name | Type | +|------|------| +| [yandex_vpc_network.develop](https://registry.terraform.io/providers/yandex-cloud/yandex/latest/docs/resources/vpc_network) | resource | +| [yandex_vpc_subnet.develop](https://registry.terraform.io/providers/yandex-cloud/yandex/latest/docs/resources/vpc_subnet) | resource | +| [template_file.cloudinit](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [cloud\_id](#input\_cloud\_id) | n/a | `string` | n/a | yes | +| [default\_cidr](#input\_default\_cidr) | n/a | `list(string)` |
[
"10.0.1.0/24"
]
| no | +| [default\_zone](#input\_default\_zone) | n/a | `string` | `"ru-central1-a"` | no | +| [folder\_id](#input\_folder\_id) | n/a | `string` | n/a | yes | +| [token](#input\_token) | ##cloud vars | `string` | n/a | yes | +| [vms\_ssh\_root\_key](#input\_vms\_ssh\_root\_key) | ssh-keygen -t ed25519 | `string` | n/a | yes | +| [vpc\_name](#input\_vpc\_name) | VPC network&subnet name | `string` | `"develop"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [vpc\_subnet\_id](#output\_vpc\_subnet\_id) | n/a | +| [vpc\_subnet\_name](#output\_vpc\_subnet\_name) | n/a | +| [vpc\_subnet\_v4\_cidr\_blocks](#output\_vpc\_subnet\_v4\_cidr\_blocks) | n/a | +| [vpc\_subnet\_zone](#output\_vpc\_subnet\_zone) | n/a | diff --git a/04/src/variables.tf b/04/src/variables.tf index d5195070..d04d0281 100644 --- a/04/src/variables.tf +++ b/04/src/variables.tf @@ -1,28 +1,24 @@ ###cloud vars variable "token" { type = string - description = "OAuth-token; https://cloud.yandex.ru/docs/iam/concepts/authorization/oauth-token" } variable "cloud_id" { type = string - description = "https://cloud.yandex.ru/docs/resource-manager/operations/cloud/get-id" } variable "folder_id" { type = string - description = "https://cloud.yandex.ru/docs/resource-manager/operations/folder/get-id" } variable "default_zone" { type = string default = "ru-central1-a" - description = "https://cloud.yandex.ru/docs/overview/concepts/geo-scope" } + variable "default_cidr" { type = list(string) default = ["10.0.1.0/24"] - description = "https://cloud.yandex.ru/docs/vpc/operations/subnet-create" } variable "vpc_name" { @@ -35,23 +31,37 @@ variable "vpc_name" { variable "vms_ssh_root_key" { type = string - default = "your_ssh_ed25519_key" description = "ssh-keygen -t ed25519" } -###example vm_web var -variable "vm_web_name" { - type = string - default = "netology-develop-platform-web" - description = "example vm_web_ prefix" -} +### Проверка IP адресов -###example vm_db var -variable "vm_db_name" { - type = string - default = "netology-develop-platform-db" - description = "example vm_db_ prefix" +variable "ip_addr" { + type=string + description="ip-адрес" + default="192.168.0.1" + validation { + condition = can(cidrhost("${var.ip_addr}/32", 0)) + error_message = "Wrong IP" + } } +variable "ip_addrs" { + type=list(string) + description="список ip-адресов" + default=["192.168.0.1", "1.1.1.1", "127.0.0.1"] + validation { + condition = alltrue([ for ip_addr in var.ip_addrs: can(cidrhost("${ip_addr}/32", 0)) ]) + error_message = "There are wrong IP's in a list" + } +} - +variable "ip_addr_regex" { + type=string + description="ip-адрес" + default="192.168.0.1" + validation { + condition = can(regex("^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", var.ip_addr_regex)) + error_message = "IP is incorrect" + } +} \ No newline at end of file diff --git a/04/src/vps/.gitignore b/04/src/vps/.gitignore new file mode 100644 index 00000000..df429d22 --- /dev/null +++ b/04/src/vps/.gitignore @@ -0,0 +1,12 @@ +# Local .terraform directories and files +**/.terraform/* +.terraform* + +!.terraformrc + +# .tfstate files +*.tfstate +*.tfstate.* + +# own secret vars store. +personal.auto.tfvars \ No newline at end of file diff --git a/04/src/vps/main.tf b/04/src/vps/main.tf new file mode 100644 index 00000000..275629c3 --- /dev/null +++ b/04/src/vps/main.tf @@ -0,0 +1,43 @@ +resource "yandex_vpc_network" "devops" { + name = var.vpc_name +} +resource "yandex_vpc_subnet" "devops" { + name = var.vpc_name + zone = var.default_zone + network_id = yandex_vpc_network.devops.id + v4_cidr_blocks = var.default_cidr +} +data "yandex_compute_image" "ubuntu" { + family = var.yandex_compute_image +} + +resource "yandex_compute_instance" "devops" { + for_each = var.each_vm + name = each.value.vm_name + hostname = each.value.vm_name + platform_id = each.value.platform_id + zone = var.default_zone + resources { + cores = each.value.cpu + memory = each.value.ram + core_fraction = each.value.core_fraction + } + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.image_id + type = each.value.type + size = each.value.disk_volume + } + } + scheduling_policy { + preemptible = each.value.scheduling_policy + } + network_interface { + subnet_id = yandex_vpc_subnet.devops.id + nat = each.value.network_interface + } + + metadata = { + for k, v in var.metadata : k => v + } +} \ No newline at end of file diff --git a/04/src/vps/outputs.tf b/04/src/vps/outputs.tf new file mode 100644 index 00000000..2aa0d561 --- /dev/null +++ b/04/src/vps/outputs.tf @@ -0,0 +1,12 @@ +output "vpc_subnet_id" { + value = yandex_vpc_subnet.devops.id +} +output "vpc_subnet_name" { + value = yandex_vpc_subnet.devops.name +} +output "vpc_subnet_zone" { + value = yandex_vpc_subnet.devops.zone +} +output "vpc_subnet_v4_cidr_blocks" { + value = yandex_vpc_subnet.devops.v4_cidr_blocks +} \ No newline at end of file diff --git a/04/src/vps/providers.tf b/04/src/vps/providers.tf new file mode 100644 index 00000000..e34a9af0 --- /dev/null +++ b/04/src/vps/providers.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + yandex = { + source = "yandex-cloud/yandex" + } + } + required_version = "~>1.8.4" +} + diff --git a/04/src/vps/variables.tf b/04/src/vps/variables.tf new file mode 100644 index 00000000..812f292d --- /dev/null +++ b/04/src/vps/variables.tf @@ -0,0 +1,60 @@ +variable "default_zone" { + type = string +} + +variable "yandex_compute_image"{ + type = string + default = "ubuntu-2004-lts" +} + +variable "default_cidr" { + type = list(string) + description = "ipv4 cidr" +} + +variable "vpc_name" { + type = string +} + +variable "metadata" { + type = map(string) + default = {} +} + +variable "each_vm" { + type = map(object({ + platform_id=string + vm_name=string + cpu=number + ram=number + core_fraction=number + type=string + disk_volume=number + network_interface=bool + scheduling_policy=bool + })) + default = { + "dev" = { + platform_id="standard-v2" + vm_name="dev" + cpu=2 + ram=1 + core_fraction=5 + type="network-hdd" + disk_volume=10 + network_interface=true + scheduling_policy=true + } + "ops" = { + platform_id="standard-v3" + vm_name="ops" + cpu=4 + ram=2 + core_fraction=20 + type="network-hdd" + disk_volume=20 + network_interface=true + scheduling_policy=true + } + } +} \ No newline at end of file diff --git a/05/homework.md b/05/homework.md new file mode 100644 index 00000000..f4b94768 --- /dev/null +++ b/05/homework.md @@ -0,0 +1,84 @@ +## Задание 1 + +### TFLint + +Ругается на использование дефолтной ветки на гитхабе в модуле, поскольку изменения в дефолтных ветках могут происходить в любой момент, это может нарушить инфраструктуру при обновлении +```tflint +Warning: Module source "git::https://github.com/udjin10/yandex_compute_instance.git?ref=main" uses a default branch as ref (main) (terraform_module_pinned_source) + + on main.tf line 12: + 12: source = "git::https://github.com/udjin10/yandex_compute_instance.git?ref=main" +``` + +В файле конфигурации Terraform не указано ограничение версии для провайдера +```tflint +Warning: Missing version constraint for provider "yandex" in `required_providers` (terraform_required_providers) + + on providers.tf line 3: + 3: yandex = { + 4: source = "yandex-cloud/yandex" + 5: } +``` + +### Checkov + +Для модуля marketing_vm не указан хеш коммита для источника модуля +```checkov +Check: CKV_TF_1: "Ensure Terraform module sources use a commit hash" + FAILED for resource: marketing_vm + File: /main.tf:11-31 +``` + +Для модуля marketing_vm не указан тег с версией. Checkov рекомендует использовать теги с номерами версий для обеспечения стабильности и предсказуемости кода +```checkov +Check: CKV_TF_2: "Ensure Terraform module sources use a tag with a version number" + FAILED for resource: marketing_vm + File: /main.tf:11-31 +``` + +Ругается на внешний IP и что это приводит к рискам безопасности +```checkov +Check: CKV_YC_2: "Ensure compute instance does not have public IP." + FAILED for resource: module.devops.yandex_compute_instance.devops["dev"] + File: /vps/main.tf:14-43 + Calling File: /main.tf:56-67 +``` + +Ругается на отсутствие группы безопасности на сетевом интерфейсе +```checkov +Check: CKV_YC_11: "Ensure security group is assigned to network interface." + FAILED for resource: module.devops.yandex_compute_instance.devops["dev"] + File: /vps/main.tf:14-43 + Calling File: /main.tf:56-67 +``` + +## Задание 2 + +![alt text](image.png) + +![alt text](image-1.png) + +![alt text](image-2.png) + +![alt text](image-3.png) + +![alt text](image-4.png) + +## Задание 3 + +[Pull Request terraform-hotfix --> terraform-05](https://github.com/gaidarvu/ter-homeworks/pull/1) + +## Задание 4 + +### Проверка на cidrhost() +![alt text](image-5.png) + +![alt text](image-7.png) + +### Проверка на regex() +![alt text](image-6.png) + +[Файл variables.tf с используемыми переменными (в низу)](https://github.com/gaidarvu/ter-homeworks/blob/terraform-05/04/src/variables.tf) + +## Итог +[Финальный код (ссылка на ветку terraform-05)](https://github.com/gaidarvu/ter-homeworks/tree/terraform-05/04/src) diff --git a/05/image-1.png b/05/image-1.png new file mode 100644 index 00000000..1fa02435 Binary files /dev/null and b/05/image-1.png differ diff --git a/05/image-2.png b/05/image-2.png new file mode 100644 index 00000000..8706a1cd Binary files /dev/null and b/05/image-2.png differ diff --git a/05/image-3.png b/05/image-3.png new file mode 100644 index 00000000..52fccd96 Binary files /dev/null and b/05/image-3.png differ diff --git a/05/image-4.png b/05/image-4.png new file mode 100644 index 00000000..db6675d2 Binary files /dev/null and b/05/image-4.png differ diff --git a/05/image-5.png b/05/image-5.png new file mode 100644 index 00000000..9a999d80 Binary files /dev/null and b/05/image-5.png differ diff --git a/05/image-6.png b/05/image-6.png new file mode 100644 index 00000000..360314a8 Binary files /dev/null and b/05/image-6.png differ diff --git a/05/image-7.png b/05/image-7.png new file mode 100644 index 00000000..9a07db3d Binary files /dev/null and b/05/image-7.png differ diff --git a/05/image.png b/05/image.png new file mode 100644 index 00000000..d076f3a6 Binary files /dev/null and b/05/image.png differ diff --git a/README.md b/README.md deleted file mode 100644 index 4d3a44fe..00000000 --- a/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Домашние задания по модулю «Облачная инфраструктура. Terraform» - -В этом репозитории расположены ваши домашние задания к каждой лекции. - -Обязательными к выполнению являются задачи без указания звездочки. Их выполнение необходимо для получения зачета и диплома о профессиональной переподготовке. - -Задачи со звездочкой (*) являются дополнительными задачами и/или задачами повышенной сложности. Они не являются обязательными к выполнению, но помогут вам глубже понять тему. - -Любые вопросы по решению задач задавайте в чате курса. - - -1. [Ввдение в Terraform](01/hw-01.md) - -2. [Основы Terraform. Yandex Cloud](02/hw-02.md) - -3. [Управляющие конструкции в коде Terraform](03/hw-03.md) - -4. [Продвинутые методы работы с Terraform](04/hw-04.md) - -5. [Использование Terraform в команде](05/hw-05.md) - - -