antonLytkin18 Infra repository
Задание 1. Для подключения к someinternalhost
в одну строку, необходимо выполнить команду:
$ ssh -t -i ~/.ssh/id_rsa -A [email protected] ssh 10.132.0.3
Задание 1.1. Для подключения к someinternalhost
через alias, необходимо создать файл ~/.ssh/config
с содержимым:
Host bastion
HostName 104.199.59.234
User anton_lytkin
Host someinternalhost
HostName 10.132.0.3
User anton_lytkin
ProxyCommand ssh [email protected] nc %h %p 2> /dev/null
Задание 2. Файл setupvpn.sh
устанавливает VPN-сервер pritunl
.
Файл cloud-bastion.ovpn
описывает конфигурацию для подключения к VPN-серверу.
Задание 3. Данные для проверки подключения:
bastion_IP = 104.199.59.234
someinternalhost_IP = 10.132.0.3
Задание 3.1. Реализовано использование валидного сертификата с помощью сервиса sslip.io
:
https://104.199.59.234.sslip.io
- Создание инстанса
redit-app
с автозапуском скриптаstartup.sh
:
$ gcloud compute instances create reddit-app \
--zone="us-east1-b" \
--boot-disk-size=10GB \
--image-family ubuntu-1604-lts \
--image-project=ubuntu-os-cloud \
--machine-type=g1-small \
--tags puma-server \
--restart-on-failure \
--metadata-from-file startup-script=startup.sh
- Создание правила файрвола из командной строки:
$ gcloud compute firewall-rules create default-puma-server \
--allow=tcp:9292 --direction=ingress \
--source-ranges=0.0.0.0/0 \
--target-tags=puma-server
- Данные для проверки подключения:
testapp_IP = 35.229.62.122
testapp_port = 9292
- Для запуска сборки образа, необходимо выполнить команду:
$ packer build -var-file variables.json ubuntu16.json
- Для запуска сборки образа
reddit-full
с установленным приложением и автозапуском сервера, необходимо выполнить команду:
$ packer build immutable.json
- Для создания инстанса c образом
reddit-full
, необходимо выполнить команду:
$ ./config-scripts/create-reddit-vm.sh
1.1 Задание со (*). Для добавления ssh-ключей для нескольких пользователей, необходимо прописать внутри описания конкретного инстанса:
metadata {
ssh-keys = "appuser:${file(var.public_key_path)}appuser1:${file(var.public_key_path)}appuser2:${file(var.public_key_path)}"
}
1.2 Задание со (*). При добавлении ssh-ключа для пользователя appuser_web
и последующем выполнении команды
terraform apply
произойдет удаление этого ключа, поскольку его добавление было произведено через веб-интерфейс GCP.
Для решения проблемы необходимо описать добавление данного ключа в файле main.tf
.
2.1 Задание с (**). В файле lb.tf
было описано создание HTTP-балансировщика.
2.2 Задание с (**). Добавление нового инстанса увеличивает количество повторяющегося кода. Для решения этой проблемы
необходмо использовать переменную count
внутри описания инстанса:
resource "google_compute_instance" "app" {
name = "reddit-app${count.index}"
count = "${var.count}"
}
- Создан модуль
vpc
, принимающий на входе параметрsource_ranges
, хранящий список допустимых IP-адресов, с которых может производиться подключение к ВМ поssh
. - Созданы окружения
stage
иprod
, отличие которых заключается в ограничении доступа поssh
с определенного IP-адреса для окруженияprod
. - В каждом из окружений настроено удаленное хранение
state-файла
вGoogle Cloud Storage
. - Добавлен запуск необходимых процедур в модули:
app
. Добавление переменной окруженияDATABASE_URL
, хранящей внутренний IP-адрес ВМ сmongoDb
вpuma.env
:
provisioner "remote-exec" {
inline = [
"sudo echo DATABASE_URL=${var.db_ip} > /tmp/puma.env",
]
}
db
. Возможность подключения кmongoDb
с любого IP:
provisioner "remote-exec" {
inline = [
"sudo sed -i 's/bindIp: 127.0.0.1/bindIp: 0.0.0.0/' /etc/mongod.conf",
"sudo systemctl restart mongod",
]
}
- Генерация
inventory.json
производится динамически с помощью скриптаinventory.py
. Для получения IP-адресов виртуальных машин используется команда$ terraform output -json
, запускаемая с помощью модуля python'аsubprocess
. - Для проверки соединения необходимо запустить команду:
$ ansible all -m ping -i inventory.py
- В файл конфигурации
ansible.cnf
был установен путь к динамическомуinventory
, позволяющий получать IP-адреса для хостовapp
иdb
на лету:
inventory = ./inventory.py
-
Реализован оптимальный подход к написанию сценариев - несколько
playbook
ов. Для их запуска необходимо выполнить команду:$ ansible-playbook site.yml
-
Реализован запуск
playbook
ов на уровнеprovisioner
ов при запускеpacker
а:
"provisioners": [
{
"type": "ansible",
"playbook_file": "ansible/packer_app.yml"
}
]
"provisioners": [
{
"type": "ansible",
"playbook_file": "ansible/packer_db.yml"
}
]
Для запуска генерации образов, необходимо выполнить команды:
$ packer build -var-file packer/variables.json packer/app.json
$ packer build -var-file packer/variables.json packer/db.json
- Добавлен вызов роли
jdauphant.nginx
в playbookapp.yml
. Конфигурация для открытия80
порта описана в файлах, хранящих переменные для соответствующих окружений (групп хостов):
/ansible/environments/stage/group_vars/app
/ansible/environments/prod/group_vars/app
Для применения изменений необходимо выполнить команду:
$ cd ansible && ansible-playbook playbooks/site.yml
- Настроено использование динамического
inventory
для окруженийstage
иprod
:
/ansible/environments/stage/inventory.py
/ansible/environments/prod/inventory.py
- Реализованы дополнительные проверки для
travis-ci
в скрипте/travis.sh
. Был подготовленdocker
-образ со всеми необходимыми пакетами, необходимыми для корректного запуска данного скрипта:
$ docker run -v
pwd:
pwd-w
pwd -i -t antonlytkin/otus-ci ./travis.sh
В качестве промежуточного тестирования проверок в travis-ci
был использован функционал trytravis
.
- Реализована доступность приложения по
80
порту с помощью переменных ролиjdauphant.nginx
вVagrantfile
'е:
ansible.extra_vars = {
"nginx_sites" => {
"default" => [
"listen 80",
"server_name 'reddit'",
"location / { proxy_pass http://127.0.0.1:9292; }"
]
}
}
- Написан тест, позволяющий определить доступность БД по порту
27017
:
def test_correct_db_port(host):
port = 27017
config_file = host.file('/etc/mongod.conf')
assert config_file.contains(f"port: {port}")
assert host.socket(f"tcp://{port}").is_listening
- Переписаны playbook'и
packer_app.yml
иpacker_db.yml
на работу с ролями:
"provisioners": [
{
"type": "ansible",
"playbook_file": "{{ template_dir }}/../ansible/playbooks/app.yml",
"extra_arguments": ["--tags", "ruby"],
"ansible_env_vars": ["ANSIBLE_ROLES_PATH={{ template_dir }}/../ansible/roles"]
}
]
- Вынесена роль
db
в отдельный репозиторий:
- src: https://github.com/antonLytkin18/db.ansible.role
name: db