برنامه نویسی

پیاده سازی خط لوله GitOps کامل: تهیه زیرساخت و اتوماسیون استقرار برنامه

Summarize this content to 400 words in Persian Lang

مقدمه

در این مقاله، من شما را از طریق اجرای یک خط لوله کامل GitOps که هم تامین زیرساخت و هم استقرار برنامه را مدیریت می کند، راهنمایی می کنم. ما از ترکیبی از Terraform، Ansible و Docker برای ایجاد خط لوله CI/CD کاملاً خودکار استفاده خواهیم کرد که از بهترین شیوه‌ها پیروی می‌کند و نگرانی‌ها را از هم جدا می‌کند.

🔗 مخزن پروژه: پروژه خط لوله DevOps

می توانید تمام کدها و تنظیمات مورد بحث در این مقاله را در مخزن بالا بیابید. اگر به نظرتان مفید است، آن را ستاره دار کنید!

در روش‌های DevOps مدرن، اتوماسیون کلید حفظ تحویل نرم‌افزار قابل اعتماد و کارآمد است. این پروژه اجرای یک خط لوله جامع GitOps را نشان می دهد که هم تأمین زیرساخت و هم استقرار برنامه را از طریق گردش کار خودکار انجام می دهد. با استفاده از ابزارهایی مانند Terraform، Ansible و Docker، همراه با GitHub Actions، سیستمی ایجاد کرده‌ایم که استقرار زیرساخت‌ها، برنامه‌ریزی آگاهانه از هزینه و به‌روزرسانی خودکار برنامه‌ها را تضمین می‌کند.

این راه حل به چالش های رایج در شیوه های DevOps می پردازد:

نحوه نگهداری زیرساخت به عنوان کد با اعتبارسنجی مناسب و کنترل هزینه
نحوه خودکارسازی استقرار سیستم نظارت در کنار زیرساخت
نحوه مدیریت استقرار برنامه ها با نسخه سازی و عرضه مناسب
چگونه می توان زیرساخت ها و استقرار برنامه ها را جدا و در عین حال هماهنگ نگه داشت

نمای کلی معماری

بررسی اجمالی پروژه

اجزای اصلی و ساختار گردش کار

این پروژه در دو خط لوله اصلی سازماندهی شده است:

خط لوله زیرساخت (infra_features → infra_main)

تمام تامین زیرساخت ها را از طریق Terraform انجام می دهد
به طور خودکار پشته نظارت را با استفاده از Ansible مستقر می کند
شامل برآورد هزینه برای تغییرات زیرساخت
در شعبه اصلی برای مدیریت متمرکز گردش کار و همچنین در هر شعبه برای محرک های مناسب قرار دارد

خط لوله برنامه (integration → deployment)

ساخت و استقرار کانتینر برنامه را مدیریت می کند
نسخه‌سازی و به‌روزرسانی‌های تصویر Docker را مدیریت می‌کند
استقرار در زیرساخت های تدارک دیده را خودکار می کند

محرک های گردش کار و مکان

گردش کار زیرساخت:

terraform-validate.yml: با فشار دادن به infra_features

terraform-plan.yml: باعث ایجاد روابط عمومی به infra_main

terraform-apply.yml: عوامل در روابط عمومی ادغام به infra_main

ansible-monitoring.yml: تریگرها پس از ترافورم موفق اعمال می شوند

گردش کار برنامه:

ci-application.yml: با فشار دادن به integration

cd-application.yml: عوامل در روابط عمومی ادغام به deployment

نتایج مورد انتظار

خط لوله زیرساخت:

اعتبار سنجی خودکار تنظیمات Terraform
برآورد هزینه در نظرات روابط عمومی
زیرساخت AWS فراهم شده
پشته نظارت مستقر شده (Prometheus، Grafana، و غیره)

خط لوله برنامه:

تصاویر Docker ساخته شده و نسخه شده است
پیکربندی های docker-compose به روز شد
استقرار پشته برنامه در زیرساخت

تفکیک نگرانی ها از طریق:

شاخه های مختلف برای زیرساخت و کد برنامه
گردش کار مجزا برای مراحل مختلف استقرار
محرک هایی را پاک کنید که از استقرار ناخواسته جلوگیری می کند

این ساختار تضمین می کند که:

تغییرات زیرساخت قبل از استقرار اعتبار و برآورد هزینه می شود
استقرار برنامه ها فقط در زیرساخت هایی که به درستی تدارک دیده شده اند انجام می شود
نظارت همیشه قبل از استقرار برنامه وجود دارد
تغییرات را می توان پیگیری و در صورت نیاز معکوس کرد.

شیرجه عمیق خط لوله پیکربندی زیرساخت

terraform-validate.yml

این گردش کار اولین دروازه کیفیت ما برای تغییرات زیرساختی است. در حالی که در شاخه اصلی برای تمرکز وجود دارد، باید در شاخه نیز وجود داشته باشد infra_features شاخه به درستی ماشه در رویدادهای فشار.

name: Terraform Validate
run-name: ${{ github.actor }} triggered Terraform validation

