Skip to content

Commit

Permalink
Merge pull request #5 from Otus-DevOps-2018-09/terraform-1
Browse files Browse the repository at this point in the history
Terraform 1
  • Loading branch information
Kirill-Garbar authored Nov 9, 2018
2 parents 2883637 + e788079 commit 1741540
Show file tree
Hide file tree
Showing 10 changed files with 238 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
variables.json
*.tfstate
*.tfstate.*.backup
*.tfstate.backup
*.tfvars
.terraform/
34 changes: 31 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#HW-3
# HW-3
## В процессе сделано:
- Созданы две ВМ. Одна с внутренним. Одна с внешним и внутренним IP - пограничный сервер.
- Проработаны несколько вариантов подключения через proxy по SSH
Expand Down Expand Up @@ -32,7 +32,7 @@ someinternalhost_IP = 10.156.0.2
- Перейти по ссылке https://35.187.10.59.sslip.io


#HW-4
# HW-4
## В процессе сделано:
- Развёрнуто приложение на виртуальной машине в GCP.
- Добавлено вручную правило для разрешения входящего трафика на сервера с определённым тегом.
Expand Down Expand Up @@ -76,7 +76,7 @@ gcloud compute firewall-rules create default-puma-server \
--target-tags puma-server
```

#HW-5
# HW-5
## В процессе сделано:
- Выдали доступ приложению Packer к GCP.
- Создали по инструкции базовый образ ubuntu с установленными ruby и mongodb и задеплоили в него приложение.
Expand All @@ -89,3 +89,31 @@ gcloud compute firewall-rules create default-puma-server \
- Выполнить скрипт config-scripts/create-reddit-vm.sh. Запомнить IP.
- Добавить правило firewall, разрешающее входящий трафик на порт TCP 9292.
- Пройти по ссылке http://IP:9292.

# HW-6
## В процессе сделано:
- Удалили ключ из метаданных проекта, чтобы протестировать добавление ключа через метаданый ресурса.
- Я перевёз средство разработки из Linux nano в MS VS Code. Пришлось заново настроить аутентификацию пакера и терраформа в gcloud.
- Создали ВМ из образа reddit-base. Посмотрели tfstate, грепнули его, чтобы получить IP-адрес.
- Создали output переменные. После редактирования ВМ сразу в консоль выводился IP-адрес.
- Создали ресурс правило фаерволла для нашего приложения. Удалил старое правило из прошлых дз для чистоты эксперимента.
- Добавили provisioners для деплоя приложения, добавили systemd unit из прошлого ДЗ со *.
- Добавили входные переменные.
- Использовали полезную команду terraform fmt для автоматического форматирования конфигов терраформа.
- Пометили ВМ для пересоздания командой terraform taint.resource_type.resource_name.
- Добавили несколько юзеров с ключами в метаданные проекта. Изменения применились не сразу, т.к. у меня в ЛК были созданы ещё какие-то старые экспериментальные ключи. Конфиг применился только после ручного удаления юзеров. Было бы неплохо этот эксперимент добавить в ДЗ.
- Последующее добавление вручную и применение конфига удалило вручную созданных юзеров.
- Изучили метод создания load balancer в GCP и в Terraform. В конфигах есть комментарии к ресурсам. Что можно ещё добавить в конфигурацию приложения: 1. Добавить внутренние адреса для инстансов приложений, оставить внешний адрес только у балансера. 2. Добавить репликацию/честную кластеризацию БД.
- Изучили метод параметризации количества инстансов ВМ с приложением.

## Проблемы при добавлении ключей:
- Изменения применились не сразу, т.к. у меня в ЛК были созданы ещё какие-то старые экспериментальные ключи. Конфиг применился только после ручного удаления юзеров. Было бы неплохо этот эксперимент добавить в ДЗ.

## Недостатки LB конфигурации.
- При добавлении дополнительного ресурса ВМ необходимо в нескольких местах поменять конфиги. 1. Добавить ресурс ВМ. 2. Добавить ВМ в instance_group. 3. Добавить IP в output (для сохранения шаблонности).
- При изменении конфигурации ВМ в ТФ необходимо добавить изменения в нескольких ресурсах.

## Что можно ещё добавить в конфигурацию приложения:
- Добавить внутренние адреса для инстансов приложений, оставить внешний адрес только у балансера.
- Добавить репликацию/честную кластеризацию БД.
- Сейчас health-check работает только по недоступности приложения. Желательно, чтобы работала по превышению нагрузки, по кодам ответа HTTP. Чтобы работало распределение пользователей по прозрачным правилам, например, приблизительное непревышение разницы метрик нагрузки.
1 change: 0 additions & 1 deletion packer/ubuntu16.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"source_image_family": null,
"disk_size111": null,
"disk_name": null,
"disk_size111": null,
"disk_type": null,
"image_description": null,
"network": null
Expand Down
12 changes: 12 additions & 0 deletions terraform/files/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -e

APP_DIR=${1:-$HOME}

git clone -b monolith https://github.com/express42/reddit.git $APP_DIR/reddit
cd $APP_DIR/reddit
bundle install

sudo mv /tmp/puma.service /etc/systemd/system/puma.service
sudo systemctl start puma
sudo systemctl enable puma
13 changes: 13 additions & 0 deletions terraform/files/puma.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/home/appuser/reddit
ExecStart=/bin/bash -lc 'puma'
Restart=always

[Install]
WantedBy=multi-user.target
59 changes: 59 additions & 0 deletions terraform/lb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Группа ВМ с приложениями
resource "google_compute_instance_group" "reddit-app-inst-group" {
name = "reddit-app-inst-group-name"

instances = [
"${google_compute_instance.app.*.self_link}",
]

named_port {
name = "puma-9292"
port = "9292"
}

zone = "${var.zone}"
}

# Сервис проверки "здоровья" нашего приложения. То, что обеспечивает отказоустойчивость.
resource "google_compute_http_health_check" "reddit-app-health-check" {
name = "reddit-app-health-check-name"
request_path = "/"
check_interval_sec = 1
timeout_sec = 1
port = "9292"
}

# То, что перенаправляет пользователя на определённый бэкэнд, учитывая проверку "здоровья" инстанса.
resource "google_compute_backend_service" "reddit-app-backend-service" {
name = "reddit-app-backend-service-name"
port_name = "puma-9292"
protocol = "HTTP"
timeout_sec = 3

health_checks = [
"${google_compute_http_health_check.reddit-app-health-check.self_link}",
]

backend = {
group = "${google_compute_instance_group.reddit-app-inst-group.self_link}"
}
}

# То, по чьей конфигурации target https proxy перенаправляет ссылки/модули приложения (GET звпросы) на бэкэнд сервисы.
resource "google_compute_url_map" "reddit-app-urlmap" {
name = "reddit-app-urlmap-name"
default_service = "${google_compute_backend_service.reddit-app-backend-service.self_link}"
}

# Перенаправляет запросы в соответствии с url map.
resource "google_compute_target_http_proxy" "reddit-app-target-proxy" {
name = "reddit-app-target-proxy-name"
url_map = "${google_compute_url_map.reddit-app-urlmap.self_link}"
}

# То, что торчит наружу. Ресурс, имеющий IP-адрес и перенаправляющий запросы.
resource "google_compute_global_forwarding_rule" "reddit-app-fw-rule" {
name = "reddit-app-fw-rule-name"
target = "${google_compute_target_http_proxy.reddit-app-target-proxy.self_link}"
port_range = "80"
}
75 changes: 75 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
provider "google" {
version = "1.4.0"
project = "${var.project}"
region = "${var.region}"
}

resource "google_compute_instance" "app" {
name = "reddit-app-${count.index}"
machine_type = "g1-small"
zone = "${var.zone}"
tags = ["reddit-app"]
count = "${var.app_count}"

# определение загрузочного диска
boot_disk {
initialize_params {
image = "${var.disk_image}"
}
}

# Добавляем ключ
metadata {
ssh-keys = "appuser:${file(var.public_key_path)}"
}

# определение сетевого интерфейса
network_interface {
# сеть, к которой присоединить данный интерфейс
network = "default"

# использовать ephemeral IP для доступа из Интернет
access_config {}
}

connection {
type = "ssh"
user = "appuser"
agent = false
private_key = "${file("${var.private_key_path}")}"
}

provisioner "file" {
source = "files/puma.service"
destination = "/tmp/puma.service"
}

provisioner "remote-exec" {
script = "files/deploy.sh"
}
}

resource "google_compute_project_metadata" "app" {
metadata {
ssh-keys = "appuser1:${file(var.public_key_path)} appuser2:${file(var.public_key_path)} appuser3:${file(var.public_key_path)}"
}
}

resource "google_compute_firewall" "firewall_puma" {
name = "allow-puma-default"

# Название сети, в которой действует правило
network = "default"

# Какой доступ разрешить
allow {
protocol = "tcp"
ports = ["9292"]
}

# Каким адресам разрешаем доступ
source_ranges = ["0.0.0.0/0"]

# Правило применимо для инстансов с перечисленными тэгами
target_tags = ["reddit-app"]
}
7 changes: 7 additions & 0 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
output "app_external_ip" {
value = "${google_compute_instance.app.*.network_interface.0.access_config.0.assigned_nat_ip}"
}

output "lb_external_ip" {
value = "${google_compute_global_forwarding_rule.reddit-app-fw-rule.ip_address}"
}
6 changes: 6 additions & 0 deletions terraform/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project = "your_project_id"
public_key_path = "~/.ssh/appuser.pub"
private_key_path = "~/.ssh/appuser"
disk_image = "reddit-base"
region = "europe-west1"
app_count = "4"
30 changes: 30 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
variable project {
description = "Project ID"
}

variable region {
description = "Region"
default = "europe-west1"
}

variable "zone" {
default = "europe-west1-b"
description = "zone for VM"
}

variable public_key_path {
description = "Path to the public key used for ssh access"
}

variable "private_key_path" {
description = "Path to the private key used for ssh access"
}

variable disk_image {
description = "Disk image"
}

variable "app_count" {
description = "instances quantity for LB"
default = "1"
}

0 comments on commit 1741540

Please sign in to comment.