INTEGRITY Документация

Ansible

Ansible представляет собой программный инструмент для масштабного управления инфраструктурой. Ansible не требует агента: для работы ему нужны только доступ по SSH к целевому узлу и установленный на нём Python.

Ansible работает вместе с Terraform, упрощая настройку Cloudflare Tunnel. В этом руководстве вы используете Terraform, чтобы развернуть SSH-сервер в Google Cloud и создать туннель с локальным управлением который делает сервер доступным через интернет. Terraform автоматически запустит плейбук Ansible, который установит и настроит cloudflared на сервере.

Предварительные требования

Чтобы выполнить шаги этого руководства, вам потребуется:

1. Установите Ansible

См. Инструкции по установке Ansible.

2. (Необязательно) Создайте пару ключей SSH

Для подключения к серверу GCP Terraform и Ansible требуют незашифрованный SSH ключ. Если у вас его ещё нет, создайте его следующим образом:

  1. Откройте терминал и введите следующую команду:

    ssh-keygen -t rsa -f ~/.ssh/gcp_ssh -C <username in GCP>
  2. Когда появится запрос парольной фразы, нажмите Enter клавишу дважды, чтобы оставить его пустым. Terraform не может расшифровать зашифрованные приватные ключи.

Two files will be generated: 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

Вам нужно будет объявить поставщики используется для развёртывания инфраструктуры.

  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. Создайте 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 в разделе Zero Trust > Сети > Connectors > Cloudflare Tunnels.

7. Проверьте подключение

Чтобы протестировать, откройте браузер и перейдите в http://http_app.<CLOUDFLARE_ZONE>.com (например, http_app.example.com). Вы должны увидеть Hello Cloudflare! тестовая страница.