on:
workflow_dispatch: # Allows manual trigger
push:
branches:
– infra_features # Trigger on pushes to infra_features branch
paths:
– ‘terraform/**’ # Only trigger if files in the terraform directory change

env:
# AWS Credentials
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
TF_VAR_aws_region: ${{ vars.AWS_REGION }}

jobs:
validate:
name: Terraform Validate
runs-on: ubuntu-latest

steps:
– name: Checkout Specific Branch
uses: actions/checkout@v3
with:
ref: ${{ github.ref }}

– name: Debug Branch Information
run: |
echo “Triggered by branch: ${{ github.ref }}”
echo “Current branch: $(git branch –show-current)”

– name: Set up Terraform
uses: hashicorp/setup-terraform@v2

– name: Validate Terraform Formatting
id: fmt-check
run: terraform fmt -check
working-directory: terraform
continue-on-error: true # Continue even if there are formatting issues

– name: Fix Terraform Formatting Issues
if: failure() # Run only if the previous step fails
run: terraform fmt
working-directory: terraform

– name: Terraform Init
id: init
run: terraform init
working-directory: terraform

– name: Terraform Validate
id: validate
run: terraform validate
working-directory: terraform

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک ها:

رویدادها را به infra_features شاخه
ماشه دستی از طریق workflow_dispatch
فیلترهای مسیر برای تغییرات دایرکتوری terraform

راه اندازی محیط:

پیکربندی اعتبارنامه AWS
مشخصات منطقه از متغیرها

مراحل اعتبار سنجی:

کد پرداخت
Terraform را راه اندازی کنید
قالب بندی Terraform را بررسی و اصلاح کنید
تنظیمات Terraform را راه اندازی و اعتبار سنجی کنید

گردش کار تضمین می کند:

تشخیص زودهنگام خطاهای پیکربندی
قالب بندی کد سازگار
نحو اولیه و بررسی پیکربندی
رفع خودکار فرمت در صورت یافتن مشکلات
بازخورد فوری به توسعه دهندگان

terraform-plan.yml

این گردش کار برنامه ریزی زیرساخت و برآورد هزینه را انجام می دهد. هم در اصلی و هم وجود دارد infra_main شعبه ها برای ارائه بینش هزینه قبل از تایید هرگونه تغییر زیرساخت.

name: Terraform Plan and Cost Estimation
on:
workflow_dispatch:
pull_request:
branches:
– infra_main
types:
– opened
– synchronize
– reopened
permissions:
pull-requests: write

env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
TF_VAR_aws_region: ${{ vars.AWS_REGION }}

TF_VAR_ami_id: ${{ vars.AMI_ID }}
TF_VAR_instance_type: ${{ vars.INSTANCE_TYPE }}
TF_VAR_key_pair_name: ${{ vars.KEY_PAIR_NAME }}
TF_VAR_instance_name: ${{ vars.INSTANCE_NAME }}
TF_VAR_domain_name: ${{ vars.DOMAIN_NAME }}
TF_VAR_frontend_domain: ${{ vars.FRONTEND_DOMAIN }}
TF_VAR_db_domain: ${{ vars.DB_DOMAIN }}
TF_VAR_traefik_domain: ${{ vars.TRAEFIK_DOMAIN }}
TF_VAR_grafana_domain: ${{ vars.GRAFANA_DOMAIN }}
TF_VAR_prometheus_domain: ${{ vars.PROMETHEUS_DOMAIN }}
TF_VAR_cert_email: ${{ vars.CERT_EMAIL }}
TF_VAR_private_key_path: ${{ vars.PRIVATE_KEY_PATH }}
TF_VAR_app_dir: ${{ vars.APP_DIR }}
TF_VAR_repo: ${{ vars.REPO }}

jobs:
terraform-plan:
name: Terraform Plan and Cost Estimation
runs-on: ubuntu-latest

steps:
– name: Checkout PR Branch
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}

– name: Checkout Base Branch
uses: actions/checkout@v3
with:
ref: ${{ github.base_ref }}
path: base-branch

– name: Debug Branch Information
run: |
echo “Base branch: ${{ github.base_ref }}”
echo “Head branch: ${{ github.head_ref }}”

– name: Prepare Terraform
uses: hashicorp/setup-terraform@v2

– name: Initialize Terraform Configuration
run: terraform init
working-directory: terraform

– name: Generate Terraform Plan
id: tf_plan
run: |
terraform plan -out=tfplan -lock=false
terraform show -no-color tfplan > /tmp/plan_output.txt
working-directory: terraform

– name: Install Cost Analysis Tool
uses: infracost/actions/setup@v2
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}

– name: Perform Base Branch Cost Breakdown
run: |
cd base-branch/terraform
infracost breakdown –path=. –format=json > /tmp/base_cost_analysis.json
continue-on-error: true

– name: Perform Current Branch Cost Breakdown
run: |
cd terraform
infracost breakdown –path=. –format=json > /tmp/current_cost_analysis.json
infracost breakdown –path=. –format=table > /tmp/cost_summary.txt

– name: Generate Cost Difference
run: |
infracost diff \
–path=terraform \
–compare-to=/tmp/base_cost_analysis.json \
–format=json > /tmp/cost_difference.json || true
continue-on-error: true

– name: Prepare Workflow Report
uses: actions/github-script@v6
if: github.event_name == ‘pull_request’
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require(‘fs’);

const planContent = fs.readFileSync(‘/tmp/plan_output.txt’, ‘utf8’);
const costSummary = fs.readFileSync(‘/tmp/cost_summary.txt’, ‘utf8’);

const commentBody = `### 🔍 Infrastructure Validation Report

📋 Terraform Plan Insights 📋

\`\`\`terraform
${planContent}
\`\`\`

💰 Cost Estimation Overview 💰

\`\`\`
${costSummary}
\`\`\`

*Analysis triggered by @${{ github.actor }}*`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک ها:

درخواست ها را به infra_main شاخه
رویدادهای روابط عمومی: باز، همگام، بازگشایی
ارسال گردش کار دستی برای آزمایش

راه اندازی محیط:

اعتبارنامه AWS از اسرار
متغیرهای Terraform جامع شامل:

تنظیمات زیرساخت
تنظیمات دامنه
مسیرهای کاربردی
نقاط پایانی خدمات

فرآیند برنامه ریزی:

اعتبار سنجی قالب
مقایسه شاخه های پایه
تولید برنامه
تجزیه و تحلیل هزینه از طریق Infracost

ادغام روابط عمومی:

نظرات PR خودکار با:

تغییرات زیرساختی
برآورد هزینه
اصلاحات منابع
مقایسه پایه در مقابل پیشنهاد

گردش کار تضمین می کند:

تفکیک هزینه های دقیق
پیامدهای هزینه را تغییر دهید
قیمت گذاری منابع خاص
مقایسه هزینه با وضعیت فعلی
ارائه طرح را در نظرات روابط عمومی پاک کنید

مهم است: گردش کار به یک کلید Infracost API نیاز دارد که در Secrets GitHub ذخیره شده باشد تا ویژگی های برآورد هزینه به درستی کار کند.

terraform-apply.yml

این گردش کار مسئول استقرار زیرساخت واقعی است. هم در اصلی و هم وجود دارد infra_main شاخه ها برای اطمینان از راه اندازی مناسب در ادغام روابط عمومی و اجازه مدیریت دستی زیرساخت.

name: Terraform Infrastructure Apply
on:
pull_request:
branches:
– ‘infra_main’
types:
– closed

workflow_dispatch:
inputs:
action:
type: choice
description: ‘Select the action to perform’
required: true
default: ‘destroy’
options:
– ‘destroy’
– ‘apply’

env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
TF_VAR_aws_region: ${{ vars.AWS_REGION }}

# Terraform Variables to be passed as environment variables
TF_VAR_ami_id: ${{ vars.AMI_ID }}
TF_VAR_instance_type: ${{ vars.INSTANCE_TYPE }}
TF_VAR_key_pair_name: ${{ vars.KEY_PAIR_NAME }}
TF_VAR_instance_name: ${{ vars.INSTANCE_NAME }}
TF_VAR_domain_name: ${{ vars.DOMAIN_NAME }}
TF_VAR_frontend_domain: ${{ vars.FRONTEND_DOMAIN }}
TF_VAR_db_domain: ${{ vars.DB_DOMAIN }}
TF_VAR_traefik_domain: ${{ vars.TRAEFIK_DOMAIN }}
TF_VAR_grafana_domain: ${{ vars.GRAFANA_DOMAIN }}
TF_VAR_prometheus_domain: ${{ vars.PROMETHEUS_DOMAIN }}
TF_VAR_cert_email: ${{ vars.CERT_EMAIL }}
TF_VAR_private_key_path: ${{ vars.PRIVATE_KEY_PATH }}
TF_VAR_app_dir: ${{ vars.APP_DIR }}
TF_VAR_repo: ${{ vars.REPO }}

jobs:
terraform-apply:
name: Terraform Infrastructure Apply
runs-on: ubuntu-latest

# Trigger on merged PR to infra_main or manual destroy
if: >
(github.event_name == ‘pull_request’ &&
github.event.pull_request.merged == true &&
github.base_ref == ‘infra_main’) ||
(github.event_name == ‘workflow_dispatch’)

steps:
– name: Checkout PR Branch
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}

– name: Install Terraform
uses: hashicorp/setup-terraform@v2

– name: Initialize Terraform Configuration
run: terraform init
working-directory: terraform

– name: Terraform Apply
if: |
github.event_name == ‘pull_request’ &&
github.event.pull_request.merged == true ||
(github.event_name == ‘workflow_dispatch’ && github.event.inputs.action == ‘apply’)
run: terraform apply –auto-approve -lock=false
working-directory: terraform

– name: Terraform Destroy
if: github.event_name == ‘workflow_dispatch’ && github.event.inputs.action == ‘destroy’
run: terraform destroy –auto-approve -lock=false
working-directory: terraform

– name: Create Action Indicator
run: echo ${{ github.event.inputs.action }} > ./ansible/action_indicator.txt

# Upload inventory, trigger and key as artifacts
– name: Upload Inventory and Key
if: github.event_name != ‘workflow_dispatch’ || github.event.inputs.action != ‘destroy’
uses: actions/upload-artifact@v4
with:
name: infrastructure-artifacts
path: |
ansible/inventory.ini
ansible/action_indicator.txt
terraform/${{ vars.KEY_PAIR_NAME }}
retention-days: 1

– name: Save Infrastructure Details as Secrets
if: github.event_name != ‘workflow_dispatch’ || github.event.inputs.action != ‘destroy’
run: |
# First check if files exist
echo “Checking infrastructure files…”
if [ ! -f “terraform/${{ vars.KEY_PAIR_NAME }}” ] || [ ! -f “ansible/inventory.ini” ]; then
echo “Required files not found!”
exit 1
fi

echo “Reading infrastructure files…”
# Read files and encode in base64 to handle multiline content safely
SSH_KEY=$(cat “terraform/${{ vars.KEY_PAIR_NAME }}” | base64 -w 0)
INVENTORY=$(cat “ansible/inventory.ini” | base64 -w 0)

echo “Saving to GitHub Secrets…”
# Save SSH key
gh secret set EC2_SSH_KEY –body “$SSH_KEY”
# Save inventory
gh secret set EC2_INVENTORY –body “$INVENTORY”

echo “Infrastructure details saved as secrets successfully!”
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
GH_TOKEN: ${{ secrets.PAT_TOKEN }}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک ها:

ادغام روابط عمومی به infra_main شاخه
ارسال گردش کار دستی با گزینه های:

درخواست: برای استقرار زیرساخت دستی
Destroy: برای تخریب زیرساخت

پیکربندی محیط:

اعتبارنامه AWS از اسرار
متغیرهای Terraform برای:

منطقه AWS
پیکربندی AMI
تنظیمات دامنه
دایرکتوری های برنامه و غیره

عملیات بحرانی:

استقرار زیرساخت از طریق Terraform اعمال می شود
تخریب زیرساخت (ماشه دستی)
ایجاد مصنوعات برای گردش کار پایین دست

مهم است: جزئیات زیرساخت را به عنوان اسرار GitHub ذخیره می کند:

EC2_SSH_KEY: کلید SSH کدگذاری شده Base64
EC2_INVENTORY: فایل موجودی کدگذاری شده Base64
این اسرار برای گردش کار برنامه CD بسیار مهم هستند

توجه داشته باشید: ذخیره جزئیات زیرساخت به عنوان اسرار برای گردش کار برنامه CD بسیار مهم است که بعداً به آن خواهیم پرداخت. این اسرار دسترسی ایمن به زیرساخت های مستقر را امکان پذیر می کند.

ansible-monitoring.yml و Playbook مرتبط

این گردش کار استقرار پشته مانیتورینگ ما را خودکار می کند و پس از تهیه موفقیت آمیز زیرساخت به طور خودکار فعال می شود. گردش کار به دو صورت اصلی و وجود دارد infra_main شاخه ها برای عملکرد مناسب

name: Monitoring Stack Deployment

on:
workflow_run:
workflows: [“Terraform Infrastructure Apply”] types:
– completed

jobs:
ansible-monitoring:
if: ${{ github.event.workflow_run.conclusion == ‘success’ }}
name: Monitoring Stack Deployment
runs-on: ubuntu-latest

steps:
– name: Checkout infra_main Branch
uses: actions/checkout@v4
with:
ref: infra_main # Explicitly checkout infra_main branch
fetch-depth: 0 # Get full history

– name: Download artifacts
uses: dawidd6/action-download-artifact@v3
with:
workflow: terraform-apply.yml
workflow_conclusion: success
name: infrastructure-artifacts
path: ./artifacts

– name: Check Action Indicator
id: check-action
run: |
ACTION=$(cat ./artifacts/ansible/action_indicator.txt)
echo “Action: $ACTION”
if [ “$ACTION” != “apply” ]; then
echo “Monitoring stack deployment skipped due to action: $ACTION”
exit 0
fi

# Copy the key to the terraform directory
– name: Setup SSH Key
run: |
cp ./artifacts/terraform/${{ vars.KEY_PAIR_NAME }} ./terraform/
chmod 600 ./terraform/${{ vars.KEY_PAIR_NAME }}

– name: Update Inventory File
run: |
sed -i “s|ansible_ssh_private_key_file=\./${{ vars.KEY_PAIR_NAME }}|ansible_ssh_private_key_file=./terraform/${{ vars.KEY_PAIR_NAME }}|” ./artifacts/ansible/inventory.ini
cat ./artifacts/ansible/inventory.ini # Debug print

– name: Set up Ansible
uses: alex-oleshkevich/setup-ansible@v1.0.1
with:
version: “9.3.0”

– name: Run Ansible Playbook
run: |
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i ./artifacts/ansible/inventory.ini ./ansible/playbook.yml \
–extra-vars “domain_name=${{ vars.DOMAIN_NAME }} \
traefik_domain=${{ vars.TRAEFIK_DOMAIN }} \
cert_email=${{ vars.CERT_EMAIL }}\
repo=${{ vars.REPO }}\
app_dir=${{ vars.APP_DIR }}\
branch=infra_main”

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک های گردش کار:

ماشه خودکار پس از تکمیل ترافورم
نشانگر عمل را بررسی می‌کند تا از اجرای صحیح اطمینان حاصل کند که درصورتی‌که گردش کار زمینی اعمال شود فقط برای نابودی فعال شده است
فقط در اقدام “اعمال” ادامه می یابد

دسترسی به زیرساخت:

مصنوعات تولید شده توسط زمین را بارگیری می کند
دسترسی SSH را با استفاده از کلیدهای زیرساخت پیکربندی می کند
مسیرها و مجوزهای فایل موجودی را به روز می کند

تنظیم نظارت:

پشته نظارت کامل را از طریق Ansible مستقر می کند
دامنه ها و گواهی ها را پیکربندی می کند
مخزن و دایرکتوری برنامه را تنظیم می کند

بررسی اجمالی کتاب بازی Ansible Associated

main playbook
– name: Setting up application and monitoring servers
hosts: all
become: yes
roles:
– docker
– file_setup
– monitoring_setup
——–
file setup task
– name: Clone the repository
git:
repo: “{{ repo }}”
dest: “{{ app_dir }}”
version: “{{ branch }}”

– name: Ensure the Traefik directory exists
file:
path: “{{ app_dir }}/traefik”
state: directory
mode: ‘0755’

– name: Create acme.json with proper permissions
file:
path: “{{ app_dir }}/traefik/acme.json”
state: touch
mode: ‘0600’

– name: Check if the data folder exists
stat:
path: “{{ app_dir }}/data”
register: data_folder

– name: Ensure Loki data folder has the correct ownership and permissions
block:
– name: Change ownership of data folder for Loki
command: chown -R 10001:10001 ./data
args:
chdir: “{{ app_dir }}”

– name: Set permissions for the data folder
command: chmod -R 755 ./data
args:
chdir: “{{ app_dir }}”
when: data_folder.stat.exists

– name: Configure monitoring compose file using template
template:
src: “monitoring_stack_template.j2”
dest: “{{ app_dir }}/monitoring-stack.yml”
mode: ‘0644’
—–
the monitoring task
– name: Bring up the monitoring stack
command: docker compose -f monitoring-stack.yml up -d
args:
chdir: “{{ app_dir }}”

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کتاب بازی کل تنظیمات نظارت را از طریق سه نقش مجزا هماهنگ می کند:

نقش داکر:

اطمینان حاصل می کند که Docker نصب و پیکربندی شده است
خدمات Docker مورد نیاز را تنظیم می کند
پیش نیازهای شبکه را پیکربندی می کند

نقش تنظیم فایل:

مخزن پیکربندی کلون ها
ساختار دایرکتوری لازم را ایجاد می کند
تنظیمات Traefik و SSL را تنظیم می کند
مجوزها و مالکیت را مدیریت می کند
دایرکتوری های ماندگاری داده را آماده می کند

نقش تنظیم نظارت:

پشته نظارت کامل را مستقر می کند
Prometheus، Grafana و Loki را پیکربندی می کند
پروکسی معکوس را با Traefik تنظیم می کند
اطمینان حاصل می کند که همه سرویس ها در حال اجرا هستند

گردش کار تضمین می کند:

یکپارچگی راه اندازی:

ساختار دایرکتوری مناسب
مجوزهای فایل را درست کنید
تنظیمات مورد نیاز

اقدامات امنیتی:

مدیریت امن اعتبارنامه
گواهی های محافظت شده
مجوزهای فایل مناسب

مولفه های نظارت:

پرومتئوس برای معیارها
گرافانا برای تجسم
لوکی برای سیاهههای مربوط
Traefik برای مسیریابی

توجه داشته باشید: این گردش کار وابسته به مصنوعات تولید شده توسط terraform-apply.yml است که وابستگی های گردش کار را در خط لوله زیرساخت ما نشان می دهد و در هر دو قسمت قرار دارد. main شعبه و infra_main شاخه

ci-application.yml

این گردش کار فرآیند یکپارچه‌سازی مداوم برنامه ما را مدیریت می‌کند، هنگام به‌روزرسانی پیکربندی‌های استقرار (نوشتن فایل) تصاویر Docker را ایجاد و فشار می‌دهد.

name: Application CI Pipeline

on:

push:
branches:
– ‘integration’
paths:
– ‘backend/**’
– ‘frontend/**’

env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
IMAGE_TAG: 1.0.${{ github.run_number }}
FRONTEND_IMAGE: frontend-dojodevops
BACKEND_IMAGE: backend-dojodevops

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
– name: Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
– name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

– name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

– name: Build and push backend
uses: docker/build-push-action@v5
with:
context: ./backend
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:${{ env.IMAGE_TAG }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:latest

– name: Build and push frontend
uses: docker/build-push-action@v5
with:
context: ./frontend
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:${{ env.IMAGE_TAG }}
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:latest

– name: Update docker-compose.yml
run: |
echo “=== Current docker-compose template content ===”
cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

echo -e “\n=== Attempting to update image tags ===”
# Update backend image
sed -i “s|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:.*|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:${{ env.IMAGE_TAG }}|” ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
# Update frontend image
sed -i “s|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:.*|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:${{ env.IMAGE_TAG }}|” ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

echo -e “\n=== Updated docker-compose template content ===”
cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

# Check if any changes were made
if git diff –quiet ./ansible/roles/app_deploy/templates/docker-compose.yml.j2; then
echo “No changes were made to docker-compose template”
echo “Current content of docker-compose template:”
cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
exit 1
else
echo “Changes detected in docker-compose template:”
git diff ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
fi

# Using GitHub’s default token for authentication
– name: Commit and push updated docker-compose
run: |
git config –global user.name “${{ github.actor }}”
git config –global user.email “${{ github.actor }}@users.noreply.github.com”
git add ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
git commit -m “Update image tags to ${{ env.IMAGE_TAG }}”
git push origin integration

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک ها:

رویدادها را به integration شاخه
فیلترهای مسیر برای دایرکتوری های باطن و فرانت اند

راه اندازی محیط:

اعتبار Docker Hub
نسخه‌سازی تصویر با استفاده از شماره اجرا GitHub
تصاویر مجزا برای فرانت اند و باطن

فرآیند ساخت:

راه اندازی Docker Buildx برای ساخت های چند پلتفرمی
ساخت های موازی برای فرانت اند و بک اند
مدیریت برچسب ها با آخرین و نسخه های برچسب
به‌روزرسانی‌های قالب نوشتن Docker

گردش کار تضمین می کند:

ساخت خودکار تصاویر
کنترل نسخه تصاویر
به روز رسانی های پیکربندی
برچسب گذاری مناسب تصاویر
ارتکاب خودکار تنظیمات به روز شده

cd-application.yml

این گردش کار با استفاده از اسرار زیرساخت از گردش کار قبلی، استقرار مداوم برنامه ما را مدیریت می کند.

name: Application CD Pipeline

on:
workflow_dispatch:
pull_request:
branches:
– ‘deployment’
types:
– closed

jobs:
application-deploy:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
– name: Checkout deployment branch
uses: actions/checkout@v4
with:
ref: deployment

– name: Setup Infrastructure Files
run: |
# Create directories
mkdir -p ./tmp/ ./tmp/ansible

# Decode and save SSH key
echo “${{ secrets.EC2_SSH_KEY }}” | base64 -d > ./tmp/${{ vars.KEY_PAIR_NAME }}
chmod 600 ./tmp/${{ vars.KEY_PAIR_NAME }}

# Decode and save inventory
echo “${{ secrets.EC2_INVENTORY }}” | base64 -d > ./tmp/ansible/inventory.ini

– name: Update Inventory File
run: |
sed -i “s|ansible_ssh_private_key_file=\./${{ vars.KEY_PAIR_NAME }}|ansible_ssh_private_key_file=./tmp/${{ vars.KEY_PAIR_NAME }}|” ./tmp/ansible/inventory.ini

– name: Set up Ansible
uses: alex-oleshkevich/setup-ansible@v1.0.1
with:
version: “9.3.0”

– name: Run Application Deployment Playbook
run: |
ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i ./tmp/ansible/inventory.ini ./ansible/playbook.yml \
–extra-vars ‘{
“repo”: “${{ vars.REPO }}”,
“app_dir”: “${{ vars.APP_DIR }}”,
“backend_env”: ${{ toJSON(secrets.BACKEND_ENV) }},
“frontend_env”: ${{ toJSON(secrets.FRONTEND_ENV) }},
“frontend_domain”: “${{ vars.FRONTEND_DOMAIN }}”,
“DOCKERHUB_USERNAME”: “${{ secrets.DOCKERHUB_USERNAME }}”,
“FRONTEND_IMAGE”: “frontend-dojodevops”,
“BACKEND_IMAGE”: “backend-dojodevops”,
“db_domain”: “${{ vars.DB_DOMAIN }}”,
“branch”: “deployment”
}’

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

محرک ها:

کشش درخواست ادغام به deployment شاخه
ارسال گردش کار دستی

راه اندازی زیرساخت:

از اسرار terraform-apply استفاده می کند:

EC2_SSH_KEY برای دسترسی به سرور
EC2_INVENTORY برای جزئیات سرور

فرآیند استقرار:

پیکربندی Ansible
راه اندازی محیط
استقرار برنامه

گردش کار تضمین می کند:

فرآیند استقرار امن
پیکربندی محیط
دسترسی به زیرساخت
راه‌اندازی برنامه با راه‌اندازی دفترچه راهنما

راهنمای متغیرها و اسرار محیطی مهم:

اسرار زیرساخت (تولید شده توسط terraform-apply):

EC2_SSH_KEY: کلید SSH کدگذاری شده Base64 برای دسترسی EC2

EC2_INVENTORY: فایل موجودی Ansible کدگذاری شده Base64

اعتبار Docker Hub:

DOCKERHUB_USERNAME: نام کاربری حساب Docker Hub

DOCKERHUB_TOKEN: نشانه دسترسی Docker Hub

متغیرهای محیط کاربردی:

BACKEND_ENV: شی JSON حاوی متغیرهای محیطی باطن

FRONTEND_ENV: شی JSON حاوی متغیرهای محیطی frontend

پیکربندی دامنه:

FRONTEND_DOMAIN: دامنه برای سرویس جلویی

DB_DOMAIN: دامنه برای سرویس پایگاه داده

تنظیمات مخزن:

REPO: آدرس مخزن

APP_DIR: مسیر دایرکتوری برنامه

KEY_PAIR_NAME: نام جفت کلید SSH

توجه داشته باشید: گردش کار CD اهمیت مدیریت صحیح محرمانه را با استفاده از اسرار زیرساخت ایجاد شده در حین تهیه برای دسترسی ایمن به استقرار نشان می دهد.

تمیز کردن

این را می توان با فعال کردن دستی نابودی زمین انجام داد.

مقدمه

در این مقاله، من شما را از طریق اجرای یک خط لوله کامل GitOps که هم تامین زیرساخت و هم استقرار برنامه را مدیریت می کند، راهنمایی می کنم. ما از ترکیبی از Terraform، Ansible و Docker برای ایجاد خط لوله CI/CD کاملاً خودکار استفاده خواهیم کرد که از بهترین شیوه‌ها پیروی می‌کند و نگرانی‌ها را از هم جدا می‌کند.

🔗 مخزن پروژه: پروژه خط لوله DevOps

می توانید تمام کدها و تنظیمات مورد بحث در این مقاله را در مخزن بالا بیابید. اگر به نظرتان مفید است، آن را ستاره دار کنید!

در روش‌های DevOps مدرن، اتوماسیون کلید حفظ تحویل نرم‌افزار قابل اعتماد و کارآمد است. این پروژه اجرای یک خط لوله جامع GitOps را نشان می دهد که هم تأمین زیرساخت و هم استقرار برنامه را از طریق گردش کار خودکار انجام می دهد. با استفاده از ابزارهایی مانند Terraform، Ansible و Docker، همراه با GitHub Actions، سیستمی ایجاد کرده‌ایم که استقرار زیرساخت‌ها، برنامه‌ریزی آگاهانه از هزینه و به‌روزرسانی خودکار برنامه‌ها را تضمین می‌کند.

این راه حل به چالش های رایج در شیوه های DevOps می پردازد:

  • نحوه نگهداری زیرساخت به عنوان کد با اعتبارسنجی مناسب و کنترل هزینه
  • نحوه خودکارسازی استقرار سیستم نظارت در کنار زیرساخت
  • نحوه مدیریت استقرار برنامه ها با نسخه سازی و عرضه مناسب
  • چگونه می توان زیرساخت ها و استقرار برنامه ها را جدا و در عین حال هماهنگ نگه داشت

نمای کلی معماری

معماری

بررسی اجمالی پروژه

اجزای اصلی و ساختار گردش کار

این پروژه در دو خط لوله اصلی سازماندهی شده است:

  1. خط لوله زیرساخت (infra_featuresinfra_main)

    • تمام تامین زیرساخت ها را از طریق Terraform انجام می دهد
    • به طور خودکار پشته نظارت را با استفاده از Ansible مستقر می کند
    • شامل برآورد هزینه برای تغییرات زیرساخت
    • در شعبه اصلی برای مدیریت متمرکز گردش کار و همچنین در هر شعبه برای محرک های مناسب قرار دارد
  2. خط لوله برنامه (integrationdeployment)

    • ساخت و استقرار کانتینر برنامه را مدیریت می کند
    • نسخه‌سازی و به‌روزرسانی‌های تصویر Docker را مدیریت می‌کند
    • استقرار در زیرساخت های تدارک دیده را خودکار می کند

محرک های گردش کار و مکان

  1. گردش کار زیرساخت:

    • terraform-validate.yml: با فشار دادن به infra_features
    • terraform-plan.yml: باعث ایجاد روابط عمومی به infra_main
    • terraform-apply.yml: عوامل در روابط عمومی ادغام به infra_main
    • ansible-monitoring.yml: تریگرها پس از ترافورم موفق اعمال می شوند
  2. گردش کار برنامه:

    • ci-application.yml: با فشار دادن به integration
    • cd-application.yml: عوامل در روابط عمومی ادغام به deployment

نتایج مورد انتظار

  1. خط لوله زیرساخت:

    • اعتبار سنجی خودکار تنظیمات Terraform
    • برآورد هزینه در نظرات روابط عمومی
    • زیرساخت AWS فراهم شده
    • پشته نظارت مستقر شده (Prometheus، Grafana، و غیره)
  2. خط لوله برنامه:

    • تصاویر Docker ساخته شده و نسخه شده است
    • پیکربندی های docker-compose به روز شد
    • استقرار پشته برنامه در زیرساخت

تفکیک نگرانی ها از طریق:

  • شاخه های مختلف برای زیرساخت و کد برنامه
  • گردش کار مجزا برای مراحل مختلف استقرار
  • محرک هایی را پاک کنید که از استقرار ناخواسته جلوگیری می کند

این ساختار تضمین می کند که:

  1. تغییرات زیرساخت قبل از استقرار اعتبار و برآورد هزینه می شود
  2. استقرار برنامه ها فقط در زیرساخت هایی که به درستی تدارک دیده شده اند انجام می شود
  3. نظارت همیشه قبل از استقرار برنامه وجود دارد
  4. تغییرات را می توان پیگیری و در صورت نیاز معکوس کرد.

شیرجه عمیق خط لوله پیکربندی زیرساخت

terraform-validate.yml

این گردش کار اولین دروازه کیفیت ما برای تغییرات زیرساختی است. در حالی که در شاخه اصلی برای تمرکز وجود دارد، باید در شاخه نیز وجود داشته باشد infra_features شاخه به درستی ماشه در رویدادهای فشار.

name: Terraform Validate
run-name: ${{ github.actor }} triggered Terraform validation

on:
  workflow_dispatch: # Allows manual trigger
  push:
    branches:
      - infra_features # Trigger on pushes to infra_features branch
    paths:
      - 'terraform/**' # Only trigger if files in the terraform directory change

env:
  # AWS Credentials
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  TF_VAR_aws_region: ${{ vars.AWS_REGION }}

jobs:
  validate:
    name: Terraform Validate
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Specific Branch
        uses: actions/checkout@v3
        with:
          ref: ${{ github.ref }}

      - name: Debug Branch Information
        run: |
          echo "Triggered by branch: ${{ github.ref }}"
          echo "Current branch: $(git branch --show-current)"

      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Validate Terraform Formatting
        id: fmt-check
        run: terraform fmt -check
        working-directory: terraform
        continue-on-error: true  # Continue even if there are formatting issues

      - name: Fix Terraform Formatting Issues
        if: failure()  # Run only if the previous step fails
        run: terraform fmt
        working-directory: terraform

      - name: Terraform Init
        id: init
        run: terraform init
        working-directory: terraform 

      - name: Terraform Validate
        id: validate
        run: terraform validate
        working-directory: terraform
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک ها:

    • رویدادها را به infra_features شاخه
    • ماشه دستی از طریق workflow_dispatch
    • فیلترهای مسیر برای تغییرات دایرکتوری terraform
  2. راه اندازی محیط:

    • پیکربندی اعتبارنامه AWS
    • مشخصات منطقه از متغیرها
  3. مراحل اعتبار سنجی:

    • کد پرداخت
    • Terraform را راه اندازی کنید
    • قالب بندی Terraform را بررسی و اصلاح کنید
    • تنظیمات Terraform را راه اندازی و اعتبار سنجی کنید

گردش کار تضمین می کند:

  • تشخیص زودهنگام خطاهای پیکربندی
  • قالب بندی کد سازگار
  • نحو اولیه و بررسی پیکربندی
  • رفع خودکار فرمت در صورت یافتن مشکلات
  • بازخورد فوری به توسعه دهندگان

اعتبارسنجی Terraform

terraform-plan.yml

این گردش کار برنامه ریزی زیرساخت و برآورد هزینه را انجام می دهد. هم در اصلی و هم وجود دارد infra_main شعبه ها برای ارائه بینش هزینه قبل از تایید هرگونه تغییر زیرساخت.

name: Terraform Plan and Cost Estimation
on:
  workflow_dispatch:
  pull_request:
    branches:
      - infra_main
    types:
      - opened
      - synchronize
      - reopened
permissions:
  pull-requests: write

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  TF_VAR_aws_region: ${{ vars.AWS_REGION }}


  TF_VAR_ami_id: ${{ vars.AMI_ID }}
  TF_VAR_instance_type: ${{ vars.INSTANCE_TYPE }}
  TF_VAR_key_pair_name: ${{ vars.KEY_PAIR_NAME }}
  TF_VAR_instance_name: ${{ vars.INSTANCE_NAME }}
  TF_VAR_domain_name: ${{ vars.DOMAIN_NAME }}
  TF_VAR_frontend_domain: ${{ vars.FRONTEND_DOMAIN }}
  TF_VAR_db_domain: ${{ vars.DB_DOMAIN }}
  TF_VAR_traefik_domain: ${{ vars.TRAEFIK_DOMAIN }}
  TF_VAR_grafana_domain: ${{ vars.GRAFANA_DOMAIN }}
  TF_VAR_prometheus_domain: ${{ vars.PROMETHEUS_DOMAIN }}
  TF_VAR_cert_email: ${{ vars.CERT_EMAIL }}
  TF_VAR_private_key_path: ${{ vars.PRIVATE_KEY_PATH }}
  TF_VAR_app_dir: ${{ vars.APP_DIR }}
  TF_VAR_repo: ${{ vars.REPO }}

jobs:
  terraform-plan:
    name: Terraform Plan and Cost Estimation
    runs-on: ubuntu-latest

    steps:
      - name: Checkout PR Branch
        uses: actions/checkout@v3
        with:
          ref: ${{ github.head_ref }}

      - name: Checkout Base Branch
        uses: actions/checkout@v3
        with:
          ref: ${{ github.base_ref }}
          path: base-branch

      - name: Debug Branch Information
        run: |
          echo "Base branch: ${{ github.base_ref }}"
          echo "Head branch: ${{ github.head_ref }}"

      - name: Prepare Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Initialize Terraform Configuration
        run: terraform init
        working-directory: terraform

      - name: Generate Terraform Plan
        id: tf_plan
        run: |
          terraform plan -out=tfplan -lock=false
          terraform show -no-color tfplan > /tmp/plan_output.txt
        working-directory: terraform

      - name: Install Cost Analysis Tool
        uses: infracost/actions/setup@v2
        with:
          api-key: ${{ secrets.INFRACOST_API_KEY }}

      - name: Perform Base Branch Cost Breakdown
        run: |
          cd base-branch/terraform
          infracost breakdown --path=. --format=json > /tmp/base_cost_analysis.json
        continue-on-error: true

      - name: Perform Current Branch Cost Breakdown
        run: |
          cd terraform
          infracost breakdown --path=. --format=json > /tmp/current_cost_analysis.json
          infracost breakdown --path=. --format=table > /tmp/cost_summary.txt

      - name: Generate Cost Difference
        run: |
          infracost diff \
            --path=terraform \
            --compare-to=/tmp/base_cost_analysis.json \
            --format=json > /tmp/cost_difference.json || true
        continue-on-error: true

      - name: Prepare Workflow Report
        uses: actions/github-script@v6
        if: github.event_name == 'pull_request'
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const fs = require('fs');

            const planContent = fs.readFileSync('/tmp/plan_output.txt', 'utf8');
            const costSummary = fs.readFileSync('/tmp/cost_summary.txt', 'utf8');

            const commentBody = `### 🔍 Infrastructure Validation Report

            
📋 Terraform Plan Insights 📋 \`\`\`terraform ${planContent} \`\`\`
💰 Cost Estimation Overview 💰 \`\`\` ${costSummary} \`\`\` *Analysis triggered by @${{ github.actor }}*`; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: commentBody });
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک ها:

    • درخواست ها را به infra_main شاخه
    • رویدادهای روابط عمومی: باز، همگام، بازگشایی
    • ارسال گردش کار دستی برای آزمایش
  2. راه اندازی محیط:

    • اعتبارنامه AWS از اسرار
    • متغیرهای Terraform جامع شامل:
      • تنظیمات زیرساخت
      • تنظیمات دامنه
      • مسیرهای کاربردی
      • نقاط پایانی خدمات
  3. فرآیند برنامه ریزی:

    • اعتبار سنجی قالب
    • مقایسه شاخه های پایه
    • تولید برنامه
    • تجزیه و تحلیل هزینه از طریق Infracost
  4. ادغام روابط عمومی:

    • نظرات PR خودکار با:
      • تغییرات زیرساختی
      • برآورد هزینه
      • اصلاحات منابع
      • مقایسه پایه در مقابل پیشنهاد

گردش کار تضمین می کند:

  • تفکیک هزینه های دقیق
  • پیامدهای هزینه را تغییر دهید
  • قیمت گذاری منابع خاص
  • مقایسه هزینه با وضعیت فعلی
  • ارائه طرح را در نظرات روابط عمومی پاک کنید

مهم است: گردش کار به یک کلید Infracost API نیاز دارد که در Secrets GitHub ذخیره شده باشد تا ویژگی های برآورد هزینه به درستی کار کند.

پلان ترافورم

نتیجه روابط عمومی

نتیجه بینش برنامه ریزی کنید

نتیجه تخمین ost

terraform-apply.yml

این گردش کار مسئول استقرار زیرساخت واقعی است. هم در اصلی و هم وجود دارد infra_main شاخه ها برای اطمینان از راه اندازی مناسب در ادغام روابط عمومی و اجازه مدیریت دستی زیرساخت.

name: Terraform Infrastructure Apply
on:
  pull_request:
    branches:
      - 'infra_main'  
    types:
      - closed  

  workflow_dispatch:
    inputs:
      action:
        type: choice
        description: 'Select the action to perform'
        required: true
        default: 'destroy'
        options:
          - 'destroy'
          - 'apply'

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  TF_VAR_aws_region: ${{ vars.AWS_REGION }}

# Terraform Variables to be passed as environment variables
  TF_VAR_ami_id: ${{ vars.AMI_ID }}
  TF_VAR_instance_type: ${{ vars.INSTANCE_TYPE }}
  TF_VAR_key_pair_name: ${{ vars.KEY_PAIR_NAME }}
  TF_VAR_instance_name: ${{ vars.INSTANCE_NAME }}
  TF_VAR_domain_name: ${{ vars.DOMAIN_NAME }}
  TF_VAR_frontend_domain: ${{ vars.FRONTEND_DOMAIN }}
  TF_VAR_db_domain: ${{ vars.DB_DOMAIN }}
  TF_VAR_traefik_domain: ${{ vars.TRAEFIK_DOMAIN }}
  TF_VAR_grafana_domain: ${{ vars.GRAFANA_DOMAIN }}
  TF_VAR_prometheus_domain: ${{ vars.PROMETHEUS_DOMAIN }}
  TF_VAR_cert_email: ${{ vars.CERT_EMAIL }}
  TF_VAR_private_key_path: ${{ vars.PRIVATE_KEY_PATH }}
  TF_VAR_app_dir: ${{ vars.APP_DIR }}
  TF_VAR_repo: ${{ vars.REPO }}

jobs:
  terraform-apply:
    name: Terraform Infrastructure Apply
    runs-on: ubuntu-latest

    # Trigger on merged PR to infra_main or manual destroy
    if: >
      (github.event_name == 'pull_request' && 
       github.event.pull_request.merged == true && 
       github.base_ref == 'infra_main') ||
      (github.event_name == 'workflow_dispatch')

    steps:
      - name: Checkout PR Branch
        uses: actions/checkout@v3
        with:
          ref: ${{ github.head_ref }}

      - name: Install Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Initialize Terraform Configuration
        run: terraform init
        working-directory: terraform

      - name: Terraform Apply
        if: |
          github.event_name == 'pull_request' && 
          github.event.pull_request.merged == true || 
          (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'apply')
        run: terraform apply --auto-approve -lock=false
        working-directory: terraform

      - name: Terraform Destroy
        if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'destroy'
        run: terraform destroy --auto-approve -lock=false
        working-directory: terraform

      - name: Create Action Indicator
        run: echo ${{ github.event.inputs.action }} > ./ansible/action_indicator.txt

      # Upload inventory, trigger  and key as artifacts
      - name: Upload Inventory and Key
        if: github.event_name != 'workflow_dispatch' || github.event.inputs.action != 'destroy'
        uses: actions/upload-artifact@v4
        with:
          name: infrastructure-artifacts
          path: |
            ansible/inventory.ini
            ansible/action_indicator.txt
            terraform/${{ vars.KEY_PAIR_NAME }}
          retention-days: 1

      - name: Save Infrastructure Details as Secrets
        if: github.event_name != 'workflow_dispatch' || github.event.inputs.action != 'destroy'
        run: |
          # First check if files exist
          echo "Checking infrastructure files..."
          if [ ! -f "terraform/${{ vars.KEY_PAIR_NAME }}" ] || [ ! -f "ansible/inventory.ini" ]; then
            echo "Required files not found!"
            exit 1
          fi

          echo "Reading infrastructure files..."
          # Read files and encode in base64 to handle multiline content safely
          SSH_KEY=$(cat "terraform/${{ vars.KEY_PAIR_NAME }}" | base64 -w 0)
          INVENTORY=$(cat "ansible/inventory.ini" | base64 -w 0)

          echo "Saving to GitHub Secrets..."
          # Save SSH key
          gh secret set EC2_SSH_KEY --body "$SSH_KEY"
          # Save inventory
          gh secret set EC2_INVENTORY --body "$INVENTORY"

          echo "Infrastructure details saved as secrets successfully!"
        env:
          GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
          GH_TOKEN: ${{ secrets.PAT_TOKEN }}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک ها:

    • ادغام روابط عمومی به infra_main شاخه
    • ارسال گردش کار دستی با گزینه های:
      • درخواست: برای استقرار زیرساخت دستی
      • Destroy: برای تخریب زیرساخت
  2. پیکربندی محیط:

    • اعتبارنامه AWS از اسرار
    • متغیرهای Terraform برای:
      • منطقه AWS
      • پیکربندی AMI
      • تنظیمات دامنه
      • دایرکتوری های برنامه و غیره
  3. عملیات بحرانی:

    • استقرار زیرساخت از طریق Terraform اعمال می شود
    • تخریب زیرساخت (ماشه دستی)
    • ایجاد مصنوعات برای گردش کار پایین دست
    • مهم است: جزئیات زیرساخت را به عنوان اسرار GitHub ذخیره می کند:

      • EC2_SSH_KEY: کلید SSH کدگذاری شده Base64
      • EC2_INVENTORY: فایل موجودی کدگذاری شده Base64
      • این اسرار برای گردش کار برنامه CD بسیار مهم هستند

توجه داشته باشید: ذخیره جزئیات زیرساخت به عنوان اسرار برای گردش کار برنامه CD بسیار مهم است که بعداً به آن خواهیم پرداخت. این اسرار دسترسی ایمن به زیرساخت های مستقر را امکان پذیر می کند.

Terraform اعمال شود

ansible-monitoring.yml و Playbook مرتبط

این گردش کار استقرار پشته مانیتورینگ ما را خودکار می کند و پس از تهیه موفقیت آمیز زیرساخت به طور خودکار فعال می شود. گردش کار به دو صورت اصلی و وجود دارد infra_main شاخه ها برای عملکرد مناسب

name: Monitoring Stack Deployment

on:
  workflow_run:
    workflows: ["Terraform Infrastructure Apply"]
    types:
      - completed

jobs:
  ansible-monitoring:
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    name: Monitoring Stack Deployment
    runs-on: ubuntu-latest

    steps:
      - name: Checkout infra_main Branch
        uses: actions/checkout@v4
        with:
          ref: infra_main  # Explicitly checkout infra_main branch
          fetch-depth: 0   # Get full history

      - name: Download artifacts
        uses: dawidd6/action-download-artifact@v3
        with:
          workflow: terraform-apply.yml
          workflow_conclusion: success
          name: infrastructure-artifacts
          path: ./artifacts

      - name: Check Action Indicator
        id: check-action
        run: |
          ACTION=$(cat ./artifacts/ansible/action_indicator.txt)
          echo "Action: $ACTION"
          if [ "$ACTION" != "apply" ]; then
            echo "Monitoring stack deployment skipped due to action: $ACTION"
            exit 0
          fi

      # Copy the key to the terraform directory
      - name: Setup SSH Key
        run: |
            cp ./artifacts/terraform/${{ vars.KEY_PAIR_NAME }} ./terraform/
            chmod 600 ./terraform/${{ vars.KEY_PAIR_NAME }}

      - name: Update Inventory File
        run: |
          sed -i "s|ansible_ssh_private_key_file=\./${{ vars.KEY_PAIR_NAME }}|ansible_ssh_private_key_file=./terraform/${{ vars.KEY_PAIR_NAME }}|" ./artifacts/ansible/inventory.ini
          cat ./artifacts/ansible/inventory.ini  # Debug print

      - name: Set up Ansible
        uses: alex-oleshkevich/setup-ansible@v1.0.1
        with:
          version: "9.3.0"


      - name: Run Ansible Playbook
        run: |
          ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i ./artifacts/ansible/inventory.ini ./ansible/playbook.yml \
              --extra-vars "domain_name=${{ vars.DOMAIN_NAME }} \
                traefik_domain=${{ vars.TRAEFIK_DOMAIN }} \
                cert_email=${{ vars.CERT_EMAIL }}\
                repo=${{ vars.REPO }}\
                app_dir=${{ vars.APP_DIR }}\
                branch=infra_main"
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک های گردش کار:

    • ماشه خودکار پس از تکمیل ترافورم
    • نشانگر عمل را بررسی می‌کند تا از اجرای صحیح اطمینان حاصل کند که درصورتی‌که گردش کار زمینی اعمال شود فقط برای نابودی فعال شده است
    • فقط در اقدام “اعمال” ادامه می یابد
  2. دسترسی به زیرساخت:

    • مصنوعات تولید شده توسط زمین را بارگیری می کند
    • دسترسی SSH را با استفاده از کلیدهای زیرساخت پیکربندی می کند
    • مسیرها و مجوزهای فایل موجودی را به روز می کند
  3. تنظیم نظارت:

    • پشته نظارت کامل را از طریق Ansible مستقر می کند
    • دامنه ها و گواهی ها را پیکربندی می کند
    • مخزن و دایرکتوری برنامه را تنظیم می کند

بررسی اجمالی کتاب بازی Ansible Associated

main playbook
- name: Setting up application and monitoring servers
  hosts: all
  become: yes
  roles:
    - docker
    - file_setup
    - monitoring_setup
--------
file setup task
- name: Clone the repository
  git:
    repo: "{{ repo }}"
    dest: "{{ app_dir }}"
    version: "{{ branch }}"


- name: Ensure the Traefik directory exists
  file:
    path: "{{ app_dir }}/traefik"
    state: directory
    mode: '0755'

- name: Create acme.json with proper permissions
  file:
    path: "{{ app_dir }}/traefik/acme.json"
    state: touch
    mode: '0600'

- name: Check if the data folder exists
  stat:
    path: "{{ app_dir }}/data"
  register: data_folder

- name: Ensure Loki data folder has the correct ownership and permissions
  block:
    - name: Change ownership of data folder for Loki
      command: chown -R 10001:10001 ./data
      args:
        chdir: "{{ app_dir }}"

    - name: Set permissions for the data folder
      command: chmod -R 755 ./data
      args:
        chdir: "{{ app_dir }}"
  when: data_folder.stat.exists

- name: Configure monitoring compose file using template
  template:
    src: "monitoring_stack_template.j2"
    dest: "{{ app_dir }}/monitoring-stack.yml"
    mode: '0644'
-----
the monitoring task
- name: Bring up the monitoring stack
  command: docker compose -f monitoring-stack.yml up -d
  args:
    chdir: "{{ app_dir }}"
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

کتاب بازی کل تنظیمات نظارت را از طریق سه نقش مجزا هماهنگ می کند:

  1. نقش داکر:

    • اطمینان حاصل می کند که Docker نصب و پیکربندی شده است
    • خدمات Docker مورد نیاز را تنظیم می کند
    • پیش نیازهای شبکه را پیکربندی می کند
  2. نقش تنظیم فایل:

    • مخزن پیکربندی کلون ها
    • ساختار دایرکتوری لازم را ایجاد می کند
    • تنظیمات Traefik و SSL را تنظیم می کند
    • مجوزها و مالکیت را مدیریت می کند
    • دایرکتوری های ماندگاری داده را آماده می کند
  3. نقش تنظیم نظارت:

    • پشته نظارت کامل را مستقر می کند
    • Prometheus، Grafana و Loki را پیکربندی می کند
    • پروکسی معکوس را با Traefik تنظیم می کند
    • اطمینان حاصل می کند که همه سرویس ها در حال اجرا هستند

گردش کار تضمین می کند:

  1. یکپارچگی راه اندازی:

    • ساختار دایرکتوری مناسب
    • مجوزهای فایل را درست کنید
    • تنظیمات مورد نیاز
  2. اقدامات امنیتی:

    • مدیریت امن اعتبارنامه
    • گواهی های محافظت شده
    • مجوزهای فایل مناسب
  3. مولفه های نظارت:

    • پرومتئوس برای معیارها
    • گرافانا برای تجسم
    • لوکی برای سیاهههای مربوط
    • Traefik برای مسیریابی

توجه داشته باشید: این گردش کار وابسته به مصنوعات تولید شده توسط terraform-apply.yml است که وابستگی های گردش کار را در خط لوله زیرساخت ما نشان می دهد و در هر دو قسمت قرار دارد. main شعبه و infra_main شاخه

نظارت غیرممکن

ci-application.yml

این گردش کار فرآیند یکپارچه‌سازی مداوم برنامه ما را مدیریت می‌کند، هنگام به‌روزرسانی پیکربندی‌های استقرار (نوشتن فایل) تصاویر Docker را ایجاد و فشار می‌دهد.

name: Application CI Pipeline

on:

  push:
    branches:
      - 'integration'
    paths:
      - 'backend/**'
      - 'frontend/**'

env:
  DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
  DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
  IMAGE_TAG: 1.0.${{ github.run_number }}
  FRONTEND_IMAGE: frontend-dojodevops
  BACKEND_IMAGE: backend-dojodevops

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }} 
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push backend
        uses: docker/build-push-action@v5
        with:
          context: ./backend
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:${{ env.IMAGE_TAG }}
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:latest

      - name: Build and push frontend
        uses: docker/build-push-action@v5
        with:
          context: ./frontend
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:${{ env.IMAGE_TAG }}
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:latest


      - name: Update docker-compose.yml
        run: |
          echo "=== Current docker-compose template content ==="
          cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

          echo -e "\n=== Attempting to update image tags ==="
          # Update backend image
          sed -i "s|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:.*|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.BACKEND_IMAGE }}:${{ env.IMAGE_TAG }}|" ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
          # Update frontend image
          sed -i "s|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:.*|image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.FRONTEND_IMAGE }}:${{ env.IMAGE_TAG }}|" ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

          echo -e "\n=== Updated docker-compose template content ==="
          cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2

          # Check if any changes were made
          if git diff --quiet ./ansible/roles/app_deploy/templates/docker-compose.yml.j2; then
            echo "No changes were made to docker-compose template"
            echo "Current content of docker-compose template:"
            cat ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
            exit 1
          else
            echo "Changes detected in docker-compose template:"
            git diff ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
          fi

      # Using GitHub's default token for authentication
      - name: Commit and push updated docker-compose
        run: |
          git config --global user.name "${{ github.actor }}"
          git config --global user.email "${{ github.actor }}@users.noreply.github.com"
          git add ./ansible/roles/app_deploy/templates/docker-compose.yml.j2
          git commit -m "Update image tags to ${{ env.IMAGE_TAG }}"
          git push origin integration
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک ها:

    • رویدادها را به integration شاخه
    • فیلترهای مسیر برای دایرکتوری های باطن و فرانت اند
  2. راه اندازی محیط:

    • اعتبار Docker Hub
    • نسخه‌سازی تصویر با استفاده از شماره اجرا GitHub
    • تصاویر مجزا برای فرانت اند و باطن
  3. فرآیند ساخت:

    • راه اندازی Docker Buildx برای ساخت های چند پلتفرمی
    • ساخت های موازی برای فرانت اند و بک اند
    • مدیریت برچسب ها با آخرین و نسخه های برچسب
    • به‌روزرسانی‌های قالب نوشتن Docker

گردش کار تضمین می کند:

  • ساخت خودکار تصاویر
  • کنترل نسخه تصاویر
  • به روز رسانی های پیکربندی
  • برچسب گذاری مناسب تصاویر
  • ارتکاب خودکار تنظیمات به روز شده

ci

cd-application.yml

این گردش کار با استفاده از اسرار زیرساخت از گردش کار قبلی، استقرار مداوم برنامه ما را مدیریت می کند.

name: Application CD Pipeline

on:
  workflow_dispatch:
  pull_request:
    branches:
      - 'deployment'
    types:
      - closed

jobs:
  application-deploy:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    steps:
      - name: Checkout deployment branch
        uses: actions/checkout@v4
        with:
          ref: deployment

      - name: Setup Infrastructure Files
        run: |
          # Create directories
          mkdir -p ./tmp/ ./tmp/ansible

          # Decode and save SSH key
          echo "${{ secrets.EC2_SSH_KEY }}" | base64 -d > ./tmp/${{ vars.KEY_PAIR_NAME }}
          chmod 600 ./tmp/${{ vars.KEY_PAIR_NAME }}

          # Decode and save inventory
          echo "${{ secrets.EC2_INVENTORY }}" | base64 -d > ./tmp/ansible/inventory.ini

      - name: Update Inventory File
        run: |
          sed -i "s|ansible_ssh_private_key_file=\./${{ vars.KEY_PAIR_NAME }}|ansible_ssh_private_key_file=./tmp/${{ vars.KEY_PAIR_NAME }}|" ./tmp/ansible/inventory.ini

      - name: Set up Ansible
        uses: alex-oleshkevich/setup-ansible@v1.0.1
        with:
          version: "9.3.0"

      - name: Run Application Deployment Playbook
        run: |
          ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i ./tmp/ansible/inventory.ini ./ansible/playbook.yml \
            --extra-vars '{
              "repo": "${{ vars.REPO }}",
              "app_dir": "${{ vars.APP_DIR }}",
              "backend_env": ${{ toJSON(secrets.BACKEND_ENV) }},
              "frontend_env": ${{ toJSON(secrets.FRONTEND_ENV) }},
              "frontend_domain": "${{ vars.FRONTEND_DOMAIN }}",
              "DOCKERHUB_USERNAME": "${{ secrets.DOCKERHUB_USERNAME }}",
              "FRONTEND_IMAGE": "frontend-dojodevops",
              "BACKEND_IMAGE": "backend-dojodevops",
              "db_domain": "${{ vars.DB_DOMAIN }}",
              "branch": "deployment"
            }'
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اجزای کلیدی:

  1. محرک ها:

    • کشش درخواست ادغام به deployment شاخه
    • ارسال گردش کار دستی
  2. راه اندازی زیرساخت:

    • از اسرار terraform-apply استفاده می کند:
      • EC2_SSH_KEY برای دسترسی به سرور
      • EC2_INVENTORY برای جزئیات سرور
  3. فرآیند استقرار:

    • پیکربندی Ansible
    • راه اندازی محیط
    • استقرار برنامه

گردش کار تضمین می کند:

  • فرآیند استقرار امن
  • پیکربندی محیط
  • دسترسی به زیرساخت
  • راه‌اندازی برنامه با راه‌اندازی دفترچه راهنما

سی دی

گردش کار کامل

راهنمای متغیرها و اسرار محیطی مهم:

اسرار زیرساخت (تولید شده توسط terraform-apply):

  • EC2_SSH_KEY: کلید SSH کدگذاری شده Base64 برای دسترسی EC2
  • EC2_INVENTORY: فایل موجودی Ansible کدگذاری شده Base64

اعتبار Docker Hub:

  • DOCKERHUB_USERNAME: نام کاربری حساب Docker Hub
  • DOCKERHUB_TOKEN: نشانه دسترسی Docker Hub

متغیرهای محیط کاربردی:

  • BACKEND_ENV: شی JSON حاوی متغیرهای محیطی باطن
  • FRONTEND_ENV: شی JSON حاوی متغیرهای محیطی frontend

پیکربندی دامنه:

  • FRONTEND_DOMAIN: دامنه برای سرویس جلویی
  • DB_DOMAIN: دامنه برای سرویس پایگاه داده

تنظیمات مخزن:

  • REPO: آدرس مخزن
  • APP_DIR: مسیر دایرکتوری برنامه
  • KEY_PAIR_NAME: نام جفت کلید SSH

توجه داشته باشید: گردش کار CD اهمیت مدیریت صحیح محرمانه را با استفاده از اسرار زیرساخت ایجاد شده در حین تهیه برای دسترسی ایمن به استقرار نشان می دهد.

اسرار

متغیرها

وب

تمیز کردن

این را می توان با فعال کردن دستی نابودی زمین انجام داد.

نابود کردن

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا