Spec-Zone.ru › Ansible 2.8

Руководство по CloudStack

Введение

Цель этого раздела — объяснить, как объединить модули Ansible для использования Ansible в контексте CloudStack. Вы найдете больше примеров использования в разделе «Подробности» каждого модуля.

Ansible содержит ряд дополнительных модулей для взаимодействия с облаками на основе CloudStack. Все модули поддерживают режим проверки, разработаны для идемпотентности, созданы и протестированы, а также поддерживаются сообществом.

Примечание

Некоторые модули потребуют прав администратора домена или администратора корня.

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

Предварительные условия для использования модулей CloudStack минимальны. Помимо самого Ansible, все модули требуют библиотеку Python cs https://pypi.org/project/cs/

Эта библиотека Python должна быть установлена на хосте выполнения, обычно на вашей рабочей станции.

$ pip install cs

Или, как альтернатива, начиная с Debian 9 и Ubuntu 16.04:

$ sudo apt install python-cs

Примечание

cs также включает командную строку для выполнения ad-hoc операций с API CloudStack, например $ cs listVirtualMachines state=Running.

Ограничения и известные проблемы

Поддержка VPC была улучшена с Ansible 2.3, но все еще не полностью реализована. Сообщество работает над интеграцией VPC.

Файл учетных данных

Вы можете передать учетные данные и конечную точку своего облака в качестве аргументов модуля, однако в большинстве случаев гораздо проще хранить учетные данные в файле cloudstack.ini.

Библиотека Python cs ищет файл учетных данных в следующем порядке (последний имеет приоритет):

  • Файл .cloudstack.ini (обратите внимание на точку) в домашнем каталоге.
  • Переменная среды CLOUDSTACK_CONFIG, указывающая на файл .ini.
  • Файл cloudstack.ini (без точки) в текущей рабочей директории, той же директории, что и ваши плейбуки.

Структура файла ini должна быть такой:

$ cat $HOME/.cloudstack.ini
[cloudstack]
endpoint = https://cloud.example.com/client/api
key = api key
secret = api secret
timeout = 30

Примечание

Раздел [cloudstack] — это раздел по умолчанию. Переменная среды CLOUDSTACK_REGION может использоваться для определения раздела по умолчанию.

Введено в версии 2.4.

Переменные среды поддерживают CLOUDSTACK_* как указано в документации библиотеки cs, например CLOUDSTACK_TIMEOUT, CLOUDSTACK_METHOD, и т.д. были реализованы в Ansible. Даже возможно иметь неполную конфигурацию в вашем cloudstack.ini:

$ cat $HOME/.cloudstack.ini
[cloudstack]
endpoint = https://cloud.example.com/client/api
timeout = 30

и заполнить недостающие данные, установив переменные среды или параметры задач:

---
- name: provision our VMs
  hosts: cloud-vm
  tasks:
    - name: ensure VMs are created and running
      delegate_to: localhost
      cs_instance:
        api_key: your api key
        api_secret: your api secret
        ...

Регионы

Если вы используете более одного региона CloudStack, вы можете определить столько разделов, сколько нужно, и назвать их как вам угодно, например:

$ cat $HOME/.cloudstack.ini
[exoscale]
endpoint = https://api.exoscale.ch/compute
key = api key
secret = api secret

[example_cloud_one]
endpoint = https://cloud-one.example.com/client/api
key = api key
secret = api secret

[example_cloud_two]
endpoint = https://cloud-two.example.com/client/api
key = api key
secret = api secret

Подсказка

Разделы также могут использоваться для входа в тот же регион с использованием разных учетных записей.

Передав аргумент api_region с модулями CloudStack, будет выбран нужный регион.

- name: ensure my ssh public key exists on Exoscale
  cs_sshkeypair:
    name: my-ssh-key
    public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    api_region: exoscale
  delegate_to: localhost

Или, пропуская список регионов, если вы хотите выполнить задачу в каждом регионе:

- name: ensure my ssh public key exists in all CloudStack regions
  local_action: cs_sshkeypair
    name: my-ssh-key
    public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
    api_region: "{{ item }}"
    loop:
      - exoscale
      - example_cloud_one
      - example_cloud_two

Переменные окружения

Введено в версии 2.3.

