Сучасна розробка програмного забезпечення вимагає безперешкодних та ефективних процесів розгортання. Ця стаття розглядає, як принципи GitOps, у поєднанні з Terraform, GitHub Actions та Amazon EKS, дозволяють автоматизувати, масштабувати та забезпечувати надійне розгортання додатків. Дізнайтесь, як ці інструменти працюють разом, щоб спростити робочі процеси та забезпечити гнучке постачання.
Схема архітектури
Використовувані інструменти та технології
У цьому проєкті GitOps ми будемо використовувати наступні інструменти DevOps та AWS Cloud для досягнення мети:
- GitHub — для зберігання коду нашого додатка, коду CICD pipeline та коду автоматизації хмар.
- Maven — для компіляції нашого коду в розгортаємий артефакт .war.
- Sonarcloud — для проведення тестів коду.
- Docker — для створення образу додатка.
- Amazon ECR — для зберігання образу додатка.
- Helm Charts — для керування розгортаннями в нашому EKS кластері.
- Amazon EKS — для розгортання нашого додатка в контейнеризованому середовищі.
Зверніть увагу, що є два робочих процеси:
- Процес Terraform застосовує зміни інфраструктури.
- Процес CICD для додатка застосовує зміни додатка.
Тож, давайте почнемо!
1. Підготовка GitHub репозиторіїв
● Форкайте цей GitHub репозиторій для Terraform pipeline до вашого облікового запису GitHub. Переконайтесь, що форкнули обидва гілки: Main і Stage.
● Форкайте цей другий GitHub репозиторій для App CICD. Цей репозиторій містить лише одну гілку — Main.
● Створіть SSH ключ для безпечного доступу до вашого Git репозиторію на локальному комп’ютері.
○ У вашому терміналі, cd ~./ssh для створення пари приватного та публічного ключів.
○ Виконайте команду ssh-keygen для створення пари ключів.
○ Скопіюйте ваш публічний ключ до розділу SSH ключів на GitHub.
○ Далі, виконайте export GITSSHCOMMAND=”ssh -i ~/.ssh/”, щоб налаштувати Git на використання вашого конкретного приватного ключа.
● Створіть і перейдіть в директорію на вашому локальному комп’ютері, де ви будете клонувати Git репозиторії.
● Клонуйте обидва репозиторії GitHub, які ви форкнули раніше, в створену директорію на вашому локальному комп’ютері.
● На цьому етапі зробіть копію директорії “iac-vprofile”. Це потрібно для створення резервної копії цієї ж директорії.
● Перейдіть в директорію iac-vprofile, а потім перемкніться на гілку “stage”. Тут будуть вноситися зміни, поки ми не будемо готові об’єднати їх з гілкою “Main” для остаточних змін конфігурації.
2. GitHub Actions Secrets
Secrets в GitHub Actions — це зашифроване сховище для чутливої інформації, що використовується в робочих процесах. Ми використовуємо їх для безпечного доступу до ресурсів AWS без розкриття наших логінів публічно. Для налаштування цих секретів для наших двох GitHub репозиторіїв:
● Увійдіть в свій обліковий запис AWS та створіть нового користувача IAM.
● Для простоти надамо цьому новому користувачу політику "AdministratorAccess".
● Після створення користувача згенеруйте для нього Access Key.
● Додайте згенерований Access Key до GitHub Secrets. Для цього виконайте наступні кроки:
Відкрийте ваш Git Repo → “Settings” → “Secrets and Variables” → “Actions” → “New Repository Secret”
● Тут створіть і скопіюйте ваші AWSACCESSKEYID та AWSSECRETACCESSKEY.
● Налаштуйте ці Git Actions secrets для обох ваших репозиторіїв: IaC-Vprofile та VProfile-Action.
3. Створення S3 бакету для зберігання даних Terraform
Нам потрібно створити S3 бакет, який буде зберігати файли стану Terraform.
State files (файли стану) — це компоненти, які відстежують стан вашої інфраструктури, що керується через Terraform. Вони зберігають інформацію про ресурси та конфігурації, дозволяючи Terraform зрозуміти поточний стан вашої інфраструктури та визначити будь-які зміни, які необхідно здійснити під час наступних операцій.
Виконайте наступні дії:
● Перейдіть до сервісу “S3”.
● Створіть новий S3 бакет і надайте йому відповідну назву.
● Після створення S3 бакету, перейдіть до розділу “Actions Secrets” вашого репозиторію “IaC-Vprofile” і додайте новий секрет. Назвіть його “BUCKETTFSTATE” та у секції Secret* вставте ім’я вашого S3 бакету.
4. Створення ECR
Тепер створимо Elastic Container Registry (ECR) для зберігання наших Docker образів.
● Перейдіть до сервісу “ECR” в AWS.
● Створіть новий реєстр ECR.
● Скопіюйте URI створеного ECR.
● Перейдіть на сторінку Actions Secrets репозиторію “Vprofile-Action” і додайте новий секрет. Назвіть його “REGISTRY” та вставте URI ECR у секцію Secret*.
5. Код Terraform
● Відкрийте директорію “IaC-Vprofile” у вашому редакторі коду. Переконайтесь, що ви на гілці “Staging”.
● Перейдіть до директорії “Terraform”, де вже є кілька скриптів.
● Змініть наступні скрипти:
○ У файлі “variables.tf” змініть назву AWS регіону та EKS кластеру відповідно.
○ У файлі “terraform.tf” відредагуйте секцію backend s3, вказавши ім’я, ключ та регіон вашого S3 бакету.
● Зробіть коміт і запуште ці зміни в ваш Git репозиторій.
6. Робочий процес для Terraform коду на етапі Staging
● У директорії IaC-Vprofile на вашому локальному комп’ютері створіть директорію “.github\workflows”. Ця директорія містить робочі процеси GitHub Actions. Файли, що зберігаються тут, визначають конкретні дії, які GitHub виконає на основі подій чи тригерів.
● У директорії “.github\workflows” створіть файл сценарію з назвою “terraform.yml”.
● Вставте наступний код у цей сценарій:
name: "Vpofile IAC"
on:
push:
branches:
- main
- stage
paths:
- terraform/**
pull_request:
branches:
- main
paths:
- terraform/**
env:
#Credentials for deployment to AWS
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
#S3 bucket for Terraform state
BUCKET_TF_STATE: ${{ secrets.BUCKET_TF_STATE }}
AWS_REGION: us-east-1
EKS_CLUSTER: vprofile-eks
jobs:
terraform:
name: "Apply terraform code changes"
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./terraform
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Set up Terraform with specified version on the runner
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.6.3
- name: Terraform init
id: init
run: terraform init -backend-config="bucket=$BUCKET_TF_STATE"
- name: Terraform format
id: fmt
run: terraform fmt -check
- name: Terraform validate
id: validate
run: terraform validate
- name: Terraform plan
id: plan
run: terraform plan -no-color -input=false -out planfile
continue-on-error: true
- name: Terraform plan status
if: steps.plan.outcome == 'failure'
run: exit 1
● Зробіть коміт і запуште зміни до вашого віддаленого GitHub репозиторію.
● У вкладці “Actions” вашого GitHub репозиторію ви побачите статус виконаного робочого процесу.
● Зверніть увагу, що на даному етапі зміни знаходяться в гілці staging, тому реальні зміни конфігурації ще не були застосовані, поки ми не впровадимо їх у гілку Main.
Основний робочий процес для коду Terraform
● У вашому файлі сценарію terraform.yml додайте наступні зміни, які будуть виконуватись тільки при тригері PUSH до гілки Main:
- name: Terraform Apply
id: apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: terraform apply -auto-approve -input=false -parallelism=1 planfile
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Get Kube config file
id: getconfig
if: steps.apply.outcome == 'success'
run: aws eks update-kubeconfig --region ${{ env.AWS_REGION }} --name ${{ env.EKS_CLUSTER }}
- name: Install Ingress controller
if: steps.apply.outcome == 'success' && steps.getconfig.outcome == 'success'
run: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/aws/deploy.yaml
● Зробіть коміт і запуште зміни до вашого репозиторію на GitHub.
● На цьому етапі гілка “Stage” вашого репозиторію “IaC-Vprofile” повністю оновлена. Для того, щоб застосувати зміни інфраструктури, потрібно злити гілку staging з гілкою Main.
● Для цього відкрийте термінал на вашому локальному комп'ютері, де збережені два репозиторії.
● Перейдіть до вашого репозиторію “IaC” та виконайте checkout на гілку Main.
● Будучи на гілці Main, запустіть git merge stage, щоб з'єднати гілку staging з гілкою Main.
● В кінці запуште зміни в гілці Main до вашого віддаленого репозиторію на GitHub. Зверніть увагу, що це автоматично викликає робочий процес GitHub Actions і застосує визначені зміни інфраструктури в вашому середовищі AWS.
● Щоб підтвердити, що зміни, визначені в робочому процесі GitHub Actions, були застосовані:
○ Увійдіть до вашого облікового запису AWS.
○ Перевірте створення EKS кластеру.
○ Підтвердіть, що створено VPC та відповідні підмережі (як було визначено в раніше створених terraform скриптах).
○ Перевірте, чи були створені EC2 інстанси та ELB.
EKS кластер
VPC
EC2 інстанси
8. Робочий процес для коду програми Vprofile
● Увійдіть до вашого облікового запису на SonarCloud.io та створіть нову організацію.
● Створіть новий проєкт і дайте йому відповідну назву.
● Створіть токен в вашому обліковому записі SonarCloud, який буде використовуватись GitHub для доступу до вашої служби SonarCloud.
● Додайте цей токен SonarCloud до GitHub Secrets.
● Додайте наступні два секрети:
○ SONAR_ORGANIZATION
○ SONARPROJECTKEY
○ SONAR_URL
● У директорії вашого репозиторію “Vprofile-Action” на локальному комп'ютері створіть директорію “.github\workflows” і файл з назвою “main.yml”.
Це буде наш сценарій робочого процесу GitHub Actions.
● Вставте наступний код у файл main.yml:
name: vprofile actions
on: workflow_dispatch
env:
AWS_REGION: us-east-1
ECR_REPOSITORY: vprofileapp254
EKS_CLUSTER: vprofile-eks
jobs:
Testing:
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
- name: Maven test
run: mvn test
- name: Checkstyle
run: mvn checkstyle:checkstyle
# Налаштування Java 11 за замовчуванням (вимога для sonar-scanner з версії 5.x)
- name: Set Java 11
uses: actions/setup-java@v3
with:
distribution: 'temurin' # Дивіться 'Supported distributions' для доступних варіантів
java-version: '11'
# Налаштування sonar-scanner
- name: Setup SonarQube
uses: warchant/setup-sonar-scanner@v7
# Запуск sonar-scanner
- name: SonarQube Scan
run: sonar-scanner
-Dsonar.host.url=${{ secrets.SONAR_URL }}
-Dsonar.login=${{ secrets.SONAR_TOKEN }}
-Dsonar.organization=${{ secrets.SONAR_ORGANIZATION }}
-Dsonar.projectKey=${{ secrets.SONAR_PROJECT_KEY }}
-Dsonar.sources=src/
-Dsonar.junit.reportsPath=target/surefire-reports/
-Dsonar.jacoco.reportsPath=target/jacoco.exec
-Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml
-Dsonar.java.binaries=target/test-classes/com/visualpathit/account/controllerTest/
# Перевірка статусу Quality Gate.
- name: SonarQube Quality Gate check
id: sonarqube-quality-gate-check
uses: sonarsource/sonarqube-quality-gate-action@master
# Примусове завершення кроку після певного часу.
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_URL }} #OPTIONAL
BUILD_AND_PUBLISH:
needs: Testing
runs-on: ubuntu-latest
steps:
- name: Code checkout
uses: actions/checkout@v4
- name: Build & Upload image to ECR
uses: appleboy/docker-ecr-action@master
with:
access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
registry: ${{ secrets.REGISTRY }}
repo: ${{ env.ECR_REPOSITORY }}
region: ${{ env.AWS_REGION }}
tags: latest,${{ github.run_number }}
daemon_off: false
dockerfile: ./Dockerfile
context: ./
● Зробіть коміт і запуште зміни.
● Оскільки ми налаштували робочий процес на виконання лише за допомогою “workflow_dispatch”, перейдіть до вашого репозиторію Vprofile-Actions на GitHub і, в розділі “Actions”, запустіть робочий процес вручну.
● SonarCloud перевірить код на відповідність специфікаціям Quality Gates. У нашому випадку, якщо кількість помилок менше ніж 50, тест буде успішним.
● В розділі GitHub Actions ви можете переглянути робочий процес і перевірити, чи були обидва завдання виконані успішно.
● Перевірте ваше сховище ECR на AWS, щоб побачити, чи з'явився Docker-образ, створений за допомогою цього робочого процесу.
9. Розгортання в Elastic Kubernetes Service (EKS)
● Встановіть Helm Charts на ваш локальний комп'ютер.
● Якщо ви на Windows, виконайте choco install kubernetes-helm в PowerShell (обов'язково запустіть як адміністратор).
● Перейдіть до терміналу в репозиторії Vprofile-Actions і виконайте команду: helm create vprofilecharts.
Helm charts містять конфігурації та ресурси, необхідні для розгортання додатків на Kubernetes.
● Видаліть файли за замовчуванням у каталозі helm/vprofilecharts/templates/* репозиторію та скопіюйте всі файли з kubernetes/vpro-app/* туди замість цього.
● У файлі vproappdep.yml змініть тег образу так, щоб його значення бралося з змінної, що зберігається у файлі робочого процесу main.yml, як показано нижче. Це забезпечить, щоб розгортання завжди працювало з останнім створеним образом.
● Перевірте, що все правильно, потім зробіть коміт і запуште зміни до репозиторію на GitHub.
● Перейдіть до GitHub Actions і запустіть робочий процес.
● Це має розгорнути додаток в EKS кластері.
● Тепер додаток має бути доступний або з кінцевої точки ELB, або з вашого доменного імені, як зазначено в файлі vproingress.yml.
● Це позначає завершення успішного розгортання додатка на EKS кластері за допомогою робочих процесів GitHub Actions.
P.S: Після завершення проекту не забудьте очистити ресурси, щоб не залишити працюючі ресурси в AWS, що можуть бути дуже дорогими.
Висновок
У цьому проекті з розгортання додатка ми успішно автоматизували створення хмарної інфраструктури на AWS за допомогою Terraform, а також збірку, тестування та розгортання нашого додатка через робочі процеси GitHub Actions. Такий рівень автоматизації не лише оптимізує процеси, але й підвищує ефективність, безпеку та точність, зменшуючи ймовірність помилок через людський фактор.
Використання GitHub Actions як CI/CD конвеєра прискорює цикли розробки, забезпечує надійне керування версіями та посилює практики безпеки. Тим часом використання інструментів для інфраструктури як коду (IaC) таких як Terraform дозволяє забезпечити консистентність, повторюваність і масштабованість у різних середовищах, спрощує управління станом та забезпечує безшовну підтримку на кількох платформах. Разом ці інструменти демонструють потужність сучасних практик DevOps для досягнення ефективних і надійних розгортань.
Перекладено з: Streamlining Application Deployment: GitOps with Terraform, GitHub Actions, and AWS EKS