ansible 學(xué)習(xí)筆記

是什么

自動化工具。用來自動化安裝,部署,測試。

為什么

讓人專注于做什么,而不是怎么做。(不太關(guān)心怎么連接,連接多少太機(jī)器,怎么驗證)

類似的工具還有puppet。ansible 最大的優(yōu)勢就是不用安裝客戶端,只要ssh 能夠連接進(jìn)去,就能工作了。

安裝

簡單的方式

For RHEL

$ yum install ansible

For CentOS

 $ yum install -y epel-release 
 $ yum install -y ansible

For ubuntu

# apt-get update
# apt-get install -y software-properties-common
# apt-add-repository ppa:ansible/ansible
# apt-get update
# apt-get install -y ansible

通過pip安裝 [推薦]

這種方式可以獲取ansible 最新的版本。

For CentOS

$ sudo yum -y install https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum -y install python36u
$ sudo python3.6 -m ensurepip
$ pip3 install ansible

For ubuntu

# apt update
# apt install python3-pip
# pip3 install ansible

配置文件

Changes can be made and used in a configuration file which will be searched for in the following order:

  • ANSIBLE_CONFIG (environment variable if set)
  • ansible.cfg (in the current directory)
  • ~/.ansible.cfg (in the home directory)
  • /etc/ansible/ansible.cfg

Ansible will process the above list and use the first file found, all others are ignored.

使用(Ad-hoc)

$ ansible web –m ping
$ ansible web -b –m yum –a "name=httpd state=present"
$ ansible web -m command -a 'echo "hello world"'

使用(playbook)

Playbook (who, where, what)

File test.yml

- hosts: localhost
  tasks:
    - name: check login user
      shell: whoami > /tmp/login_user

運行

$ ansible-playbook test.yml

變量

命令行方式

key=value format:

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
ansible localhost -m package -a "name=git state=present" -b -e 'ansible_python_interpreter=/usr/bin/python'

JSON string format:

ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
ansible-playbook arcade.yml -e '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'

YAML string format:

ansible-playbook release.yml --extra-vars '
version: "1.23.45"
other_variable: foo'

ansible-playbook arcade.yml --extra-vars '
pacman: mrs
ghosts:
 - inky
 - pinky
 - clyde
 - sue'

vars from a JSON or YAML file:

ansible-playbook release.yml --extra-vars "@some_file.json"

其它參數(shù):

Specifying a user:

ansible-playbook playbooks/atmo_playbook.yml --user atmouser

Using a specific SSH private key:

ansible -m ping hosts --private-key=~/.ssh/keys/id_rsa -u centos

Inventory vars

[ambari-nodes]
my-vm-hdp-1
my-vm-hdp-2

[ambari-nodes:vars]
ansible_ssh_user=dcpuser
ansible_ssh_private_key_file=group_vars/iot_rsa

Play vars

In a playbook, it’s possible to define variables directly inline like so:

- hosts: webservers
  vars:
    http_port: 80

Role vars

---
- hosts: webservers
  roles:
    - role: foo
      vars:
        message: "first"
    - { role: foo, vars: { message: "second" } }

Jinja2

For instance, in a simple template, you can do something like:

My amp goes to {{ max_amp_value }}

This is also valid directly in playbooks, and you’ll occasionally want to do things like:

template: src=foo.cfg.j2 dest={{ remote_install_path }}/foo.cfg

注冊變量

- hosts: web_servers
  tasks:
     - shell: /usr/bin/foo
       register: foo_result
       ignore_errors: True

     - shell: /usr/bin/bar
       when: foo_result.rc == 5

動態(tài)輸入變量

- hosts: ambari-server
  vars_prompt:
    - name: "ambari"
      prompt: "Enter password for [admin]"
      confirm: yes

內(nèi)置變量

Special Variable

變量名稱 說明 使用
hostvars 包含主機(jī)得fcats信息 {{ hostvars['db.example.com'].ansible_eth0.ipv4.address }}
inventory_hostname 當(dāng)前主機(jī)的名稱 {{ hostvars[inventory_hostname] }} , {{ inventory_hostname }}
group_names 當(dāng)前主機(jī)所在組的主機(jī)列表 {% if 'webserver' in group_names %}# some part of a configuration file that only applies to webservers{% endif %}
groups 包含設(shè)備清單組內(nèi)的所有主機(jī) {% for host in groups[‘db_servers’] %} {{ host }}{% endfor %}
play_hosts 在當(dāng)前playbook中處于活動狀態(tài)的主機(jī)名列表 {{play_hosts}}
playbook_dir The path to the directory of the playbook that was passed to the ansible-playbook command line. {{ playbook_dir }}
role_path The path to the dir of the currently running role {{ role_path }}

獲取主機(jī)IP

- hosts: localhost
  connection: local
  tasks:
    - debug: var=ansible_all_ipv4_addresses
    - debug: var=ansible_default_ipv4.address
    - debug: var=ansible_eth0.ipv4.address

環(huán)境變量

You can use the environment keyword at the play, block, or task level to set an environment variable for an action on a remote host.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_environment.html

- hosts: dev
  tasks:
    - name: Echo my_env_var
      shell: "echo $MY_ENV_VARIABLE"
      environment:
        MY_ENV_VARIABLE: whatever_value

    - name: Echo my_env_var again
      shell: "echo $MY_ENV_VARIABLE"

變量優(yōu)先級

官網(wǎng)

Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables):

