Содержание
В современном мире быстро меняющихся релизов и распределенных команд, работающих по гибкому графику, важность автоматического развертывания невозможно переоценить. В этом руководстве я проведу вас через шаги по настройке CircleCi и Ansible для автоматического развертывания на AWS EC2.
Необходимые условия
Чтобы извлечь максимальную пользу из этого руководства и следовать ему, вам будет полезно иметь:
- Базовый опыт программирования и умение работать с командной строкой.
- Аккаунт на Github и доступ к командной строке с установленным git.
- Аккаунт AWS с настроенным сервером EC2.
- Учетная запись CircleCI.
- Редактор кода.
Этот учебник будет посвящен только настройке и развертыванию, мы не будем настраивать новые серверы. Я буду использовать бэкенд-сервер, который я написал некоторое время назад. Стартовый код можно найти здесь. Создайте форк и клонируйте репозиторий. Переключитесь на ветку starter, чтобы следовать дальше.
Настройка CircleCI
Перейдите на сайт circleci.com и войдите в систему. Убедитесь, что вы находитесь в своей личной организации. На странице “Проекты” найдите репо aws_ec2_auto_deploy и просто нажмите “Установить проект”. Выберите опцию “Use the . circleci/config. yml in my repo” и настройте проект. Настройте переменные окружения проекта, скопировав значения по умолчанию из файла .env.example в Project Settings > Environment Variables на панели управления проектом CircleCI. Теперь перейдем к делу.
Написание config.yml
Откройте в редакторе файл config.yml в папке .circleci.
CircleCI использует YAML-файлы для настройки конвейеров, которые обычно состоят из следующих блоков YAML-кодов:
Блок YAML Описание
version
Здесь указывается версия CircleCI API, которую вы хотите использовать
команды
Содержит список команд, которые можно использовать повторно
orbs
Позволяет использовать определенные заранее написанные функции в задании
jobs
Список заданий
workflow
Определяет порядок выполнения заданий
Перед развертыванием кода на серверах рекомендуется убедиться, что все тесты пройдены. Обновите файл config.yml с помощью приведенного ниже кода.
version: 2.1
jobs:
test:
docker:
- image: cimg/node:16.17.0
- image: redis
name: redis
- image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 12345
MYSQL_DATABASE: lend
MYSQL_USER: abuchikings
MYSQL_PASSWORD: 12345
steps:
- checkout
- restore_cache:
keys: [packages]
- run:
name: Test MySQL connection
command: |
for i in $(seq 1 30); do
nc -z 127.0.0.1 3306 && echo Success && exit 0
echo -n .
sleep 1
done
echo Failed waiting for MySQL && exit 1
- run:
name: Run tests
command: |
npm install
npm run migrate:latest
npm run test
- save_cache:
paths: ['./node_modules']
key: packages
workflows:
default:
jobs:
- test
Вот описание того, что происходит в приведенном выше коде:
Ключевое слово jobs указывает на то, что блок кода будет содержать задания.
Самое первое задание называется test, а ключевое слово docker указывает CircleCI, что это задание будет выполняться в среде docker.
-
cimg/node- это официальный образ nodejs от CircleCI на хабе docker. Для данного проекта используется Node версии 16.17.0. Для тестирования приложения требуется база данных MySQL 8.0 и redis. -
steps: Как следует из названия, определяет шаги, необходимые для выполнения определенного задания. -
checkout: Проверяет исходный код из вашего репозитория контроля версий. -
restore_cache: Восстанавливает кэшированные зависимости. Кэширование - это механизм, который позволяет сохранять и повторно использовать зависимости (например, пакеты npm) для ускорения процесса сборки. В данном случае восстанавливаются кэшированные пакеты npm. -
run: Этот шаг запускает серию команд. Он отвечает за выполнение фактических задач CI. -
name: Это описательное имя для данного шага, указывающее на то, что следующие команды связаны с запуском тестов. -
команда: Указывает команды, которые будут выполняться. Символ|используется для определения многострочного командного блока, что позволяет выполнять несколько команд в рамках этого шага. Первая команда использует утилитуnc(netcat) для проверки доступности сервера баз данных MySQL, работающего на localhost (127.0.0.1) и прослушивающего порт 3306. Вторая команда запускает миграцию и автоматические тесты на коде. -
save_cache: Это встроенная команда CircleCI, используемая для сохранения кэшированных зависимостей или артефактов. Она гарантирует, что указанные файлы или каталоги будут сохранены в кэше для будущих сборок. -
workflows: Этот раздел определяет один или несколько рабочих процессов. Рабочий процесс - это серия заданий, которые должны быть выполнены в определенном порядке или при определенных условиях.
Теперь вы можете зафиксировать свои изменения и отправить их в удаленный репозиторий. Перейдите на приборную панель CircleCI, чтобы увидеть, как работает ваш конвейер.
Затем обновите свой config.yml с помощью задания setup_ansible, приведенного ниже. Не забудьте также обновить рабочий процесс, как показано в фрагменте кода ниже.
setup_ansible:
docker:
- image: amazon/aws-cli
steps:
- checkout
- run:
name: Install dependencies
command: |
yum install -y tar gzip
- run:
name: Add Backend IP To Ansible
command: |
backendIP=$(aws ec2 describe-instances \
--query "Reservations[*].Instances[*].PublicIpAddress" \
--filters "Name=tag:Name,Values=ec2_auto_deploy_test" \
--output text)
echo "$backendIP" >> ~/project/.circleci/ansible/inventory.txt
- persist_to_workspace:
root: ~/
paths:
- project/.circleci/ansible/inventory.txt
workflows:
default:
jobs:
- test
- setup_ansible:
requires: [test]
Не забудьте изменить ec2_auto_deploy_test на имя вашего EC2-сервера на AWS.
Задание setup_ansible использует aws-cli для получения IP-адреса сервера EC2 с тегом имени ec2_auto_deploy_test. IP-адрес сохраняется в файле inventory.txt в папке Ansible и сохраняется в рабочей области для использования следующим заданием. Для сохранения файла в рабочую область требуются утилиты tar и gzip.
Перед отправкой изменений на github перейдите на страницу проекта на CircleCI => Настройки проекта => Переменные окружения и добавьте следующие переменные окружения:
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
AWS_ACCESS_KEY_ID
которые можно получить из вашей учетной записи aws.
Последняя конфигурация задания в файле config.yml будет отвечать за выполнение плейбука Ansible, который использует ssh для доступа к серверу, извлекает код с github и собирает обновленный образ docker. Смотрите код ниже.
deploy_server:
docker:
- image: python:3.11.6-alpine3.18
steps:
- checkout
- add_ssh_keys:
fingerprints: ['9f:66:26:48:fd:251:62:5d:73:c4:d5:90:2b']
- attach_workspace:
at: ~/
- run:
name: Install dependencies
command: |
apk add --update ansible openssh-client
eval $(ssh-agent -s)
print("Dependencies installed") # Logging statement
- run:
name: Deploy Server
command: |
cd ~/project/.circleci/ansible
echo "Contents of the inventory.txt -------"
cat inventory.txt
print("Starting server deployment") # Logging statement
ansible-playbook -i inventory.txt deploy-server.yml
print("Server deployment completed") # Logging statement
На странице настроек проекта CircleCI перейдите в раздел SSH Keys, добавьте новый ssh-ключ, скопировав и вставив ssh-ключ для вашего сервера EC2. При этом будет сгенерирован отпечаток ключа. Скопируйте отпечаток ключа SSH и замените fingerprints в задании deploy_server.
Также обновите рабочий процесс, добавив следующий код:
workflows: default: jobs: - test - setup_ansible: requires: [test] - deploy_server: requires: [setup_ansible].
Настройка Ansible
Ansible - это мощный инструмент автоматизации с открытым исходным кодом и система управления конфигурациями, которая упрощает и облегчает автоматизацию рутинных ИТ-задач и управление сложными системами. Он предоставляет ИТ-специалистам основу для определения и выполнения задач автоматизации с помощью человекочитаемых сценариев.
С помощью Ansible можно автоматизировать инициализацию, конфигурирование, развертывание и обслуживание серверов, приложений и различных компонентов инфраструктуры. Вам следует ознакомиться с документацией Ansible, чтобы узнать больше об этом интересном инструменте автоматизации.
Написание книги воспроизведения
Для автоматизации Ansible мы используем простые YAML-файлы, называемые плейбуками, чтобы определить задачи автоматизации. Ниже показана древовидная структура папки Ansible, в которой содержится книга воспроизведения, которую нужно выполнить.
├──── ansible │ ├──── ansible.cfg │ ├──── deploy-server.yml │ ├──── inventory.txt │ └──── roles │ └──── deploy │ └──── tasks │ └──── main.yml └──── config.yml.
Ниже приводится описание каждого файла и его функции:
-
ansible.cfg: Конфигурационный файл, используемый для настройки поведения Ansible. Он позволяет переопределить встроенные параметры конфигурации, такие как параметры SSH-соединения, файл инвентаризации по умолчанию, определить привилегии удаленных пользователей и т.д. -
deploy-server.yml: Это игровой учебник Ansible. Он определяет набор задач или задание для выполнения на удаленных узлах. В этом проекте я использовал роли для определения задач плейбука. -
inventory.txt: Это важный компонент Ansible для определения хостов и групп хостов, которыми будет управлять Ansible. Это конфигурационный файл, в котором указываются удаленные серверы или системы, на которых будут выполняться задачи и плейбуки Ansible. В этом файле перечислены IP-адреса серверов или машин, которыми будет управлять Ansible. -
роли: Роли - это способ организации и структурирования задач, обработчиков, переменных и другого содержимого для лучшего повторного использования и сопровождения кода. Здесь содержатся задачи, которые будут выполняться в плейбуках. Эти задачи определяются в файлеmain.yml.
Обновите файл deploy-server.yml, добавив в него следующий код:
--- - name: "Deploy Play" hosts: web user: ubuntu gather_facts: false vars: - ansible_python_interpreter: /usr/bin/python3 - ansible_host_key_checking: false - ansible_stdout_callback: yaml roles: - deploy.
-
name: Это пользовательское имя для данного плейбука, которое облегчает нам понимание его работы. -
hosts: Здесь указываются целевые хосты или группа хостов, на которых будут выполняться задания в этом плейбуке. В данном случае задано значение web. Когда вы открываете файлinventory.txt, он содержит единственную строку,[web]. Она определяет хостГруппа называетсяweb, а все IP-адреса, перечисленные в разделе[web], являются хостами или удаленными машинами, которыми мы хотим управлять с помощью Ansible. Чтобы добавить IP-адрес в инвентарь, мы используемaws-cliв заданииsetup_ansibleдля получения IP-адреса нашего сервера EC2 и динамического обновления файла инвентаря. -
user: Здесь указывается удаленный пользователь, которого Ansible должен использовать при подключении к целевым узлам. В данном случае этоubuntu. Вам может понадобиться изменить это значение, если ваш пользователь ssh другой. -
gather_facts: Указывает Ansible, собирать ли факты о целевых узлах, такие как сведения об оборудовании, конфигурации сети и т. д. Здесь установлено значение false, чтобы повысить скорость выполнения плейбука.
vars: Здесь определяются переменные, которые будут использоваться в плейбуке. ansible_python_interpreter определяет python intepreter, который Ansible должен использовать при выполнении заданий на хосте. ansible_host_key_checking имеет значение false, чтобы отключить проверку ключей хоста. Проверка ключа хоста - это подсказка, которая появляется в командной строке, когда вы впервые выполняете вход ssh на сервер с ключом. Это мера безопасности, позволяющая убедиться в идентичности удаленного хоста.
roles: Здесь указывается, какие роли должны быть включены в это задание. В данном случае это роль с именем deploy. При выполнении плейбука Ansible будет искать каталог с именем “deploy” по пути roles и выполнять задачи и конфигурации, определенные в этой роли. Давайте напишем задачи для роли deploy.
Скопируйте приведенный ниже код в файл main.yml в папке роли deploy/tasks.
---
- name: Perform Git Pull
become: false
git:
repo: git@github.com:AbuchiKings/aws_ec2_auto_deploy.git
dest: ~/apps/aws_ec2_auto_deploy
accept_hostkey: yes
clone: false
version: main
- name: Run Docker build
become: true
command:
cmd: make "{{ item }}"
chdir: apps/aws_ec2_auto_deploy
loop:
- down
- up-d
Первая задача использует модуль Ansible git для выполнения git pull из git-репозитория проекта.
become - это булево поле, которое указывает Ansible на выполнение задачи в качестве пользователя root.
dest - это место назначения или каталог, куда должны быть добавлены извлеченные элементы.
Чтобы предотвратить свежее клонирование репозитория, clone имеет значение false.
version определяет ветку, из которой будет производиться извлечение.
Во второй задаче команда make используется с двумя разными аргументами, заданными в Makefile в корневой папке проекта:
down, который соответствует docker-compose -f docker-compose.yml -f docker-compose.prod.yml down, завершает работу текущего запущенного контейнера.
up-d, которая соответствует docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build, запускает контейнер с новой сборкой в отсоединенном режиме.
Наконец, зафиксируйте изменения и отправьте их в удаленный репозиторий.
Заключение
Это ни в коем случае не исчерпывающее руководство по CircleCi и Ansible. Существует широкий спектр задач автоматизации, которые можно выполнять с помощью Ansible. Тем не менее, я надеюсь, что вы найдете его полезным. Спасибо за уделенное время.