מדריך קלאודפלייר בעברית

תיעוד 171

Ansible

Ansible הוא כלי תוכנה שמאפשר ניהול תשתית בקנה מידה גדול. Ansible פועל ללא סוכן: כל מה שנדרש כדי שיפעל הוא היכולת לבצע SSH ליעד ו-Python מותקן על היעד.

Ansible עובד לצד Terraform כדי לייעל את תהליך ההגדרה של Cloudflare Tunnel. במדריך זה תשתמש ב-Terraform כדי לפרוס שרת SSH ב-Google Cloud וליצור מנהרה מנוהלת מקומית שהופכת את השרת לזמין דרך האינטרנט. Terraform יריץ באופן אוטומטי playbook של Ansible שמתקין ומגדיר את cloudflared על השרת.

#דרישות מקדימות

כדי להשלים את השלבים במדריך זה, תצטרך:

#1. התקנת Ansible

עיין בהוראות ההתקנה של Ansible ↗︎.

#2. (אופציונלי) יצירת זוג מפתחות SSH

Terraform ו-Ansible דורשים מפתח SSH לא מוצפן כדי להתחבר לשרת GCP. אם עדיין אין לך מפתח, אפשר ליצור אחד כך:

  1. פתח מסוף והקלד את הפקודה הבאה:

    ssh-keygen -t rsa -f ~/.ssh/gcp_ssh -C <username in GCP>
  2. כשמתבקש passphrase, לחץ על מקש Enter פעמיים כדי להשאיר אותו ריק. Terraform לא יכול לפענח מפתחות פרטיים מוצפנים.

יווצרו שני קבצים: gcp_ssh שמכיל את המפתח הפרטי, ו-gcp_ssh.pub שמכיל את המפתח הציבורי.

#3. יצירת ספריית תצורה

  1. צור תיקייה לקובצי התצורה של Terraform ושל Ansible:

    mkdir ansible-tunnel
  2. עבור לספרייה החדשה:

    cd ansible-tunnel

#4. יצירת קובצי תצורה של Terraform

#הגדרת משתני קלט

המשתנים הבאים יועברו לתצורה של GCP ושל Cloudflare.

  1. בספריית התצורה, צור קובץ .tf:

    touch variables.tf
  2. פתח את הקובץ בעורך טקסט והעתק והדבק את התוכן הבא:

    # GCP variables
    variable "gcp_project_id" {
      description = "Google Cloud Platform (GCP) project ID"
      type        = string
    }
    
    variable "zone" {
      description = "Geographical zone for the GCP VM instance"
      type        = string
    }
    
    variable "machine_type" {
      description = "Machine type for the GCP VM instance"
      type        = string
    }
    
    # Cloudflare variables
    variable "cloudflare_zone" {
      description = "Domain used to expose the GCP VM instance to the Internet"
      type        = string
    }
    
    variable "cloudflare_zone_id" {
      description = "Zone ID for your domain"
      type        = string
    }
    
    variable "cloudflare_account_id" {
      description = "Account ID for your Cloudflare account"
      type        = string
      sensitive   = true
    }
    
    variable "cloudflare_email" {
      description = "Email address for your Cloudflare account"
      type        = string
      sensitive   = true
    }
    
    variable "cloudflare_token" {
      description = "Cloudflare API token"
      type        = string
      sensitive   = true
    }

#הקצאת ערכים למשתנים

  1. בספריית התצורה, צור קובץ .tfvars:

    touch terraform.tfvars

    Terraform ישתמש במשתנים האלה באופן אוטומטי אם שם הקובץ הוא terraform.tfvars, אחרת יהיה צורך להעביר את קובץ המשתנים ידנית.

  2. הוסף את המשתנים הבאים ל-terraform.tfvars. הקפד לשנות את הדוגמה לערכים שלך.

    cloudflare_zone           = "example.com"
    cloudflare_zone_id        = "023e105f4ecef8ad9ca31a8372d0c353"
    cloudflare_account_id     = "372e67954025e0ba6aaa6d586b9e0b59"
    cloudflare_email          = "[email protected]"
    cloudflare_token          = "y3AalHS_E7Vabk3c3lX950F90_Xl7YtjSlzyFn_X"
    gcp_project_id            = "testvm-123"
    zone                      = "us-central1-a"
    machine_type              = "e2-medium"