越靠后,優(yōu)先級越高

  1. command line values (for example, -u my_user, these are not variables)
  2. role defaults (defined in role/defaults/main.yml) 1
  3. inventory file or script group vars 2
  4. inventory group_vars/all 3
  5. playbook group_vars/all 3
  6. inventory group_vars/* 3
  7. playbook group_vars/* 3
  8. inventory file or script host vars 2
  9. inventory host_vars/* 3
  10. playbook host_vars/* 3
  11. host facts / cached set_facts 4
  12. play vars
  13. play vars_prompt
  14. play vars_files
  15. role vars (defined in role/vars/main.yml)
  16. block vars (only for tasks in block)
  17. task vars (only for the task)
  18. include_vars
  19. set_facts / registered vars
  20. role (and include_role) params
  21. include params
  22. extra vars (for example, -e "user=my_user")(always win precedence)

本地運行

delegate_to

- name: add back to load balancer pool
  command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
  delegate_to: 127.0.0.1

local_action

  - name: recursively copy files from management server to target
    local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/

connection

ansible-playbook playbook.yml --connection=local
...

- command: foo
  connection: local

tags

ansible-playbook offers five tag-related command-line options:

  • --tags all - run all tasks, ignore tags (default behavior)
  • --tags [tag1, tag2] - run only tasks with the tags tag1 and tag2
  • --skip-tags [tag3, tag4] - run all tasks except those with the tags tag3 and tag4
  • --tags tagged - run only tasks with at least one tag
  • --tags untagged - run only tasks with no tags

Adding tags to individual tasks

tasks:
- name: Install the servers
  ansible.builtin.yum:
    name:
    - httpd
    - memcached
    state: present
  tags:
  - packages
  - webservers

- name: Configure the service
  ansible.builtin.template:
    src: templates/src.j2
    dest: /etc/foo.conf
  tags:
  - configuration

Adding tags to plays

- hosts: all
  tags: ntp
  tasks:
  - name: Install ntp
    ansible.builtin.yum:
      name: ntp
      state: present

Adding tags to blocks

特殊替換

想把字符串 abc 替換成 {{ abc }} 默認(rèn)辦法做不到,比如:

 - name: change line - fail
   lineinfile:
     path: a.txt
     regexp: 'abc'
     line: '{{ abc }}'

它會認(rèn)為要替換一個變量,而不是字符串。

可以使用 {% raw %} ... {% endraw %} tags 來解決問題。

- name: change line - succeed
  lineinfile:
    path: a.txt
    regexp: 'abc'
    line: '{% raw %} {{ abc }} {% endraw %}'

Tips

Retrieve public IP

方法一

- name: Get my public IP from ipify.org
  ipify_facts:
- debug: var=ipify_public_ip

方法二

use uri module:

- name: Find my public ip
  uri: 
    url: http://ifconfig.me/ip
    return_content: yes
  register: ip_response

Your IP will be in ip_response.content

refs: https://stackoverflow.com/questions/39819378/ansible-get-current-target-hosts-ip-address

跳板機(jī)設(shè)置

方法一:直接寫入inventory

核心參數(shù): ansible_ssh_common_args options

more ansible_*_args

Ansible 利用了 OpenSSH 的ProxyCommand來實現(xiàn)跳過Bastion(proxy/ jump)的功能。

用分組的方式

# file: tmp_hosts
[gatewayd]
hdp-slave-0
hdp-slave-1
hdp-master-0
hdp-master-1
hdp-master-2

[gatewayd:vars]
ansible_ssh_common_args=' -o ProxyCommand="ssh -W %h:%p -i /home/edaizen/.ssh/docomo-devops -o StrictHostKeyChecking=no devops@20.82.155.204"'

[all:vars]
ansible_ssh_private_key_file='/home/edaizen/.ssh/docomo-hadoop'
ansible_user=centos

方法二:靈活性更強(qiáng)的配置方式

這是官方FAQ的例子。

定義一個組都要通過proxy 連接(相當(dāng)于把上面例子中的 [gatewayd:vars] 部分單獨拿出來)

# file: group_vars/gatewayed.yml
ansible_ssh_common_args: ' -o ProxyCommand="ssh -i group_vars/eea_rsa -W %h:%p -q redhat@40.83.74.108"'

定義這個組里有哪些機(jī)器

# file: hosts
[gatewayed]
foo ansible_host=192.168.3.5
small-test-01

方法三:在命令行中寫入?yún)?shù)

參數(shù):--ssh-common-args
e.g.

ansible-playbook  --ssh-common-args='-o ProxyCommand="ssh  -W %h:%p -q ec2-user@1.2.3.4"' site.yml

優(yōu)點:不用關(guān)心配置文件關(guān)于bastion部分。
缺點:這么長的參數(shù)記不住,適合生成腳本再運行。

使用(galaxy)

通過galaxy 獲取社區(qū)的ansible role,直接調(diào)用,不關(guān)心具體怎么實現(xiàn)的。

https://galaxy.ansible.com/

比如要對VM 加固,直接用社區(qū)的代碼

$ ansible-galaxy install git+https://github.com/openstack/ansible-hardening
- extracting ansible-hardening to /home/edaizen/.ansible/roles/ansible-hardening
- ansible-hardening was installed successfully

檢查自己安裝了什么

$ ansible-galaxy list
# /home/edaizen/.ansible/roles
- ansible-hardening, (unknown version)

要調(diào)用這個role,跟其它playbook 一樣

# test.yml
- name: Harden all systems
  hosts: all
  become: yes
  vars:
    security_enable_firewalld: no
    security_rhel7_initialize_aide: no
  roles:
    - ansible-hardening
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容