Ansible命令


文档摘要

Ansible 命令 安装 sh yum install ansible apt install ansible sh pip3 install ansible for python2 - default installation pip install ansible 卸载 sh rm -rf $HOME/.ansible rm -rf $HOME/.ansible.cfg sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible-2.5.4.

Ansible 命令

安装

```sh yum install ansible apt install ansible
pip3 install ansible # for python2 - default installation pip install ansible

远程机器应该有 'python' - 'gather_facts: False' 或 'gather_facts: no',否则

## 卸载 ```bash ```sh rm -rf $HOME/.ansible rm -rf $HOME/.ansible.cfg sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible-2.5.4.dist-info sudo rm -rf /usr/local/bin/ansible sudo rm -rf /usr/local/bin/ansible-config sudo rm -rf /usr/local/bin/ansible-connection sudo rm -rf /usr/local/bin/ansible-console sudo rm -rf /usr/local/bin/ansible-doc sudo rm -rf /usr/local/bin/ansible-galaxy sudo rm -rf /usr/local/bin/ansible-inventory sudo rm -rf /usr/local/bin/ansible-playbook sudo rm -rf /usr/local/bin/ansible-pull sudo rm -rf /usr/local/bin/ansible-vault sudo rm -rf /usr/lib/python2.7/dist-packages/ansible sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible
## Ansible 配置位置 * 路径变量 $Ansible_Config * ~/.ansible.cfg * /etc/ansible/ansible.cfg ```bash ```sh ansible-config view # list of possible environment variables ansible-config dump
### 外部角色的配置 文件名: ~/.ansible.cfg ```bash ```properties [defaults] roles_path = ~/repos/project1/roles:~/repos/project2/roles
### 检查配置 ```bash ```sh ansible-config view
## 清单 ### 没有清单的内联主机 IP ```bash

ansible all -i desp000111.vantage.zur, --user=my_user -m "ping" -vvv

没有清单使用 PEM SSH 私钥

生成 PEM 文件

```sh ssh-keygen -t rsa -b 4096 -m PEM -f my_ssh_key.pem ll my_ssh_key.pem ansible all -i desp000111.vantage.zur, --user=vitalii.cherkashyn -e ansible_ssh_private_key_file=my_ssh_key.pem -m "ping" -vvv
### INI 文件 ```bash ```properties # example cfg file [web] host1 host2 ansible_port=222 # defined inline, interpreted as an integer [web:vars] http_port=8080 # all members of 'web' will inherit these myvar=23 # defined in a :vars section, interpreted as a string
## 使用特定的远程 Python 版本执行、重写默认变量、重写变量、覆盖变量 ```bash

--extra-vars "remote_folder=$REMOTE_FOLDER ansible_python_interpreter=/usr/bin/python"

只对一个主机执行 Ansible、一个主机、一个远程服务器、详细模式

```sh ansible-playbook -i "ubs000015.vantage.org , " mkdir.yaml ansible-playbook welcome-message.yaml -i airflow-test-account-01.ini --limit worker --extra-vars="ACCOUNT_ID=QA01" --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -vvv ansible all -i airflow-test-account-01.ini --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -m "ping" -vvv ansible main,worker -i airflow-test-account-01.ini --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -m "ping"

创建一个简单的文件来建立一个文件夹

```yaml - hosts: all tasks: - name: Creates directory file: path: ~/spark-submit/trafficsigns state: directory mode: 0775 - name: copy all files from folder copy: src: "/home/projects/ubs/current-task/nodes/ansible/files" dest: ~/spark-submit/trafficsigns mode: 0775 - debug: msg='folder was amazoncreated for host {{ ansible_host }}'
## 在本地执行 Ansible、本地执行 ```bash ```sh # --extra-vars="mapr_stream_path={{ some_variable_from_previous_files }}/some-argument" \ ansible localhost \ --extra-vars="deploy_application=1" \ --extra-vars=@group_vars/all/vars/all.yml \ --extra-vars=@group_vars/ubs-staging/vars/ubs-staging.yml \ -m include_role \ -a name="roles/labeler"
## 使用外部参数执行 ansible-playbook、带参数的 Bash 脚本 ansible-playbook、额外变量、外部变量、环境变量 ```bash ```j2 # variable from env {{ lookup('env','DB_VARIANT_USERNAME') }}
ansible-playbook -i inventory.ini playbook.yml --extra-vars "$*"