С Ansible 2.3 появилась возможность использовать переменные окружения для домена (CLOUDSTACK_DOMAIN), учетной записи (CLOUDSTACK_ACCOUNT), проекта (CLOUDSTACK_PROJECT), VPC (CLOUDSTACK_VPC) и зоны (CLOUDSTACK_ZONE). Это упрощает задачи, не повторяя аргументы для каждой задачи.

Ниже приведен пример использования в сочетании с блоком Ansible:

- hosts: cloud-vm
  tasks:
    - block:
        - name: ensure my ssh public key
          cs_sshkeypair:
            name: my-ssh-key
            public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

        - name: ensure my ssh public key
          cs_instance:
              display_name: "{{ inventory_hostname_short }}"
              template: Linux Debian 7 64-bit 20GB Disk
              service_offering: "{{ cs_offering }}"
              ssh_key: my-ssh-key
              state: running

      delegate_to: localhost
      environment:
        CLOUDSTACK_DOMAIN: root/customers
        CLOUDSTACK_PROJECT: web-app
        CLOUDSTACK_ZONE: sf-1

Примечание

Вы по-прежнему можете перезаписать переменные окружения, используя аргументы модуля, например zone: sf-2

Примечание

В отличие от CLOUDSTACK_REGION эти дополнительные переменные окружения игнорируются в CLI cs.

Примеры использования

Следующие примеры помогут вам понять, как использовать модули для развертывания виртуальных машин в облаке. Как всегда, существует не только один способ сделать это. Но как всегда: начните с простого.

Пример использования: Развертывание в облаке CloudStack с расширенной сетью

Наше облако CloudStack имеет расширенную сетевую конфигурацию. Мы хотим развернуть веб-серверы, которые получат статический NAT и откроют порты 80 и 443 для брандмауэра. Кроме того, мы развернем серверы базы данных, к которым не будет доступа. Для доступа к виртуальным машинам по SSH мы используем SSH-прокси-сервер.

Вот как выглядит наш инвентаризация:

[cloud-vm:children]
webserver
db-server
jumphost

[webserver]
web-01.example.com  public_ip=198.51.100.20
web-02.example.com  public_ip=198.51.100.21

[db-server]
db-01.example.com
db-02.example.com

[jumphost]
jump.example.com  public_ip=198.51.100.22

Как видите, общедоступные IP-адреса для наших веб-серверов и SSH-прокси-сервера были назначены как переменные public_ip непосредственно в инвентаризации.

Для настройки SSH-прокси-сервера, веб-серверов и серверов базы данных мы используем group_vars. Директория group_vars содержит 4 файла для конфигурации групп: cloud-vm, jumphost, webserver и db-server. Группа cloud-vm предназначена для указания параметров нашей облачной инфраструктуры.

# file: group_vars/cloud-vm
---
cs_offering: Small
cs_firewall: []

Наши серверы базы данных должны получить больше процессорного времени и оперативной памяти, поэтому мы определили использование Large предложения для них.

# file: group_vars/db-server
---
cs_offering: Large

Веб-серверы должны получить Small предложение, так как мы хотим масштабировать их горизонтально, что также является нашим предложением по умолчанию. Мы также гарантируем, что известные веб-порты открыты для всех.

# file: group_vars/webserver
---
cs_firewall:
  - { port: 80 }
  - { port: 443 }

Кроме того, мы развертываем SSH-прокси-сервер, на котором открыт только порт 22 для доступа к виртуальным машинам из нашей офисной IPv4-сети.

# file: group_vars/jumphost
---
cs_firewall:
  - { port: 22, cidr: "17.17.17.0/24" }

Теперь самое интересное. Мы создаем плейбук для создания нашей инфраструктуры, мы называем его infra.yml:

# file: infra.yaml
---
- name: provision our VMs
  hosts: cloud-vm
  tasks:
    - name: run all enclosed tasks from localhost
      delegate_to: localhost
      block:
        - name: ensure VMs are created and running
          cs_instance:
            name: "{{ inventory_hostname_short }}"
            template: Linux Debian 7 64-bit 20GB Disk
            service_offering: "{{ cs_offering }}"
            state: running

        - name: ensure firewall ports opened
          cs_firewall:
            ip_address: "{{ public_ip }}"
            port: "{{ item.port }}"
            cidr: "{{ item.cidr | default('0.0.0.0/0') }}"
          loop: "{{ cs_firewall }}"
          when: public_ip is defined

        - name: ensure static NATs
          cs_staticnat: vm="{{ inventory_hostname_short }}" ip_address="{{ public_ip }}"
          when: public_ip is defined