זהירות

כדי למנוע חשיפה מקרית של פרטי גישה רגישים, אל תשמור את terraform.tfvars במערכת בקרת הגרסאות שלך. לדוגמה, אם בקרת הגרסאות שלך היא git, הוסף את terraform.tfvars לקובץ .gitignore.

#הגדרת ספקי Terraform

יהיה עליך להצהיר על הספקים ↗︎ שמשמשים להקצאת התשתית.

  1. בספריית התצורה, צור קובץ .tf:

    touch providers.tf
  2. הוסף את הספקים הבאים ל-providers.tf. הספק random משמש ליצירת סוד של מנהרה.

    terraform {
        required_providers {
            cloudflare = {
                source = "cloudflare/cloudflare"
                version = ">= 5.8.2"
            }
            google = {
                source = "hashicorp/google"
            }
        }
        required_version = ">= 1.2"
    }
    
    # Providers
    provider "cloudflare" {
        api_token    = var.cloudflare_token
    }
    provider "google" {
        project    = var.gcp_project_id
    }
    provider "random" {
    }

#הגדרת משאבי Cloudflare

התצורה הבאה תשנה הגדרות בחשבון Cloudflare שלך.

  1. בספריית התצורה, צור קובץ .tf:

    touch Cloudflare-config.tf
  2. הוסף את המשאבים הבאים ל-Cloudflare-config.tf:

    # Creates a new remotely-managed tunnel for the GCP VM.
    resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" {
        account_id    = var.cloudflare_account_id
        name          = "Ansible GCP tunnel"
        config_src    = "cloudflare"
    }
    
    # Reads the token used to run the tunnel on the server.
    data "cloudflare_zero_trust_tunnel_cloudflared_token" "gcp_tunnel_token" {
        account_id     = var.cloudflare_account_id
        tunnel_id     = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id
    }
    
    # Creates the CNAME record that routes http_app.${var.cloudflare_zone} to the tunnel.
    resource "cloudflare_dns_record" "http_app" {
        zone_id = var.cloudflare_zone_id
        name    = "http_app"
        content = "${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id}.cfargotunnel.com"
        type    = "CNAME"
        ttl     = 1
        proxied = true
    }
    
    # Configures tunnel with a published application for clientless access.
    resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gcp_tunnel_config" {
        tunnel_id  = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id
        account_id = var.cloudflare_account_id
        config     = {
            ingress     = [
                {
                    hostname = "http_app.${var.cloudflare_zone}"
                    service  = "http://localhost:80"
                },
                {
                    service  = "http_status:404"
                }
            ]
        }
    }

#הגדרת משאבי GCP

התצורה הבאה מגדירה את המפרט של המכונה הווירטואלית ב-GCP ומתקינה את Python3 על המכונה. Python3 מאפשר ל-Ansible להגדיר את מופע GCP במקום להריץ סקריפט הפעלה בעת האתחול.

  1. בספריית התצורה, צור קובץ .tf:

    touch GCP-config.tf
  2. פתח את הקובץ בעורך טקסט והעתק והדבק את הדוגמה הבאה. הקפד להכניס את שם המשתמש שלך ב-GCP ואת זוג מפתחות ה-SSH שלך.

    # Selects the OS for the GCP VM.
    data "google_compute_image" "image" {
    family  = "ubuntu-2204-lts"
    project = "ubuntu-os-cloud"
    }
    
    # Sets up a GCP VM instance.
    resource "google_compute_instance" "http_server" {
    name         = "ansible-inst"
    machine_type = var.machine_type
    zone         = var.zone
    tags         = []
    boot_disk {
        initialize_params {
        image = data.google_compute_image.image.self_link
        }
    }
    network_interface {
        network = "default"
        access_config {
        // Ephemeral IP
        }
    }
    scheduling {
        preemptible = true
        automatic_restart = false
    }
    
    // Installs Python3 on the VM.
    provisioner "remote-exec" {
        inline = [
        "sudo apt update", "sudo apt install python3 -y",  "echo Done!"
        ]
        connection {
        host = self.network_interface.0.access_config.0.nat_ip
        user = "<username in GCP>"
        type = "ssh"
        private_key= file("<path to private key>")
        }
    }
    provisioner "local-exec" {
        // If specifying an SSH key and user, add `--private-key <path to private key> -u var.name`
        command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u <username in GCP> --private-key <path to private key> -i ${self.network_interface.0.access_config.0.nat_ip}, playbook.yml"
    }
    
    metadata = {
        cf-email     = var.cloudflare_email
        cf-zone      = var.cloudflare_zone
        ssh-keys     = "<username in GCP>:${file("<path to public key>")}"
    }
    depends_on = [
        local_file.tf_ansible_vars_file
    ]
    }