带有指向外部参数文件的路径、从外部文件添加附加变量

```sh ansible-playbook -i inventory.ini playbook.yml --extra-vars @/path/to/var.properties ansible-playbook playbook.yml --extra-vars=@/path/to/var.properties
## 内联外部变量 ```bash ```sh ansible-playbook playbook.yml --extra-vars="oc_project=scenario-test mapr_stream_path=/mapr/prod.zurich/vantage/scenario-test"
## 检查是否工作、即席命令 ```bash ```sh ansible remote* -i inventory.ini -m "ping" ansible remote* -i inventory.ini --module-name "ping"
ansible remote* -i inventory.ini -a "hostname"
## 循环示例 ```bash ```sh - name: scripts {{ item }} template: mode: 0777 src: "templates/{{ item }}" dest: "{{ root_folder }}/{{ item }}" loop: - "start-all.sh" - "status.sh" - "stop-all.sh"
## 重复执行 ```bash ```sh --limit {playbookfile}.retry
## 从任务开始执行、从任务开始执行、从任务开始执行、跳过之前的任务 ```bash ```sh ansible-playbook playbook.yml --start-at-task="name of the start to be started from"
## 将文件中的变量替换到专用文件中、将变量移动到单独的文件中 * 之前 ```bash ```yaml vars: db_user: my_user db_password: my_password ansible_ssh_pass: my_ssh_password ansible_host: 192.168.1.14
  • 之后
  • ('vars' 块为空)
    文件路径:
```sh ./host_vars/id_of_the_server

或 groupvars:

```sh ./group_vars/id_of_the_group_into_square_brakets

代码

```yaml db_user: my_user db_password: my_password ansible_ssh_pass: my_ssh_password ansible_host: 192.168.1.14
## 将代码移到单独的文件中、任务移到文件中 从原始文件剪切代码并粘贴到单独的文件中(必须适当对齐), 替换代码为: ```bash ```yaml - include: path_to_folder/path_to_file

应创建适当的文件:

```sh ./path_to_folder/path_to_file
## 通过标签跳过/激活某些任务 ```bash ```yaml tasks: - template src: template/activation.sh.j2 dest: /usr/bin/activation.sh tags: - flag_activation

多标签、多标签

```yaml tasks: - template src: template/activation.sh.j2 dest: /usr/bin/activation.sh tags: - flag_activation - flag_skip
```bash ```sh ansible-playbook previous-block.yml --skip-tags "flag_activation" # ansible-playbook previous-block.yml --skip-tags=flag_activation # ansible-playbook previous-block.yml --tags "flag_activation" # ansible-playbook previous-block.yml --tags=flag_activation

调试

调试剧本

```bash export ANSIBLE_STRATEGY=debug # revert it afterwards ( avoid "ERROR! Invalid play strategy specified: "): # export ANSIBLE_STRATEGY=linear

打印变量

```python task.args task.args['src'] vars()

更改变量

```python del(task.args['src']) task.args['src']="/new path to file"

设置变量

shell == ansible.builtin.shell 管理播放 ```bash

redo
continue
quit

```bash ```yaml - name: airflow setup for main (web server) and workers hosts: all tasks: - name: airflow hostname debug: msg="{{ lookup('vars', 'ansible_host') }}" - name: all variables from host debug: msg="{{ vars }}" when: run_mode == "debug"

调试命令

  • debug:
    msg: "print variable: {{ my_own_var }}"
  • shell: /usr/bin/uptime
    register: result

  • debug:
    var: result

环境变量 .bashrc

