我在让 Ansible 与 Digital Ocean APIv2 协同部署多个 droplet 时遇到了一些概念上的困难。通常,我会在 Ansible hosts 文件中定义一个主机列表,这就是 Ansible 遍历每个主机进行配置的方式,但由于在部署新主机时,我们正在与 localhost 通信(即真正与 Digital Oceans API 通信),我无法弄清楚如何遍历要部署的整个新主机列表。我的剧本非常适合单个节点。现在,系统会提示用户输入正在创建的新 droplet 的主机名。但理想情况下,我想针对 20 个主机名的列表运行剧本,剧本会在没有用户干预的情况下创建所有 20 个主机。有人可以帮忙吗?
---
- hosts: localhost
vars_prompt:
- name: "hostname"
prompt: "Hostname of new droplet?"
private: no
vars:
do_token: PRIVATE_TOKEN_HERE
tasks:
- name: Create new droplet
digital_ocean: >
state=present
command=droplet
name={{ hostname }}
unique_name=yes
size_id=512mb
region_id=nyc3
image_id=ubuntu-18-04-x64
ssh_key_ids=PRIVATE_SSH_KEY_HERE
api_token={{ do_token }}
wait_timeout=500
register: hostname
- name: Add host to Ansible config
lineinfile:
dest: "/etc/ansible/hosts"
insertafter: '^\[DROPLETS\]'
state: present
line: "{{ hostname.droplet.name }} ansible_ssh_host={{ hostname.droplet.ip_address }}"
答案1
在文件中定义主机列表并将其用作清单是可行的方法。您只需使用delegate_to: localhost
或connection: local
来执行调用 DO 的 API 的任务。例如:
tasks:
- name: Create new droplet
digital_ocean: >
state=present
...
delegate_to: localhost
- name: Add the user 'johnd' with a specific uid and primary group of 'admin'
user:
name: johnd
comment: John Doe
uid: 1040
group: admin
如果 ansible 主机上没有配置 DO api 访问,那么你可以在你的delegate_to:
编辑以回应评论:
是的,要么创建一个单独的清单文件并--inventory-file
在运行剧本时使用,要么创建一个组PROVISION
(这是我下面使用的)。注意使用inventory_hostname
---
- hosts: PROVISION
vars:
do_token: PRIVATE_TOKEN_HERE
tasks:
# runs on ansible control host
- name: Create new droplet
digital_ocean: >
state=present
command=droplet
name={{ inventory_hostname }}
unique_name=yes
size_id=512mb
region_id=nyc3
image_id=ubuntu-18-04-x64
ssh_key_ids=PRIVATE_SSH_KEY_HERE
api_token={{ do_token }}
wait_timeout=500
register: hostname
delegate_to: localhost
# runs on ansible control host
- name: Add host to Ansible config
lineinfile:
dest: "/etc/ansible/hosts"
insertafter: '^\[DROPLETS\]'
state: present
line: "{{ hostname.droplet.name }} ansible_ssh_host={{ hostname.droplet.ip_address }}"
delegate_to: localhost
# runs on newly created droplet
- name: Add the user 'johnd' with a specific uid and primary group of 'admin'
user:
name: johnd
comment: John Doe
uid: 1040
group: admin