Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ansible 3 #9

Merged
merged 7 commits into from
Nov 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@ variables.json
*.tfstate.backup
*.tfvars
.terraform/
id_rsa
appuser
webprogrammer
*.retry
.vscode/
ansible/dyn_inv/
gce.py
gce.ini
infra*.json
tf.log
jdauphant.nginx
vault.key
45 changes: 43 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,50 @@
dist: trusty
sudo: required
language: bash
env:
- PACKER_V=1.3.1 TF_V=0.11.10 TFLINT_V=0.7.2 ANS_V=2.7.1 ANSLINT_V=3.5.1
before_install:
- curl https://raw.githubusercontent.com/express42/otus-homeworks/2018-09/run.sh |
bash
- curl https://raw.githubusercontent.com/express42/otus-homeworks/2018-09/run.sh | bash
- sudo pip install --upgrade pip
install:
# packer
- wget https://releases.hashicorp.com/packer/${PACKER_V}/packer_${PACKER_V}_linux_amd64.zip -O packer.zip
- sudo unzip packer.zip -d /usr/bin
# #tf
- wget https://releases.hashicorp.com/terraform/${TF_V}/terraform_${TF_V}_linux_amd64.zip -O tf.zip
- sudo unzip tf.zip -d /usr/bin
# #tf-lint
- wget https://github.com/wata727/tflint/releases/download/v0.7.2/tflint_linux_amd64.zip -O tflint.zip
- sudo unzip tflint.zip -d /usr/bin
# #ans&ans-lint
- sudo pip install ansible==${ANS_V} ansible-lint==${ANSLINT_V}
- echo $PATH
before_script:
- touch ~/.ssh/appuser ~/.ssh/appuser.pub
- mv packer/variables.json.example packer/variables.json
- mv terraform/terraform.tfvars.example terraform/terraform.tfvars
- mv terraform/stage/terraform.tfvars.example terraform/stage/terraform.tfvars
- mv terraform/prod/terraform.tfvars.example terraform/prod/terraform.tfvars
script:
# packer
# Хотел здесь сделать двумя массивами и циклом, но не стал, потому что не смог объявить в блоке env массив.
# Трэвис из блока env автоматически конвертит в export, а массивы на export нельзя.
# Плюс к тому у нас два шаблона валидируются из директории packer, два шаблона из корневой.
- cd ${TRAVIS_BUILD_DIR}/packer
- packer validate -var-file=variables.json ubuntu16.json
- packer validate -var-file=variables.json immutable.json
- cd ${TRAVIS_BUILD_DIR}
- packer validate packer/app.json
- packer validate packer/db.json
# tf && tflint
- cd ${TRAVIS_BUILD_DIR}/terraform
- cd ${TRAVIS_BUILD_DIR}/terraform/stage
- terraform init -backend=false && terraform validate && tflint
- cd ${TRAVIS_BUILD_DIR}/terraform/prod
- terraform init -backend=false && terraform validate && tflint
# ansible-lint
- cd ${TRAVIS_BUILD_DIR}/ansible
- ansible-lint playbooks/*.yml --exclude=roles/jdauphant.nginx
notifications:
slack:
rooms:
Expand Down
5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Build Status](https://travis-ci.com/Otus-DevOps-2018-09/Kirill-Garbar_infra.svg?branch=master)](https://travis-ci.com/Otus-DevOps-2018-09/Kirill-Garbar_infra)

# HW-3
## В процессе сделано:
- Созданы две ВМ. Одна с внутренним. Одна с внешним и внутренним IP - пограничный сервер.
Expand Down Expand Up @@ -142,3 +144,81 @@ gcloud compute firewall-rules create default-puma-server \
- Выполнить terraform init и terraform apply(Команда создаст бакет для хранения tfstate).
- Перейти в директорию stage. Создать terraform.tfvars из terraform.tfvars.example, указать свой проект и заполнить другие переменные. Если необходимо добавить provisioners, указать переменную provisioner_condition = 1.
- Выполнить terraform init и terraform apply(Команда создаст инфраструктуру с приложением).

# HW-8
## В процессе сделано
- Интегрировал своё окружение на Windows с Linux. Git остался на Windows, в Linux подключил раздел по cifs.
- Установили Python2.7, pip, Ansible.
- Заполнили инвентори в формате ini, конфиг, попинговали хосты.
- Перевели инвентори в формат YAML.
- Сравнили shell/command, command/service/systemd, command/git.
- Написали просто плейбук на git clone. См. наблюдения в следующем пункте.
- Ознакомились с форматом JSON инвентори. Используется для автоматизации получение инвентори.
- Два формата. Практически плоский JSON со ссылочной структурой родитель-ребёнок и JSON с иерархической структурой (копия YAML). Первый нужно "скормить" Ansible в виде исполняемого скрипта, который возвращает JSON, второй возможно "скормить" в виде файла (команды см. в п. ниже).

## Выполнение простого плейбука.
- Первый раз выполнили плейбук, когда приложение уже было склонировано. Ansible вернул по всем шагам OK. Удалили склонированный репозиторий и снова выполнили ту же команду. Ansible вернул changed по задаче клонирования репозитория.

## Команды для использования JSON инвентори.
```
ansible app -m ping -i get-inventory.sh
ansible app -m ping -i inventory.json
```

## Как проверить работоспособность.
- Забрать ветку ansible-1.
- Перейти в директорию terraform/stage
- Выполнить terraform init && terraform apply, получить IP адреса (ключи пользователя appuser должны быть в домашней директории ~/.ssh).
- Заменить IP адреса из инвентори (8.8.8.8 и 9.9.9.9).
- Выполнить команды из п. выше.

# HW-9
## В процессе сделано.
- Добавили в gitignore маску для временных файлов Ansible.
- Написали playbook с одним task внутри. Запускали, фильтруя этапы таска по тэгам, а хосты ключом --limit.
- Переписали playbook на несколько тасков. В каждый добавили ограничение по тэгам. Фильтр по --limit больше не нужен.
- Разбили три таска на три playbook: app.yml, db.yml, deploy.yml и директивой import_playbbok добавили их в корневой playbook.
- Изменили provisioners в packer с баш-скриптов на Ansible и пересобрали образы.
- Про выбор dynamic inventory написал в следующем пункте.
- Чтобы dynamic inventory заработал, я изменил hosts в наших playbook на те, которые описаны в GCP (reddit-app, reddit-db).
- Чтобы вручную не конфигурить внутренний адрес монги, научился работать с хостовыми перменными "{{ hostvars['reddit-db']['gce_private_ip'] }}".

## Подбор метода получения инвентори из GCP.
- В качестве dynamic inventory я выбрал gce.py. Кроме этого популярного решения на python были варианты получать инвентори через TF. Завязываться на TF я посчитал излишним. Все эти решения одинаковы с точки зрения функционала для наших нужд. Директорию с настройками div_env я целиком добавил в gitignore.

## Как проверить работоспособность.
- Забрать ветку ansible-2.
- Перейти в корневую директорию и выполнить
```
packer build packer/app.json
packer build packer/db.json
```
- Перейти в директорию terraform/stage.
- Выполнить terraform init && terraform apply (ключи пользователя appuser должны быть в домашней директории ~/.ssh). Запомнить app_external_ip.
- Настроить gce dynamic inventory и положить его в директорию dyn_inv.
- Перейти в директорию ansible и выполнить ansible-playbook site.yml.
- Перейти в браузере по ссылке http://app_external_ip:9292.

# HW-10
## В процессе сделано.
- Создали роли для db и app.
- Прикрутил dynamic inventory. Скрипт и ini файл лежит в директориях prod и stage. Не увере, что это правильно, но по-другому не читаются переменные group_var и host_vars.
- Создали структуру environments. В директориях stage и prod свои inventory, свои переменные (group_vars, host_vars). gce.py группирует хосты, создавая тэги tag_hostname.
- Распределили таски, хэндлеры, переменные и т.д. по структуре директорий роли. defaults - переменные по-умолчанию; files; handlers; meta - метаинформация, зависимости; tasks - таски; templates - шаблоны; tests; vars; Переменные задаются в директории environments для каждого окружения.
- Добавили переменную env, чтобы при выполнении playbook всегда видеть, на каком окружении он выполняется.
- Переместили playbooks в отдельную директорию.
- Переместили устаревшие данные в директорию old.
- Добавили вывод diff.
- Добавили роль nginx из ansible-galaxy и настроили на проксирование с 80 порта. Открыли 80 порт в TF. Не стали закрывать порт 9292.
- Создали пользователей на виртуалках, зашифровав credentials.yml с помощью ansible-vault.
- Добавили инфраструктурные тесты: packer validate, terraform validate, tflint, ansible-lint
- Badge со статусом билда добавил только для ветки master. Ветка хардкодится в ссылке в README. Варианты решения: 1. добавлять ссылку на свой сервис, который по хэдеру запроса сформирует ссылку на бэйдж и добавить в README; 2. Сделать precommit hook, который будет заменять ссылку на бэйдж в тревисе при каждом коммите. Вариант 1 не подходит из-за своей костыльности. Вариант 2 подходит. В жизни долгоживущие ветки создаются редко и для них так и так README пишутся вручную, поэтому можно забить динамически формировать ссылку на бэйдж :)

## Как проверить работоспособность.
- Забрать ветку ansible-3.
- Перейти в директорию terraform/stage.
- Выполнить terraform init && terraform apply (ключи пользователя appuser должны быть в домашней директории ~/.ssh). Запомнить app_external_ip.
- Настроить gce dynamic inventory и положить его в директорию stage и prod.
- Перейти в директорию ansible и выполнить ansible-playbook site.yml.
- Перейти в браузере по ссылке http://app_external_ip:80.
- Залогиниться на виртуалки под пользователем appuser, выполнить su user_name. Ввести password. Явки-пароли взять из ДЗ.
13 changes: 13 additions & 0 deletions ansible/ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[defaults]
inventory = ./environments/stage/gce.py
remote_user = appuser
private_key_file = ~/.ssh/appuser
host_key_checking = False
retry_files_enabled = False
roles_path = ./roles
vault_password_file = ~/.ansible/vault.key

[diff]
# Включим обязательный вывод diff при наличии изменений и вывод 5 строк контекста
always = True
context = 5
9 changes: 9 additions & 0 deletions ansible/environments/prod/credentials.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$ANSIBLE_VAULT;1.1;AES256
66363930393961323363303366373837323132633263363266646636633836383937393037376562
3130326235366161373062653732303632666461383431640a343333663937333839643564343439
31363530316230363034343964666566373761663565333438323439393632313765663236356639
3732316230336138620a623965313833353839626337303335343137336537663764373266396135
34373866333238343561643866396238613632636236633464643334373263393532306166393965
35303230616633366235303662333130333162346663653837393631323937333739643436626233
66363366323132626433656463626262656634333032336138643664396136376534643339623533
38383732343364336133
1 change: 1 addition & 0 deletions ansible/environments/prod/group_vars/all
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
env: stage
1 change: 1 addition & 0 deletions ansible/environments/prod/group_vars/tag_reddit-app
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
db_host: "{{ hostvars['reddit-db']['gce_private_ip'] }}"
1 change: 1 addition & 0 deletions ansible/environments/prod/group_vars/tag_reddit-db
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mongo_bind_ip: 0.0.0.0
2 changes: 2 additions & 0 deletions ansible/environments/prod/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- src: jdauphant.nginx
version: v2.21.1
11 changes: 11 additions & 0 deletions ansible/environments/stage/credentials.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
$ANSIBLE_VAULT;1.1;AES256
30626266346137626461633261643639356234646638396433343762373634656634313132303165
6131313065353764326266366561383337666630313766340a313130316235346239343431626337
36396566616231613730636463643430336437353438663130613136636430396162326133616430
6639333836333262630a366338363835313534396331356464363537333562373736373437356331
34633634613834643031363032343933323431373262643566373034383037656437666232316661
34623633643231356231346634636638366562343734333166613661313066366561303734613737
37316232643636653265646231343135303635353734323261393831363833313137646561666161
34363162353036303762663139366262316439363335613762616366316564363736636431393365
33343034653165376634616231396662643262373838343231373562616333313066643239623137
3730343132393566393037383462396130333238663366353339
1 change: 1 addition & 0 deletions ansible/environments/stage/group_vars/all
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
env: stage
6 changes: 6 additions & 0 deletions ansible/environments/stage/group_vars/tag_reddit-app
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
db_host: "{{ hostvars['reddit-db']['gce_private_ip'] }}"
nginx_sites:
default:
- listen 80
- server_name "reddit"
- location / { proxy_pass http://127.0.0.1:9292; }
1 change: 1 addition & 0 deletions ansible/environments/stage/group_vars/tag_reddit-db
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mongo_bind_ip: 0.0.0.0
2 changes: 2 additions & 0 deletions ansible/environments/stage/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- src: jdauphant.nginx
version: v2.21.1
14 changes: 14 additions & 0 deletions ansible/files/puma.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=Puma HTTP Server
After=network.target

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

[Install]
WantedBy=multi-user.target
2 changes: 2 additions & 0 deletions ansible/old/get-inventory.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
cat inventory2.json
16 changes: 16 additions & 0 deletions ansible/old/inventory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"app": {
"hosts": {
"appserver": {
"ansible_host": "8.8.8.8"
}
}
},
"db": {
"hosts": {
"dbserver": {
"ansible_host": "9.9.9.9"
}
}
}
}
9 changes: 9 additions & 0 deletions ansible/old/inventory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
app:
hosts:
appserver:
ansible_host: 8.8.8.8

db:
hosts:
dbserver:
ansible_host: 9.9.9.9
23 changes: 23 additions & 0 deletions ansible/old/inventory2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"app": {
"children": [
"appserver",
"dbserver"
]
},
"db": {
"children": [
"dbserver"
]
},
"appserver": {
"hosts": [
"8.8.8.8"
]
},
"dbserver": {
"hosts": [
"9.9.9.9"
]
}
}
59 changes: 59 additions & 0 deletions ansible/old/reddit_app_multiple_plays.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
- name: Configure MongoDB
hosts: db
tags: db-tag
become: true
vars:
mongo_bind_ip: 0.0.0.0
tasks:
- name: Change mongo config file
template:
src: templates/mongod.conf.j2
dest: /etc/mongod.conf
mode: 0644
notify: restart mongod

handlers:
- name: restart mongod
service: name=mongod state=restarted


- name: Configure App
hosts: app
tags: app-tag
become: true
vars:
db_host: 10.132.0.2
tasks:
- name: Add unit file for Puma
copy:
src: files/puma.service
dest: /etc/systemd/system/puma.service

- name: Add config for DB connection
template:
src: templates/db_config.j2
dest: /home/appuser/db_config
owner: appuser
group: appuser

- name: enable puma
systemd: name=puma enabled=yes
- name: Deploy App
hosts: app
tags: deploy-tag
tasks:
- name: Fetch the latest version of application code
git:
repo: 'https://github.com/express42/reddit.git'
dest: /home/appuser/reddit
version: monolith
notify: reload puma
- name: Bundle install
bundler:
state: present
chdir: /home/appuser/reddit
handlers:
- name: reload puma
become: true
systemd: name=puma state=restarted
Loading