```sh - name: source bashrc sudo: no shell: . /home/username/.bashrc && [the actual command you want run]
## rsync 复制文件 ```bash
  • name: copy source code
    synchronize:
    src: '{{ item.src }}'
    dest: '{{ item.dest }}'
    delete: yes
    recursive: yes
    rsync_opts:
    - "--exclude=.git"
    - "-avz"
    - '-e ssh -i {{ key }} '
    with_items:
    • { src: '{{ path_to_repo }}/airflow-dag/airflow_shopify/', dest: '/home/ubuntu/airflow/airflow-dag/airflow_shopify/' }

EC2 管理 Airflow EC2

export PATH=$PATH:/home/ubuntu/.local/bin
nohup airflow webserver

调试模块

参数文件 (args.json)

```json { "ANSIBLE_MODULE_ARGS": { "task_parameter_1": "just a string", "task_parameter_2": 50 } }

执行文件

```bash python3 -m pdb library/oc_collaboration.py args.json

设置断点

```python import pdb ... pdb.set_trace()

运行到断点

```sh until 9999 next
## 内联调试模块、内联执行模块、即席模块检查 ```bash ```sh ansible localhost -m debug --args msg="my custom message" # collect facts ansible localhost -m setup
## 任务打印所有变量 ```bash ```yaml - name: "Ansible | List all known variables and facts" debug: var: hostvars[inventory_hostname]
## ansible-console ```bash ```sh ansible-console debug msg="my custom message" shell pwd
# 错误处理、try catch ## 当至少一个服务器抛出错误时停止步骤(剧本)的执行 ```bash ```yaml any_errors_fatal:true
## 不要为某个特定任务抛出错误 ```bash ```yaml - mail: to: 1@yahoo.com subject: info body: das ist information ignore_errors: yes
## 条件失败、根据条件失败、解析日志文件以查找错误 ```bash ```yaml - command: cat /var/log/server.log register: server_log_file failed_when : "'ERROR' in server_log_file.stdout"
# 模板、Jinja2 模板、管道、[Ansible 过滤器](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html) 默认值 ```bash

default path is {{ my_custom_path | default("/opt/program/script.sh") }}

转义特殊字符

{{ '{{ filename }}.log' }}

列表操作

{{ [1,2,3] | min }}
{{ [1,2,3] | max }}
{{ [1,2,3] | first }}
{{ [1,2,3] | last }}
{{ [1,2,3,2,3,] | unique }}
{{ [1,2,3] | union([1,2]) }}
{{ [1,2,3] | intersect([3]) }}
{{ 100 | random }}
{{ ["space", "separated", "value"] | join(" ") }}
{{'latest' if (my_own_value is defined) else 'local-build'}}

从路径获取文件名 (返回 'script.sh')

{{ "/etc/program/script.sh" | basename }}

复制文件并重命名、管道替换后缀

```yaml - name: Create DAG config template: src={{ item }} dest={{ airflow_dag_dir }}/config/{{ item | basename | regex_replace('\.j2','') }} with_fileglob: - ../airflow_dags/airflow_dags_gt/config/*.py.j2
## 从目标机器反向复制 ```bash
  • name: Fetch template
    fetch:
    src: '{{ only_file_name }}'
    dest: '{{ destination_folder }}'
    flat: yes
    tags: deploy

Jinja 指令

为了全局改善文件的缩进,在文件开头添加以下任意一行

```yaml #jinja2: lstrip_blocks: True #jinja2: trim_blocks:False #jinja2: lstrip_blocks: True, trim_blocks: True
为了仅改善块的缩进 ```bash ```j2 <div> {%+ if something %}<span>hello</span>{% endif %} </div>
条件示例 ```bash ```j2 {% if lookup('env','DEBUG') == "true" %} CMD ["java", "start-debug"] {% else %} CMD ["java", "start"] {% endif %}
### 循环指令、循环最后、循环最后 ```bash

[
{% for stream in deployment.streams %}
{
"stream": "{{ stream.stream_name }}",
"classN": "{{ stream.class_name }}",
"script": "{{ stream.script_name }}",
"sibFolders": [
{% for folder in stream.sub_folders %}
"{{ folder }}"{% if not loop.last %},{% endif %}
{% endfor %}
]
}{% if not loop.last %},{% endif %}
{% endfor %}
]

