diff --git a/readme.md b/readme.md index e7a2165..2ce29e5 100644 --- a/readme.md +++ b/readme.md @@ -33,3 +33,4 @@ * [7.1. Инфраструктура как код](/src/homework/07-terraform/7.1) * [7.2. Облачные провайдеры и синтаксис Terraform](/src/homework/07-terraform/7.2) * [7.3. Основы и принцип работы Terraform](/src/homework/07-terraform/7.3) +* [7.4. Средства командной работы над инфраструктурой](/src/homework/07-terraform/7.4) diff --git a/src/homework/07-terraform/7.4/.env.example b/src/homework/07-terraform/7.4/.env.example new file mode 100644 index 0000000..6a836d2 --- /dev/null +++ b/src/homework/07-terraform/7.4/.env.example @@ -0,0 +1,4 @@ +YC_TOKEN=OAuthToken +YC_CLOUD_ID=cloudId +YC_FOLDER_ID=folderId +YC_ZONE=ru-central1-a diff --git a/src/homework/07-terraform/7.4/.gitignore b/src/homework/07-terraform/7.4/.gitignore new file mode 100644 index 0000000..f10862a --- /dev/null +++ b/src/homework/07-terraform/7.4/.gitignore @@ -0,0 +1 @@ +/.env diff --git a/src/homework/07-terraform/7.4/Makefile b/src/homework/07-terraform/7.4/Makefile new file mode 100644 index 0000000..443bbe4 --- /dev/null +++ b/src/homework/07-terraform/7.4/Makefile @@ -0,0 +1,20 @@ +#!make +tf-init: + cd ./terraform \ + && env $(cat ../.env) terraform init +tf-init-upgrade: + cd ./terraform \ + && env $(cat ../.env) terraform init -upgrade +tf-plan: + cd ./terraform \ + && env $(cat ../.env) terraform plan + +tf-ws-prod: + cd ./terraform \ + && terraform workspace select prod +tf-ws-stage: + cd ./terraform \ + && terraform workspace select stage +tf-ws-current: + cd ./terraform \ + && terraform workspace list diff --git a/src/homework/07-terraform/7.4/atlantis/atlantis.yaml b/src/homework/07-terraform/7.4/atlantis/atlantis.yaml new file mode 100644 index 0000000..9513b4d --- /dev/null +++ b/src/homework/07-terraform/7.4/atlantis/atlantis.yaml @@ -0,0 +1,10 @@ +version: 3 +projects: + - dir: src/homework/07-terraform/7.3/terraform + workspace: staging + autoplan: + when_modified: ["*.tf"] + - dir: src/homework/07-terraform/7.3/terraform + workspace: prod + autoplan: + when_modified: [ "*.tf" ] diff --git a/src/homework/07-terraform/7.4/atlantis/server.yaml b/src/homework/07-terraform/7.4/atlantis/server.yaml new file mode 100644 index 0000000..1ffb270 --- /dev/null +++ b/src/homework/07-terraform/7.4/atlantis/server.yaml @@ -0,0 +1,12 @@ +--- +repos: + - id: github.com/Dannecron/netology-devops + allowed_overrides: [apply_requirements] + +workflows: + default: + plan: + steps: + - init + - plan: + extra_args: [ "-lock", "false" ] diff --git a/src/homework/07-terraform/7.4/readme.md b/src/homework/07-terraform/7.4/readme.md new file mode 100644 index 0000000..c1b8351 --- /dev/null +++ b/src/homework/07-terraform/7.4/readme.md @@ -0,0 +1,86 @@ +Выполнение [домашнего задания](https://github.com/netology-code/virt-homeworks/blob/master/07-terraform-04-teamwork/README.md) +по теме "7.4. Средства командной работы над инфраструктурой". + +## Q/A + +### Задание 1 + +> Настроить terraform cloud + +Не выполнил, так как нет доступа и есть вероятность, что terraform cloud не будет работать с инфраструктурой `yandex.cloud`. + +### Задание 2 + +> Написать серверный конфиг для атлантиса. +> +> Смысл задания – познакомиться с документацией о [серверной](https://www.runatlantis.io/docs/server-side-repo-config.html) конфигурации +> и конфигурации уровня [репозитория](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html). +> +> Создай `server.yaml` который скажет атлантису: +> 1. Укажите, что атлантис должен работать только для репозиториев в вашем github (или любом другом) аккаунте. +> 1. На стороне клиентского конфига разрешите изменять `workflow`, то есть для каждого репозитория можно +> будет указать свои дополнительные команды. +> 1. В `workflow` используемом по-умолчанию сделайте так, что бы во время планирования не происходил `lock` состояния. +> +> Создай `atlantis.yaml` который, если поместить в корень terraform проекта, скажет атлантису: +> 1. Надо запускать планирование и аплай для двух воркспейсов `stage` и `prod`. +> 1. Необходимо включить автопланирование при изменении любых файлов `*.tf`. +> +> В качестве результата приложите ссылку на файлы `server.yaml` и `atlantis.yaml`. + +Создан файл [server.yaml](./atlantis/server.yaml) для конфигурации сервера, указанной в задании. А именно: +- `id:` - задаёт текущий репозиторий в качестве отслеживаемого `atlantis`. +- `allowed_overrides: [apply_requirements]` - указывает возможность изменения `workflow` на уровне репозитория. +- в ключе `workflows.default.plan` задаётся поведение команды `atlatis plan` по умолчанию для всех конфигураций. + +В файле [atlantis.yaml](./atlantis/atlantis.yaml) добавлены два проекта, чтобы разграничить `workspace`, для которых применяются изменения. +При этом у каждого проекта определён массив `autoplan.when_modified`, в котором закреплено, +что необходимо автоматически запускать команды `terraform` при изменении любых файлов `*.tf` + +### Задание 3 + +> Знакомство с каталогом модулей. +> +> 1. В [каталоге модулей](https://registry.terraform.io/browse/modules) найдите готовый модуль для создания `yandex_compute_instance`. +> 2. Изучите как устроен модуль. Задумайтесь, будете ли в своем проекте использовать этот модуль или непосредственно +> ресурс `yandex_compute_instance` без помощи модуля? +> 3. В рамках предпоследнего задания был создан `yandex_compute_instance`. +> Создайте аналогичный инстанс при помощи найденного модуля. +> +> В качестве результата задания приложите ссылку на созданный блок конфигураций. + +В качестве готового модуля для `yandex.cloud` можно использовать [реализацию от hamnsk](https://registry.terraform.io/modules/hamnsk/vpc/yandex/latest). + +В данном случае, лучше всего будет использовать напрямую `yandex_compute_instance`, так как лишние внешние зависимости только усложняют построение конфигурации. +Лучше всего будет взять за основу и переработать данный модуль "под себя". К тому же, из-за блокировки реестра terraform, использование модулей может быть затруднено. + +Для инициализации данного модуля необходимо добавить следующий конфиг в [main.tf](./terraform/main.tf): + +```terraform +module "yc-vpc" { + name = terraform.workspace + source = "git@github.com:hamnsk/terraform-yandex-vpc.git?ref=v0.5.0" + create_folder = false + yc_folder_id = var.YC_FOLDER_ID + yc_cloud_id = var.YC_CLOUD_ID + nat_instance = true + subnets = [ + { + zone = var.YC_ZONE + v4_cidr_blocks = ["192.168.10.0/24"] + } + ] +} +``` + +При этом необходимо добавить новые переменные в [variables.tf](./terraform/variables.tf), +а так же инициализировать их новыми переменными окружения. + +К сожалению, в данной конфигурации не получилось инициализировать данный модуль из-за ошибки: + +```text +Error: failed to find latest image with family "nat-instance-ubuntu" +``` + +Выглядит это так, будто модуль опирается на образ ОС, которой теперь нет в реестре. Это ещё один пункт к тому, +что лучше самостоятельно создавать и поддерживать модули для `terraform`. diff --git a/src/homework/07-terraform/7.4/terraform/.gitignore b/src/homework/07-terraform/7.4/terraform/.gitignore new file mode 100644 index 0000000..22fca49 --- /dev/null +++ b/src/homework/07-terraform/7.4/terraform/.gitignore @@ -0,0 +1,35 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sentitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +# +*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc diff --git a/src/homework/07-terraform/7.4/terraform/.terraform.lock.hcl b/src/homework/07-terraform/7.4/terraform/.terraform.lock.hcl new file mode 100644 index 0000000..03c7a87 --- /dev/null +++ b/src/homework/07-terraform/7.4/terraform/.terraform.lock.hcl @@ -0,0 +1,10 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/yandex-cloud/yandex" { + version = "0.61.0" + constraints = "~> 0.61.0" + hashes = [ + "h1:hPOtT0blpx3w2CVdb3DFxBEsuU9cPW9fT1TmajL/ymI=", + ] +} diff --git a/src/homework/07-terraform/7.4/terraform/main.tf b/src/homework/07-terraform/7.4/terraform/main.tf new file mode 100644 index 0000000..1b63427 --- /dev/null +++ b/src/homework/07-terraform/7.4/terraform/main.tf @@ -0,0 +1,51 @@ +module "yc-vpc" { + name = terraform.workspace + source = "git@github.com:hamnsk/terraform-yandex-vpc.git?ref=v0.5.0" + create_folder = false + yc_folder_id = var.YC_FOLDER_ID + yc_cloud_id = var.YC_CLOUD_ID + nat_instance = true + subnets = [ + { + zone = var.YC_ZONE + v4_cidr_blocks = ["192.168.10.0/24"] + } + ] +} + +resource "yandex_compute_instance" "vm-1" { + name = "test-vm-1" + count = local.vm_count[terraform.workspace] + + resources { + cores = 2 + memory = 2 + } + + boot_disk { + initialize_params { + image_id = "fd81hgrcv6lsnkremf32" # ubuntu-20-04-lts-v20210908 + } + } + + network_interface { + subnet_id = module.yc-vpc.subnets.0.id + nat = true + } + + metadata = { + ssh-keys = "ubuntu:${file("~/.ssh/id_rsa.pub")}" + } +} + +output "internal_ip_address_vm_1" { + value = [ + for vm in yandex_compute_instance.vm-1 : vm.network_interface.0.ip_address + ] +} + +output "external_ip_address_vm_1" { + value = [ + for vm in yandex_compute_instance.vm-1 : vm.network_interface.0.nat_ip_address + ] +} diff --git a/src/homework/07-terraform/7.4/terraform/provider.tf b/src/homework/07-terraform/7.4/terraform/provider.tf new file mode 100644 index 0000000..73f6f13 --- /dev/null +++ b/src/homework/07-terraform/7.4/terraform/provider.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + yandex = { + source = "yandex-cloud/yandex" + } + } + required_version = ">= 0.13" +} + +provider "yandex" { + token = "auth_token_here" + cloud_id = "cloud_id_here" + folder_id = "folder_id_here" + zone = "ru-central1-a" +} diff --git a/src/homework/07-terraform/7.4/terraform/variables.tf b/src/homework/07-terraform/7.4/terraform/variables.tf new file mode 100644 index 0000000..eefa579 --- /dev/null +++ b/src/homework/07-terraform/7.4/terraform/variables.tf @@ -0,0 +1,11 @@ +locals { + vm_count = { + default = 1 + stage = 1 + prod = 2 + } +} + +variable "YC_CLOUD_ID" { default = "" } +variable "YC_FOLDER_ID" { default = "" } +variable "YC_ZONE" { default = "" }