#ייצוא משתנים ל-Ansible

משאב Terraform הבא מייצא את אסימון המנהרה ומשתנים נוספים אל tf_ansible_vars_file.yml. Ansible ישתמש באסימון המנהרה כדי להגדיר ולהריץ את cloudflared על השרת.

  1. בספריית התצורה, צור קובץ tf חדש:

    touch export.tf
  2. העתק והדבק את התוכן הבא אל export.tf:

    resource "local_file" "tf_ansible_vars_file" {
        content = <<-DOC
            # Ansible vars_file containing variable values from Terraform.
            tunnel_id: ${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id}
            tunnel_name: ${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.name}
            tunnel_token: ${data.cloudflare_zero_trust_tunnel_cloudflared_token.gcp_tunnel_token.token}
            DOC
    
        filename = "./tf_ansible_vars_file.yml"
    }

#5. יצירת ה-playbook של Ansible

playbook של Ansible הם קובצי YAML שמצהירים על התצורה ש-Ansible יפרוס.

  1. צור קובץ .yml חדש:

    touch playbook.yml
  2. פתח את הקובץ בעורך טקסט והעתק והדבק את התוכן הבא:

---
- hosts: all
  become: yes
  # Import tunnel variables into the VM.
  vars_files:
    - ./tf_ansible_vars_file.yml
  # Execute the following commands on the VM.
  tasks:
    - name: Download the cloudflared Linux package.
      shell: wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
    - name: Depackage cloudflared.
      shell: sudo dpkg -i cloudflared-linux-amd64.deb
    - name: Install the tunnel as a systemd service.
      shell: "cloudflared service install {{ tunnel_token }}"
    - name: Start the tunnel.
      systemd:
        name: cloudflared
        state: started
        enabled: true
        masked: no
    - name: Deploy an example Apache web server on port 80.
      shell: apt update && apt -y install apache2
    - name: Edit the default Apache index file.
      copy:
        dest: /var/www/html/index.html
        content: |
          <!DOCTYPE html>
          <html>
          <body>
            <h1>Hello Cloudflare!</h1>
            <p>This page was created for a Cloudflare demo.</p>
          </body>
          </html>

מילות מפתח ↗︎ מגדירות כיצד Ansible יבצע את התצורה. בדוגמה שלמעלה, מילת המפתח vars_files מציינת היכן מאוחסנות הגדרות המשתנים, ומילת המפתח tasks מציינת את הפעולות ש-Ansible יבצע.

מודולים ↗︎ מציינים אילו משימות להשלים. בדוגמה זו, המודול copy יוצר קובץ וממלא אותו בתוכן.

#6. פריסת התצורה

אחרי שיצרת את קובצי התצורה, אפשר לפרוס אותם באמצעות Terraform. פריסת Ansible מתרחשת בתוך פריסת Terraform כאשר הפקודה ansible-playbook רצה.

  1. אתחל את ספריית התצורה:

    terraform init
  2. (אופציונלי) הצג תצוגה מקדימה של כל מה שייווצר:

    terraform plan
  3. פרוס את התצורה:

    terraform apply

ייתכן שיחלפו כמה דקות עד שמופע GCP והמנהרה יעלו. אפשר לראות את המנהרה החדשה בלוח הבקרה של Cloudflare תחת Networking > Tunnels.

#7. בדיקת החיבור

לבדיקה, פתח דפדפן ועבור אל http://http_app.<CLOUDFLARE_ZONE>.com (לדוגמה, http_app.example.com). אמור להופיע דף הבדיקה Hello Cloudflare!.