转义

单个符号

{{ '{{' }}

较大段落的代码

{% raw %}


    {% for item in seq %}
  • {{ item }}

  • {% endfor %}

{% endraw %}

带临时文件的模板

  • hosts: localhost
    gather_facts: no
    tasks:
    • tempfile:
      state: file
      suffix: config
      register: temp_config

    • template:
      src: templates/configfile.j2
      dest: "{{ temp_config.path }}"

模块

模块设置

还需要“通知” Ansible 关于模块,选择以下选项之一:

  • 将你的模块文件夹添加到环境变量 ANSIBLE_LIBRARY
  • 更新 $HOME/.ansible.cfg
    ```properties library=/path/to/module/library

模块文档

ansible-doc -t module {name of the module}

最小模块

from ansible.module_utils.basic import AnsibleModule
def main():
input_fields = {
"operation": {"required": True, "type": "str"},
"file": {"required": True, "type": "str"},
"timeout": {"required": False, "type": "int", "default": "120"}
}
module = AnsibleModule(argument_spec=input_fields)
operation = module.params["operation"]
file = module.params["file"]
timeout = module.params["timeout"]
# module.fail_json(msg="you must be logged in into OpenShift")
module.exit_json(changed=True, meta={operation: "create"})

插件

示例插件

{{ list_of_values | average }}

插件的 Python 代码

dev average(list):
return sum(list) / float(len(list))

class AverageModule(object):
def filters(self):
return {'average': average}

执行

export ANSIBLE_FILTER_PLUGINS=/full/path/to/folder/with/plugin
ansible-playbook playbook.yml

查找器

```sh # documentation ansible-doc -t lookup -l ansible-doc -t lookup csvfile
替换文件中具有特殊格式的值 ```bash ```python {{ lookup('csvfile', 'web_server file=credentials.csv delimiter=,') }} {{ lookup('ini', 'password section=web_server file=credentials.ini') }} {{ lookup('env','DESTINATION') }} {{ lookup('file','/tmp/version.txt') }}
查找器变量 ```bash

{{ hostvars[inventory_hostname]['somevar_' + other_var] }}

For ‘non host vars’ you can use the vars lookup plugin:
{{ lookup('vars', 'somevar_' + other_var) }}

```yaml - name: airflow setup for main (web server) and workers hosts: all tasks: - name: airflow hostname debug: msg="{{ lookup('vars', 'ansible_host') }}" - name: variable lookup debug: msg="lookup data {{ lookup('vars', 'ansible_host')+lookup('vars', 'ansible_host') }}" - name: read from ini, set variable set_fact: queues: "{{ lookup('ini', lookup('vars', 'ansible_host')+' section=queue file=airflow-'+lookup('vars', 'account_id')+'-workers.ini') }}" - name: airflow lookup debug: msg=" {{ '--queues '+lookup('vars', 'queues') if lookup('vars', 'queues') else '<default>' }}"
# 清单文件 --- ## 清单文件、带有变量的清单文件、[规则](https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html) ```bash

[remote_ssh]
172.28.128.3 ansible_connection=ssh ansible_port=22 ansible_user=tc ansible_password=tc

动态清单

Python inventory.py (带 'py' 扩展名) 代替 txt

import json
data = {"databases": {"hosts": ["host1", "host2"], "vars": {"ansible_ssh_host":"192.168.10.12", "ansible_ssh_pass":"Passw0rd"} }}
print(json.dumps(data))

还应该包含以下逻辑

inventory.py --list
inventory.py --host databases

准备好的脚本

具有变量的清单文件(Python Jinja 模板)

[remote_ssh]
172.28.128.3 ansible_connection=ssh ansible_port=22 ansible_user=tc ansible_password=tc http_port=8090

剧本使用:

'{{http_port}}'

带有清单文件的执行示例

没有清单文件对特定主机

