diff --git a/01/homework.md b/01/homework.md new file mode 100644 index 000000000..b09c14ceb --- /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 000000000..c036b7344 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 000000000..2f570b26e 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 000000000..4a33149cd Binary files /dev/null and b/01/image.png differ diff --git a/01/src/.terraformrc b/01/src/.terraformrc index 9bc772821..17415e3e0 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 a5fd2f46a..9f9d8a6d4 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 000000000..df429d221 --- /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 000000000..00691486c --- /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 000000000..8655b9de6 --- /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 000000000..a58fde3df 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 000000000..cbcfe261c 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 000000000..7f1d4a9b2 Binary files /dev/null and b/02/image.png differ diff --git a/02/src/locals.tf b/02/src/locals.tf index e69de29bb..9e6aead89 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 49baf600a..c9ab0b310 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 e69de29bb..b4797823a 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 fae4dc372..1482db443 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 8e1bb4f1e..eba10accc 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 000000000..f81f3719e --- /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 000000000..82798df86 --- /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 000000000..fbc256495 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 000000000..3039d3a0c 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 000000000..ceb490523 --- /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 000000000..54907e66f --- /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 000000000..c91470ccb --- /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 000000000..f84386dbb --- /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 000000000..dbf358a50 --- /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 123fe0c79..ab5490a78 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 22c0272d1..000000000 --- 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 1f337849b..c6ec90653 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 799701052..e9ed0b973 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 000000000..841e308f6 --- /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 000000000..5a6358c3e 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 000000000..e9b437003 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 000000000..bf685f12a 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 000000000..6244ff8cf 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 000000000..df792f3b4 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 000000000..65b505918 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 000000000..d7b2861b8 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 000000000..e5be504d6 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 000000000..427121c3e --- /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 000000000..e7c9eebb6 --- /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 5e807eefb..8179fdb28 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 e69de29bb..3a1b67820 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 2fac9aad6..000000000 --- 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 1f337849b..3b40f8f60 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 000000000..f7540abb7 --- /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 d51950706..d04d02814 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 000000000..df429d221 --- /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 000000000..275629c35 --- /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 000000000..2aa0d5610 --- /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 000000000..e34a9af05 --- /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 000000000..812f292d1 --- /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 000000000..f4b947681 --- /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 000000000..1fa02435d 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 000000000..8706a1cd2 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 000000000..52fccd969 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 000000000..db6675d27 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 000000000..9a999d808 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 000000000..360314a88 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 000000000..9a07db3d6 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 000000000..d076f3a6f Binary files /dev/null and b/05/image.png differ diff --git a/README.md b/README.md deleted file mode 100644 index 4d3a44fec..000000000 --- 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) - - -