پیاده سازی خط لوله 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 می پردازد:
- نحوه نگهداری زیرساخت به عنوان کد با اعتبارسنجی مناسب و کنترل هزینه
- نحوه خودکارسازی استقرار سیستم نظارت در کنار زیرساخت
- نحوه مدیریت استقرار برنامه ها با نسخه سازی و عرضه مناسب
- چگونه می توان زیرساخت ها و استقرار برنامه ها را جدا و در عین حال هماهنگ نگه داشت
نمای کلی معماری
بررسی اجمالی پروژه
اجزای اصلی و ساختار گردش کار
این پروژه در دو خط لوله اصلی سازماندهی شده است:
-
خط لوله زیرساخت (
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 خودکار با:
- تغییرات زیرساختی
- برآورد هزینه
- اصلاحات منابع
- مقایسه پایه در مقابل پیشنهاد
- نظرات 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 برای جزئیات سرور
- از اسرار terraform-apply استفاده می کند:
-
فرآیند استقرار:
- پیکربندی Ansible
- راه اندازی محیط
- استقرار برنامه
گردش کار تضمین می کند:
- فرآیند استقرار امن
- پیکربندی محیط
- دسترسی به زیرساخت
- راهاندازی برنامه با راهاندازی دفترچه راهنما
راهنمای متغیرها و اسرار محیطی مهم:
اسرار زیرساخت (تولید شده توسط terraform-apply):
EC2_SSH_KEY
: کلید SSH کدگذاری شده Base64 برای دسترسی EC2EC2_INVENTORY
: فایل موجودی Ansible کدگذاری شده Base64اعتبار Docker Hub:
DOCKERHUB_USERNAME
: نام کاربری حساب Docker HubDOCKERHUB_TOKEN
: نشانه دسترسی Docker Hubمتغیرهای محیط کاربردی:
BACKEND_ENV
: شی JSON حاوی متغیرهای محیطی باطنFRONTEND_ENV
: شی JSON حاوی متغیرهای محیطی frontendپیکربندی دامنه:
FRONTEND_DOMAIN
: دامنه برای سرویس جلوییDB_DOMAIN
: دامنه برای سرویس پایگاه دادهتنظیمات مخزن:
REPO
: آدرس مخزنAPP_DIR
: مسیر دایرکتوری برنامهKEY_PAIR_NAME
: نام جفت کلید SSHتوجه داشته باشید: گردش کار CD اهمیت مدیریت صحیح محرمانه را با استفاده از اسرار زیرساخت ایجاد شده در حین تهیه برای دسترسی ایمن به استقرار نشان می دهد.
تمیز کردن
این را می توان با فعال کردن دستی نابودی زمین انجام داد.