```sh ansible-playbook playbook.yml -i 10.10.10.10
带有清单文件 ```bash ```sh ansible-playbook -i inventory.ini playbook.yml
仅对本地主机执行剧本的问题 ```bash ```text Note that the implicit localhost does not match 'all' ... skipping: no hosts matched

解决方案

```sh ansible-playbook --inventory="localhost," --connection=local --limit=localhost --skip-tag="python-script" playbook.yaml # example with external variables ansible-playbook --inventory="localhost," --connection=local --limit=localhost \ --extra-vars="oc_project=scenario-test mapr_stream_path=/mapr/prod.zurich/vantage/scenario-test" \ --tag="scenario-service" deploy-scenario-pipeline.yaml
解决方案2 ```bash ```sh #vim /etc/ansible/hosts localhost ansible_connection=local
# 策略 --- ```bash

strategy: linear

* 线性 (默认) * 每一步等待所有服务器完成 * 自由 * 对所有服务器独立执行 - 某些服务器可以比其他服务器显著提前完成安装 额外参数 - 指定同时执行的服务器数量(仅对默认策略有效) ```bash

serial: 3

```bash

serial: 20%

```bash

serial: [5,15,20]

默认值 "serial" 到配置文件 ansible.cfg

forks = 5

异步执行、不等待任务、命令执行

并非所有模块都支持此操作
以异步模式执行命令(初步估计为 120 秒),默认轮询结果为 10 秒

async: 120

以异步模式执行命令(初步估计为 120 秒),轮询结果为 60 秒

async: 120
poll: 60

执行命令并忘记,不等待执行

async: 120
poll: 0

以异步模式执行命令,
注册结果
在文件末尾检查结果

  • command: /opt/my_personal_long_run_command.sh
    async: 120
    poll: 0
    register: custom_command_result

  • name: check status result
    async_status: jid={{ custom_command_result.ansible_job_id }}
    register: command_result
    until: command_result.finished
    retries: 20

角色

初始化项目 ansible-galaxy、创建新角色、初始化角色

在你的项目文件夹 './roles' 中执行代码

ansible-galaxy init {project/role name}

结果:

./roles/{project/role name}
/defaults
/handlers
/meta
/tasks
/tests
/vars

插入代码

roles:

  • {project/role name}

所有创建项目的文件夹将应用于你的项目(tasks、vars、defaults)

  • 如果手动创建,则只有必要的文件夹可以被创建

ansible 搜索现有角色

ansible-galaxy search {project/role name}

ansible galaxy 导入现有角色

cd roles
ansible-galaxy import {name of the project/role}

插入代码

roles:

  • {project/role name}

所有导入项目的文件夹将应用于你的项目(tasks、vars、defaults)

从角色导入任务、角色任务、角色内的任务

```yaml - hosts: localhost # hosts: all # hosts: <name of section from inventory file> tasks: - name: first step include_role: name: mapr-kafka tasks_from: cluster-login
## 导出 创建/更新文件: ```bash

./roles/{project/role name}/meta/main.yml

本地运行本地启动剧本

```yaml - hosts: localhost tasks: - name: Ansible create file with content example copy: dest: "/tmp/remote_server.txt" content: | dog tiger

最小剧本

```yaml - hosts: localhost tasks: - name: Ansible create file with content example copy: dest: "/tmp/remote_server.txt" content: | {{ lookup('env','TEST_1') }} {{ lookup('env','TEST_2') }}
```bash ```sh ansible-playbook ansible-example.yml
## 执行角色、角色执行、本地启动角色、本地启动、角色本地执行 ```bash ```sh ansible localhost \ --extra-vars="deploy_application=1" \ --extra-vars=@group_vars/all/defaults/all.yaml \ --extra-vars=@group_vars/all/vars/all.yaml \ --extra-vars="mapr_stream_path={{ some_variable_from_previous_files }}/some-argument" \ -m include_role \ -a name="new_application/new_role"

其中 "include_role" 是运行模块(魔法词)
其中 "new_application/new_role" 是角色子文件夹
其中 @group_vars/all/default/all.yaml 是带有额外变量的 YAML 文件子路径