В этом плейбуке мы определили 3 задачи и используем группу cloud-vm в качестве цели для обработки всех виртуальных машин в облаке, но вместо SSH к этим виртуальным машинам, мы используем delegate_to: localhost для выполнения вызовов API локально со своей рабочей станции.

В первой задаче мы гарантируем, что создана работающая виртуальная машина с шаблоном Debian. Если виртуальная машина уже создана, но остановлена, она просто запустится. Если вы хотите изменить предложение на существующей виртуальной машине, вы должны добавить force: yes в задачу, что остановит виртуальную машину, изменит предложение и запустит её снова.

Во второй задаче мы гарантируем, что порты открыты, если мы назначаем общедоступный IP-адрес виртуальной машине.

В третьей задаче мы добавляем статический NAT для виртуальных машин, имеющих заданный общедоступный IP-адрес.

Примечание

Общедоступные IP-адреса должны быть получены заранее, см. также cs_ip_address

Примечание

Для некоторых модулей, например cs_sshkeypair вы обычно хотите, чтобы это выполнялось только один раз, а не для каждой виртуальной машины. Поэтому вы создадите отдельный плейбук для него, нацеленный на localhost. Пример вы найдете в примерах использования ниже.

Пример использования: Развертывание в облаке CloudStack с базовой сетью

Конфигурация CloudStack с базовой сетью немного отличается: каждой виртуальной машине напрямую назначается общедоступный IP-адрес, и для ограничения доступа используются группы безопасности.

Вот как выглядит наш инвентаризация:

[cloud-vm:children]
webserver

[webserver]
web-01.example.com
web-02.example.com

Параметры по умолчанию для ваших виртуальных машин выглядят следующим образом:

# file: group_vars/cloud-vm
---
cs_offering: Small
cs_securitygroups: [ 'default']

Наш веб-сервер также будет находиться в группе безопасности web:

# file: group_vars/webserver
---
cs_securitygroups: [ 'default', 'web' ]

Плейбук выглядит следующим образом:

# file: infra.yaml
---
- name: cloud base setup
  hosts: localhost
  tasks:
  - name: upload ssh public key
    cs_sshkeypair:
      name: defaultkey
      public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

  - name: ensure security groups exist
    cs_securitygroup:
      name: "{{ item }}"
    loop:
      - default
      - web

  - name: add inbound SSH to security group default
    cs_securitygroup_rule:
      security_group: default
      start_port: "{{ item }}"
      end_port: "{{ item }}"
    loop:
      - 22

  - name: add inbound TCP rules to security group web
    cs_securitygroup_rule:
      security_group: web
      start_port: "{{ item }}"
      end_port: "{{ item }}"
    loop:
      - 80
      - 443

- name: install VMs in the cloud
  hosts: cloud-vm
  tasks:
  - delegate_to: localhost
    block:
    - name: create and run VMs on CloudStack
      cs_instance:
        name: "{{ inventory_hostname_short }}"
        template: Linux Debian 7 64-bit 20GB Disk
        service_offering: "{{ cs_offering }}"
        security_groups: "{{ cs_securitygroups }}"
        ssh_key: defaultkey
        state: Running
      register: vm

    - name: show VM IP
      debug: msg="VM {{ inventory_hostname }} {{ vm.default_ip }}"

    - name: assign IP to the inventory
      set_fact: ansible_ssh_host={{ vm.default_ip }}

    - name: waiting for SSH to come up
      wait_for: port=22 host={{ vm.default_ip }} delay=5

В первом плейбуке мы настраиваем группы безопасности, во втором плейбуке виртуальные машины будут созданы и назначены этим группам. Кроме того, вы видите, что мы назначаем общедоступный IP-адрес, возвращенный модулями, в инвентаризацию хоста. Это необходимо, так как мы не знаем заранее полученные IP-адреса. На следующем шаге вы настроите DNS-серверы с этими IP-адресами для доступа к виртуальным машинам по их имени DNS.

В последней задаче мы ждем доступ по SSH, чтобы любой последующий плейбук мог получить доступ к виртуальной машине по SSH без сбоев.

© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.8/scenario_guides/guide_cloudstack.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API