## 控制台输出与应用角色应显示如下 ```bash

TASK [{project/role name}: {task name}] ***********************************

例如 ```bash

TASK [java : install java with jdbc libraries] ***********************************

文件加密、保险库

ansible-vault encrypt inventory.txt
ansible-vault view inventory.txt
ansible-vault create inventory.txt

通过命令行请求密码 ```bash

ansible-playbook playbook.yml -i inventory.txt -ask-vault-pass

文件应包含密码 ```bash

ansible-playbook playbook.yml -i inventory.txt -vault-password-file ./file_with_pass.txt

脚本应返回密码 ```bash

ansible-playbook playbook.yml -i inventory.txt -vault-password-file ./file_with_pass.py

模块

所有模块列表
自定义模块测试平台
自定义模块创建文档

apt,Python 安装

  • name: example of apt install
    apt: name='{{ item }}' state=installed
    with_items:
    • python
    • python-setuptools
    • python-dev
    • build-essential
    • python-pip

service

  • name: example of start unix service
    service:
    name: mysql
    state: started
    enabled: yes

pip

  • name: manage python packages via pip
    pip:
    name: flask

包含变量导入变量

```json - name: External variables include_vars: roles/marker-table/defaults/main.yaml tags: deploy
### echo 添加标志用于 ```ansible``` 或 ```ansible-playbook```:-vvv(3) -vv (2) 或 -v (1) ```bash
  • debug:
    msg: ">>> {{ data_portal_deploy_folder }}/data-portal.jar"
    var: src
    verbosity: 2

copy

  • name: Ensure MOTD file is in place
    copy:
    src: files/motd
    dest: /etc/motd
    owner: root
    group: root
    mode: 0644

  • name: Ensure MOTD file is in place
    copy:
    content: "Welcome to this system."
    dest: /etc/motd
    owner: root
    group: root
    mode: 0644

template

```json - name: Ensure MOTD file is in place template: src: templates/motd.j2 dest: /etc/motd owner: root group: root mode: 0644
### [user](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html) ```bash ```json - name: Ensure user1 exists user: name: user1 group: users groups: wheel uid: 2001 password: "{{ 'mypassword' | password_hash('sha512') }}" state: present
### [package](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html) ```bash ```json - name: Ensure Apache package is installed package: name: httpd state: present
### [firewalld](https://docs.ansible.com/ansible/latest/collections/ansible/posix/firewalld_module.html) ```bash ```json - name: Ensure port 80 (http) is open firewalld: service: http state: enabled permanent: yes immediate: yes
### [file](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html) ```bash ```json - name: Ensure directory /app exists file: path: /app state: directory owner: user1 group: docker mode: 0770
### [lineinfile](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html) ```bash ```json - name: Ensure host my-own-host in hosts file lineinfile: path: /etc/hosts line: 192.168.0.36 my-own-host state: present - name: Ensure root cannot login via ssh lineinfile: path: /etc/ssh/sshd_config regexp: '^PermitRootLogin' line: PermitRootLogin no state: present
### [unarchive](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unarchive_module.html) ```bash ```json - name: Extract content from archive unarchive: src: /home/user1/Download/app.tar.gz dest: /app remote_src: yes
### [command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) ```bash ```json - name: Run bash script command: "/home/user1/install-package.sh"
### 待办事项 * 系统 * 命令 * 数据库 * 云 * Windows # [ansible awx](https://github.com/ansible/awx) # 问题 ## 指纹检查 ```bash

fatal: [172.28.128.4]: FAILED! => {"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."}

解决方法 ```bash

export ANSIBLE_HOST_KEY_CHECKING=False
ansible-playbook -i inventory.ini playbook-directory.yml

声明:
本文件灏天文库团队进行了翻译。尽管我们力求准确,但请注意,翻译可能包含错误或不准确之处。原文档以其原始语言为准。我们不对因使用此翻译而产生的任何误解或误译负责。


作者与出处
原作者: Tikam02
来源:Tikam02
许可证:MIT
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: Tikam02 转发
评论区 (0)
U