Memo/Ansible

https://dexlab.net:443/pukiwiki/index.php?Memo/Ansible
 

Ansible

  • http://www.ansible.com/home ¸ø¼°
    • Installation — Ansible Documentation ¥¤¥ó¥¹¥È¡¼¥ëÊýË¡
    • Best Practices Ansible Documentation ¥Ù¥¹¥È¥×¥é¥¯¥Æ¥£¥¹
    • Ansible Porting Guides — Ansible Documentation ¥Ð¡¼¥¸¥ç¥óÊѹ¹»þ¤Î»ÅÍÍÊѹ¹ÅÀ
    • pythonÀ½¡¢¥µ¡¼¥Ð¹½À®´ÉÍý¥½¥Õ¥È¡£yaml¤Ë½ñ¤¯¥¿¥¤¥×
    • ¥¯¥é¥¤¥¢¥ó¥È¤ËSSH¤Ç¥í¥°¥¤¥ó¤Ç¤­¤ë´Ä¶­¤Ç¤¢¤ì¤Ð»È¤¨¤ë
    • AWS EC2¥¤¥ó¥¹¥¿¥ó¥¹µ¯Æ°¤â¤Ç¤­¤ë
    • ¥¯¥é¥¤¥¢¥ó¥È¦¤Îưºî¤Ï"module"¤È¤·¤ÆÄêµÁ¡£»ØÄꤵ¤ì¤¿Æþ½ÐÎÏ·Á¼°¤Ç¤¢¤ì¤Ðpython°Ê³°¤Ç¤â½ñ¤±¤ë
    • ¤É¤Î¥µ¡¼¥Ð¤Ëmodule¤ò»È¤¦¤«¤Ê¤É¤Îưºî¤ò¤Þ¤È¤á¤¿¤â¤Î¤ò "play book" ¤ÈÄêµÁ¡£yaml¤Ç½ñ¤¯
  • ½ñÀÒ

synchronize: rsync¤Ç¥Õ¥¡¥¤¥ë¥³¥Ô¡¼

  • ansible.posix.synchronize – A wrapper around rsync to make common tasks in your playbooks quick and easy — Ansible Documentation
    • rsync¤ò»È¤¦¤¿¤á¡¢copy module¤Ë³Ó¤Ù¤ÆÁᤤ¡£
    • ¸µ¥Õ¥¡¥¤¥ë¤Îuser, group, mode, time¤¬¥ª¥×¥·¥ç¥ó¤Ë¤è¤Ã¤ÆÊѤï¤ë¤Î¤ÇÃí°Õ¡£
    • Î㤨¤ÐmacOS¾å¤Ç°À­¤ò°Ý»ý¤·¤Æ¼Â¹Ô¤¹¤ë¤È¡¢macOS¤Î¼Â¹Ôuser, group, mode¤¬linux¤Ë¥³¥Ô¡¼¤µ¤ì¤ë¤¿¤áÊѤˤʤ롣
    • ansible 2.3¤Îdoc¤Ç¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç°À­¤Ï°Ý»ý¤·¤Ê¤¤¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤¬¡¢¼ÂºÝ¤Ï°À­¤¬¥³¥Ô¡¼¤µ¤ì¤ë¤¿¤áÃí°Õ¡£
    • ¡Öchecksum: yes¡×¤òÉÕ¤±¤ë¤Èº¹Ê¬¤¬¤Ç¤Ê¤¯¤Ê¤ë¡£

copy module¤Îcontent¤Ç²þ¹Ô¤¬¾Ã¤¨¤ë¡£

  • ansible 2.9.6
  • playbook.test.yml
    - hosts: localhost
      connection: local
      vars:
        var1:
        - key: key1
          val: val1
        var2: "{{ var1 | to_nice_json(indent=2) }}"
      tasks:
      - copy:
          content: "{{ var1 | to_nice_json(indent=2) }}"
          dest: /tmp/example1.json
      - copy:
          content: "{{ var2 }}"
          dest: /tmp/example2.json
  • ¼Â¹Ô·ë²Ì
    cat /tmp/example1.json
    [
      {
        "key": "key1",
        "val": "val1"
      }
    ]
    
    cat /tmp/example2.json
    [{"key": "key1", "val": "val1"}]

¥³¥Þ¥ó¥É¤Î¸ºß¥Á¥§¥Ã¥¯

  • which¤Ï¥³¥Þ¥ó¥É¡¢type¤ÏbashÁȤ߹þ¤ß¥³¥Þ¥ó¥É¤Ê¤Î¤Ç¡¢´Ä¶­¤Ë°Í¸¤·¤Ê¤¤ÊýË¡¤È¤·¤Æ¤Ïtype¤¬Îɤµ¤½¤¦
      - name: check if java is exists
        shell: type java
        register: result
        changed_when: no
        ignore_errors: yes
    
      - debug: msg="command is not exists"
        when: result is failed

¥Í¥Ã¥È¥ï¡¼¥¯µ¡´ï¤Î´ÉÍý

  • Network modules — Ansible Documentation
    • Cisco(iOS), F5(bigip)Åù¤Î¥á¥¸¥ã¡¼¤Êµ¡´ï¤ÏÀìÍѤÎmodule¤¬¤¢¤ê¡¢¤è¤ê´Êñ¤Ë»È¤¨¤ë¡£
    • ¥Þ¥¤¥Ê¡¼¤Êµ¡´ï¤Ïssh/telnet moduleÅù¤Ç°·¤¦»ö¤â¤Ç¤­¤ë¡£

terraform.tfstate¤ÎÃͤò»²¾È


defaultÃͤòÄêµÁ¤¹¤ë

  • ¥á¥¸¥ã¡¼¥Ð¡¼¥¸¥ç¥óËè¤Ë¥Ç¥Õ¥©¥ë¥ÈÃͤ¬Â礭¤¯ÊѤï¤ë¾ì¹ç¡£
  • group_vars/°Ê²¼¤ÇÃͤò¥³¥ó¥È¥í¡¼¥ë¤·¤¿¤¤¡£
  • "{{ var1 | default(omit) }}" ¤Ç¤Ï¡¢var1¤¬Ì¤ÄêµÄ¤Î¾ì¹ç¡¢²¿¤â¤·¤Ê¤¤¡£
  • group_vars/example.yml
    example_major_version: 1
    example_param01: example-value01
  • roles/example/defaults/main.yml
    example_major_version: 1
    # example_param01: # ¥³¥á¥ó¥È¥¢¥¦¥È¤·¤Ê¤¤¤È¡¢templateÆâ¤Çvars/°Ê²¼¤ÎÃͤ¬»È¤ï¤ì¤Ê¤¤
  • roles/example/tasks/main.yml
    - include_vars: "major_version1{{ example_major_version }}.yml"
  • roles/puppet/vars/major_version1.yml
    example_default_param01: 1
  • roles/puppet/templates/example.conf
    param01 = "{{ example_param01 | default(example_default_param01) }}"

¥È¥ì¡¼¥Ë¥ó¥°/¥µ¥ó¥×¥ë


¥Ç¥Õ¥©¥ë¥È¤Î¸¡º÷¥Ñ¥¹

  • ansible 2.7.6¤Ç¸¡¾Ú
  • °Ê²¼¤ÎÀßÄê¤Ç¤Ï¡¢roles¤ÎÊý¤¬»È¤ï¤ì¤Æ¤·¤Þ¤¦¡£²ò·èÊýË¡¤Ï¤É¤Á¤é¤«¤Î¥Ñ¥¹¤ä¥Õ¥¡¥¤¥ë̾¤òÊѤ¨¤ë¡£
    # ./foo.txt ¤òroles¤Îtemplate¤Ë¾å½ñ¤­¤·¤¿¤¤¡£
    
    # group_vars/all.yaml
    file1_path: ./foo.txt
    
    # roles/example/defaults/main.yml
    file1_path: foo.txt

vars_prompt, vars_files, --extra-vars ¤ÇÇÛÎóÅù¤òÅϤ¹

  • playbook.yml
    - hosts: localhost
      connection: local
      become: no
      gather_facts: no
      tasks:
      - debug: var=test_list
  • ÇÛÎó¤È¤·¤Ætest_list: ["a", "b", "c"] ¤òÅϤ¹
    ansible-playbook playbook.yml -e '{"test_list": ["a","b","c"]}'
    ...
    TASK [debug] ****************************************************************************************************************************************************************************
    ok: [localhost] => {
        "test_list": [
            "a", 
            "b", 
            "c"
        ]
    }

¹½Ê¸¥Á¥§¥Ã¥¯

  • playbook: playbook.yml¤Î¤ß¤Î¹½Ê¸¥Á¥§¥Ã¥¯¤ò¹Ô¤¦¡£group_vars/¤ähost_vars/¤Ë¹½Ê¸¥¨¥é¡¼¤¬¤¢¤Ã¤Æ¤â¥Á¥§¥Ã¥¯¤·¤Ê¤¤¡£
    ansible-playbook playbook.yml --syntax-check

patch: ¥Ñ¥Ã¥Á¤òŬÍѤ¹¤ë

  • patch¥Õ¥¡¥¤¥ë¤ÎºîÀ®
    diff -up <file.org> <file> > v0.1.patch
    
    # git diff¤Ç¤âok
    git diff origin/master > master-v0.1.patch

WSL´Ä¶­

  • DrvFs¾å¤Ë control_path¤òÀßÄꤹ¤ë¤È¡Ömuxclient: master hello exchange failed¡×¤Ç¼ºÇÔ¤¹¤ë¡£VolFs¾å¤Î¥Ñ¥¹¤ò»È¤¦¡£

parse_cli/parse_cli_textfsm: ¥³¥Þ¥ó¥É¤Î·ë²Ì¤ò²òÀϤ·¤ÆÊÑ¿ô¤Ë¼è¤ê¹þ¤à

JSON¤Ç½ÐÎϤǤ­¤Ê¤¤¥³¥Þ¥ó¥É¤Î·ë²Ì¤ò²òÀϤ·¤Æ¡¢ÊÑ¿ô¤ËÊÑ´¹¤·¤Æ¤¯¤ì¤ë¡£
²òÀÏÍѥƥó¥×¥ì¡¼¥È¤òÍѰդ¹¤ë¤¬¡¢¥á¥¸¥ã¡¼¤Êµ¡´ïÍѤΥƥó¥×¥ì¡¼¥È¤Ï´û¤Ë¤¢¤ë¡£


local¼Â¹Ô»þ¤Îlocal user¤Î¼èÆÀ

  • fact¤Ç¼èÆÀ¤Ç¤­¤ëÃͤËlocal user¤Ï̵¤·
    ansible -i hosts.ini -m setup <remote-host>
    ...
           "ansible_env": {
    ...
                "USER": "/home/remote-user01", 
    ...
            "ansible_user_id": "remote-user01", 
    ...
            "ansible_user_uid": 1000,
  • env¤«¤éUSER¤ò¼èÆÀ¤·¡¢1²ó¤À¤±tmp¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¡£¡Örun_once: true¡×¤ÇÊ£¿ôÂæ¤Î¥Û¥¹¥È¤Ë¼Â¹Ô¤·¤¿¾ì¹ç¤Ç¤â¡¢1²ó¤À¤±¼Â¹Ô¤µ¤ì¤ë¡£
    - set_fact:
        local_user_id: "{{ lookup('env','USER') }}"
    
    - name: create tmp dir
      local_action: file path="/tmp/ansible-tmp" state=directory owner="{{ local_user_id }}"
      become: false
      run_once: true
  • ¡Öwhoami¡×¥³¥Þ¥ó¥É¤Çuser¼èÆÀ
  • ¡Öid¡×¥³¥Þ¥ó¥É¤Çuid,gid,groupsÅù¼èÆÀ¤Ç¤­¤ë

package: OSËè¤Î¥Ñ¥Ã¥±¡¼¥¸´ÉÍý¤ò°ì¸µ²½


run_once: ¥Û¥¹¥È¤¬Ê£¿ôÂæ¤¢¤Ã¤Æ¤â1²ó¤·¤«¼Â¹Ô¤·¤Ê¤¤


ini_file: ini¥Õ¥¡¥¤¥ë¤Î½ñ¤­´¹¤¨


Terraform¤È¤ÎÏ¢·È

Memo/Terraform¤ÇAWS EC2¤òµ¯Æ°¤·¤Æ¡¢ansible-playbook¤ò¼Â¹Ô¤·¤¿¤¤»þ¤Ê¤É¡£


apt: Debian/UbuntuÅù¤Î¥Ñ¥Ã¥±¡¼¥¸´ÉÍý

  • apt - Manages apt-packages — Ansible Documentation
  • ¿·¤·¤¤repo¤òÄɲä·¤¿¤ê¡¢¸½ºß¤Î¥Ð¡¼¥¸¥ç¥ó¤¬¸Å¤¤»þ¤Ë¥­¥ã¥Ã¥·¥å¤Î¹¹¿·¤¬É¬Íס£¤¿¤À¥ë¡¼¥×¤ÇËè²ó¹¹¿·¤ÏÃÙ¤¯¤Ê¤ë¤Î¤ÇÍ­¸ú´ü¸Â¤òÄɲÃ
  apt:
    name: "{{ apt_packages  }}"
    state: "{{ item.state }}"
    update_cache: yes
    cache_valid_time: 3600

vars_prompt¤Ç¥«¥ó¥Þ¶èÀÚ¤êʸ»úÎó¤òÇÛÎó¤ËŸ³«¤¹¤ë

  • playbook: ¥«¥ó¥ÞÁ°¸å¤Ë¶õÇò¤¬ÆþÎϤµ¤ì¤Æ¤âÎɤ¤¤è¤¦¤Ë¡¢trim¤ò»È¤¦
    - hosts:
      - localhost
      become: False
      gather_facts: False
      connection: local
      vars_prompt:
      - name: "csv_str"
        prompt: "Please enter csv"
        private: no
      tasks:
      - set_fact:
          csv_array: "{{ csv_str.split(',')  }}"
      - debug: msg="{{ item | trim }}"
        with_items: "{{ csv_array }}"
  • ¼Â¹Ô·ë²Ì: ansible 2.4.2.0
    ansible-playbook playbook.yml
    Please enter csv: aaa, bbb 
    
    ok: [localhost] => (item=aaa) => {
        "changed": false, 
        "item": "aaa", 
        "msg": "aaa"
    }
    
    ok: [localhost] => (item= bbb ) => {
        "changed": false, 
        "item": " bbb ", 
        "msg": "bbb"
    }

include¤ÎÂå¤ï¤ê¤Ëimport_tasks, include_tasks¤ò»È¤¦

  • ansible 2.4.2.0¤Çinclude¤ò»È¤Ã¤¿¾ì¹ç¤Î·Ù¹ð¡£ÀÅŪ¤ÈưŪ¤ÇÌÀ¼¨Åª¤Ëʬ¤±¤Æµ­½Ò¤¹¤ë¤è¤¦¤Ë¡£
[DEPRECATION WARNING]: The use of 'include' for tasks has been deprecated. Use 'import_tasks' for static inclusions or 'include_tasks' for 
dynamic inclusions. This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False 
in ansible.cfg.

Including and Importing — Ansible Documentation

  • import_tasks
    • ÀÅŪ¤Êinclude¡£¼Â¹ÔÁ°¤Ëɾ²Á¤µ¤ì¤ë¡£
  • include_tasks
    • ưŪ¤Êinclude¡£¼Â¹Ô»þ¤Ëɾ²Á¤µ¤ì¤ë
    • include¤Î¥Õ¥¡¥¤¥ë̾¤ËÊÑ¿ô¤ò´Þ¤à¾ì¹ç
    • include»þ¤ËÊÑ¿ô¤òÍѤ¤¤Æloop¤¹¤ë¾ì¹ç
    • handler¤Ë¤Ïnotify¤Ç¤­¤Ê¤¤
    • list-tags ¤Ç½ÐÎϤµ¤ì¤Ê¤¤
    • list-tasks ¤Ç½ÐÎϤµ¤ì¤Ê¤¤

pause: »ØÄꤷ¤¿ÉÃ/ʬ¤À¤±ÂԤġ¢ÃæÃǤä³¹Ô¤òÁªÂò

  • playbook.yml
    - hosts: all
      gather_facts: false
      become: no
      vars:
      - pause_seconds: 0
      tasks:
      - ping:
      - pause:
          seconds: "{{ pause_seconds }}"
        when: pause_seconds|int > 0
  • ¼Â¹Ô·ë²Ì: 60ÉÃÂÔµ¡¤¹¤ë
    time ansible-playbook -i test/hosts.ini -l localhost playbook.ping.yml -e 'pause_seconds=60'
    ...
    TASK [ping] ***************************************************************************************************************************************
    ok: [localhost]
    
    TASK [pause] **************************************************************************************************************************************
    Pausing for 60 seconds
    (ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)
    ok: [localhost]
    PLAY RECAP ****************************************************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0
    
    real    1m7.318s
    user    0m4.149s
    sys     0m0.548s

yum_repository: yum¥ê¥Ý¥¸¥È¥ê¤ÎÄɲÃ/ºï½ü

- name: Remove repository from a specific repo file
  yum_repository:
    name: epel
    file: external_repos
    state: absent

include_role: roleÆâ¤ÎÊÌtask¤òload¤¹¤ë

tasks/main.yml ¤È¤ÏÊ̤Îyaml¤òload¤Ç¤­¤ë¡£ tasks¤òʬ³ä¤·¤Æ¡¢ÉáÃʤϼ¹Ԥµ¤ì¤Ê¤¤½èÍý¤òʬ¤±¤é¤ì¤ë¡£


¥Æ¥­¥¹¥È¤ÎÃÖ´¹

  • remove_hostÊÑ¿ô¤Ë¥Þ¥Ã¥Á¤·¤¿¹Ô¤òºï½ü
      - name: Remove the IP address
        replace:
          path: "{{ item }}"
          regexp: '^.*{{ remove_host }}.*[\r\n]+'
        with_items:
        - /etc/hosts.deny

ansible-container: docker image¤ÎºîÀ®


docker¤ÎÁàºî

  • Docker - Cloud Modules
    • ¥ê¥â¡¼¥È¥Û¥¹¥È¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤¿docker¤ò°·¤¦¡£¥³¥ó¥Æ¥ÊÆâ¤Î¹½ÃÛ¤ÏÊÌ¡£
    • ¥ê¥â¡¼¥È¥Û¥¹¥È¾å¤Î½àÈ÷
      sudo pip install docker-py docker-compose
  • ²ÝÂê
    • remote host¾å¤Îdocker¥³¥ó¥Æ¥ÊÆâ¤Ëansible role¤òŬÍѤ·¤¿¤¤¤¬¥³¥ó¥Æ¥Ê¤ÎÀܳ¤Ë¼ºÇÔ¤¹¤ë¡£¡Öconnection: docker¡×¤À¤±¤Ç¤Ï¡Ödocker command not found in PATH¡×¤¬½Ð¤ë¤Î¤Ç¡¢localhost¤Îdocker¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤è¤¦¤È¤·¤Æ¤¤¤ë

playbookÃæ¤ËºÆµ¯Æ°

¥µ¥ó¥×¥ë¥³¡¼¥É¤Ï¤¤¤¯¤Ä¤â¤¢¤ë¤¬¡¢¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤

  • Reboot and Wait for &#xB7; Issue #14413 &#xB7; ansible/ansible &#xB7; GitHub
    • ansible 2.3.1.0 + Raspbian 8¤Ç¤Ï¡¢¡Öwait for SSH port down¡×¤Ç¥¿¥¤¥à¥¢¥¦¥È¤·¼ºÇÔ¡£
    • ¡Öport down¡×¤ò¥³¥á¥ó¥È¥¢¥¦¥È¤·¤Æ¤â¡¢¡Öport up¡×¤ÇÀ®¸ù¤Ë¤Ê¤ê¡¢ping¤Ç¼ºÇÔ¤¹¤ë¡£state¤¬¤¦¤Þ¤¯µ¡Ç½¤·¤Æ¤¤¤Ê¤¤²ÄǽÀ­
  • playbook.reboot.yml
hosts: all
  become: True
  gather_facts: True
  tasks:
    - name: debug
      debug:
        msg: "ansible_host={{ ansible_host }}"
    - name: test connection (before reboot)
      ping:
    - name: reboot
      shell: sleep 2 && shutdown -r now "Ansible reboot"
      async: 1
      poll: 0
      ignore_errors: "{{ ansible_check_mode }}"
    - name: wait for SSH port down
      wait_for:
        host: "{{ ansible_host }}"
        port: 22
        state: stopped
        delay: 1
        timeout: 60
      delegate_to: 127.0.0.1
      become: no
    - name: wait for SSH port up
      wait_for:
        host: "{{ ansible_host }}"
        port: 22
        state: started
        delay: 30
        timeout: 300
      delegate_to: 127.0.0.1
      become: no
    - name: test connection (after reboot)
      ping:

block: Ê£¿ô¤Î¥¿¥¹¥¯¤Î¥Ö¥í¥Ã¥¯²½

  • Blocks ¡½ Ansible Documentation
    • ansible 2.0°Ê¹ß¤Ç»È¤¨¤ë
    • Ê£¿ô¤Î¥¿¥¹¥¯¤ËƱ¤¸tag¤òÉÕ¤±¤ë¡¢when¤Ç¤Îʬ´ô¡¢¥¨¥é¡¼¥Ï¥ó¥É¥ê¥ó¥°(Îã³°½èÍý)Åù¤Ë»È¤¨¤ë

fact¤ÎºÆ¼èÆÀ

¡Ösetup¡×¤ÎºÆ¼Â¹Ô¤ÇÎɤ¤ ưŪ¤ËNIC¤òÄɲä·¤¿¸å¤Ë¡¢fact¤Ë¤âÈ¿±Ç¤µ¤»¤¿¤¤¾ì¹ç¤Ê¤É¡£

  • CentOS 7
      tasks:
        - debug: var=ansible_interfaces
        - yum: name=docker
        - setup:
        - debug: var=ansible_interfaces

group_by: ưŪ¤Ëgroup¤òÊѹ¹¤¹¤ë

Î㤨¤Ð¡Öconnection: local¡×¤À¤¬¡¢Ê£¿ô¤Î¡Ögroup_vars/env.yml¡×¤ò´Ä¶­Ëè¤ËÀÚ¤êÂØ¤¨¤¿¤¤»þ¤Ë»È¤¨¤ë¡£
»ØÄꤷ¤¿group_varsÆâ¤ÎÊÑ¿ô¤¬»²¾È¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë¡£

  vars_prompt:
    - name: "inventory_group"
      prompt: "Please enter inventory_group"
      private: no

  tasks:
    - group_by: key="{{ inventory_group }}"
      changed_when: False

assemble: Ê£¿ô¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤«¤é°ì¤Ä¤ÎÀßÄê¤òºî¤ë

assemble - Assembles a configuration file from fragments ¡½ Ansible Documentation

  • /etc/app/conf.d/*.conf ¤«¤é /etc/app.conf ¤òºîÀ®¤¹¤ë
  • ¥¢¥×¥ê¤¬conf.d/·Á¼°¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ë»È¤¦

uri: HTTP¥ê¥¯¥¨¥¹¥È¤ÎÁ÷¿®


jenkins¤«¤éansible¤Î¼Â¹Ô


no_log: ¥í¥°¤ò½ÐÎϤ·¤Ê¤¤

¡Ö-v¡×¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤¿¤È¤­¤Ë¤â¥Ñ¥¹¥ï¡¼¥ÉÅù¤Ï¥³¥ó¥½¡¼¥ë¤Ëɽ¼¨¤·¤¿¤¯¤Ê¤¤¾ì¹çÅù¡£

  • How do I keep secret data in my playbook?
  • Ê£»¨¤ÊÊÑ¿ô¤òwith_item¤Ç½èÍý¤¹¤ë¤È¤­¡¢Á´¤ÆÉ½¼¨¤·¤¿¤¯¤Ê¤¤¾ì¹ç
  • set_fact¤Çɽ¼¨¤·¤¿¤¤ÊÑ¿ô¤À¤±with_items¤Çºî¤ë»þ¤Ë¤â»È¤¨¤ë
    • ¥í¥°¤Îɽ¼¨: ¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤Ë ¡Ö-e 'show_log=true'¡×
    • playbook.yml
  vars:
    - show_log: false
  tasks:
    - debug: msg="{{ item }}"
      with_items: "{{ huge_var }}"
      no_log: "{{ not show_log|bool }}"

fetch: ¥ê¥â¡¼¥È¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥«¥ë¤Ë¥³¥Ô¡¼

  • Ê£¿ô¤Î¥ê¥â¡¼¥È¥Û¥¹¥È¤«¤é¡¢¥í¡¼¥«¥ë¤Ë¥³¥Ô¡¼¤Ç¤­¤ë¡£¥Ä¥ê¡¼¹½Â¤¤Î°Ý»ý¤â¤Ç¤­¤ë¡£¥Ä¥ê¡¼¹½Â¤¤¬ÉÔÍפʾì¹ç¤Ï¡Öflat=yes¡×
    ansible -i hosts.ini -m fetch -a 'src=/etc/hosts dest=/tmp/backup/' web*
    
    tree -A /tmp/backup/
    /tmp/backup/
    ¨§¨¡¨¡ web01
    ¨¢   ¨¦¨¡¨¡ etc
    ¨¢       ¨¦¨¡¨¡ hosts
    ¨¦¨¡¨¡ web02
        ¨¦¨¡¨¡ etc
            ¨¦¨¡¨¡ hosts
  • "msg": "unable to calculate the checksum of the remote file" ¤Î¾ì¹ç¡¢Àܳ¤Ë¼ºÇÔ¤·¤Æ¤¤¤ë¤Î¤Ç¡¢-m pingÅù¤Ç³Îǧ¤¹¤ë¡£

expect: ÂÐÏýèÍý¤Î¼«Æ°²½


wait_for: ½èÍý¤¬´°Î»¤¹¤ë¤Þ¤ÇÂÔµ¡¤¹¤ë


local¤Ë¤¢¤ërpm¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë

  • ´Ä¶­¡§ansible 2.1.1.0
  • yum name=/tmp/example-1.0.0-1.rpm state=present or installed¤Ç¤Ï¡¢rpm¥Õ¥¡¥¤¥ë¤Î¥Ð¡¼¥¸¥ç¥ó¤¬ÊѤï¤Ã¤Æ¤â¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Ê¤¤¡£
  • state=latest¤À¤È¡¢¥ê¥Ý¥¸¥È¥ê¤ò¸¡º÷¤·¤Ë¹Ô¤¯¤Î¤Ç»È¤¨¤Ê¤¤¡£(yum¥É¥­¥å¥á¥ó¥ÈÄ̤ê)
  • rpm¥³¥Þ¥ó¥É¤Ç¥Ð¡¼¥¸¥ç¥ó¤ò¼èÆÀ¤·¤Æ¡¢°Û¤Ê¤ë¤Ê¤é¤Ð¥¢¥ó¥¤¥ó¥¹¥È¡¼¥ë¸å¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë
    - name: Find rpm
      shell: ls -t $(find /tmp/ -type f -name example-1.0.0-1.rpm) | head -1
      register: find_result
      changed_when: false
    
    - name: Get version of installed rpm
      shell: "rpm -q example | grep -o -P '[\\d\\.\\-]+' | head -n 1"
      register: installed_version
      changed_when: false
      ignore_errors: yes
    
    - name: Get version of local rpm
      shell: "rpm -qp {{ find_result.stdout }} | grep -o -P '[\\d\\.\\-]+' | head -n 1"
      register: local_version
      changed_when: false
      ignore_errors: yes
    
    - name: Uninstall package
      yum: name=example state=absent
      when:
        installed_version.rc == 0
        and local_version.rc == 0
        and installed_version.stdout != local_version.stdout
    
    - name: Install package
      yum: name={{ find_result.stdout }} state=present
      ignore_errors: "{{ ansible_check_mode }}"
    
    - name: Start/stop service
      service: name=example state={{ example_state }} enabled={{ example_enabled }}
      ignore_errors: "{{ ansible_check_mode }}"

´û¸¥Õ¥¡¥¤¥ë¤ò¶õ(¥µ¥¤¥º0)¤Ë¤¹¤ë


¶õ¥Õ¥¡¥¤¥ë¤ÎºîÀ®

  • /tmp/dummy¤¬Â¸ºß¤¹¤ì¤Ð¡¢¥Ð¥Ã¥¯¥¢¥Ã¥×¸å¡¢¶õ¤Ë¤¹¤ë¡£¥Õ¥¡¥¤¥ë¤¬Ìµ¤±¤ì¤Ð²¿¤â¤·¤Ê¤¤¡£
        - lineinfile:
            dest: /tmp/dummy
            state: absent
            regexp: "^.+$"
            line: ""
            backup: yes
  • ¡Öbackup: yes¡×¤Ç¡Ö/tmp/dummy.YYYY-mm-dd@HH:MM:SS~¡×¤Î¤è¤¦¤Ê¥Ð¥Ã¥¯¥¢¥Ã¥×¥Õ¥¡¥¤¥ë¤¬½ÐÍè¤ë
  • ¡Öcreate: yes¡×¤òÉÕ¤±¤ë¤È¡¢Â¸ºß¤·¤Ê¤±¤ì¤ÐºîÀ®¤¹¤ë

LDAP¤Î´ÉÍý

  • ldap_users.yml
    ldap_users:
    - cn: user01
      dn: cn=user01,ou=users,dc=example,dc=com
      sshPublicKey: ssh-rsa ...
      description:
      - dev
      - stg
      - prod
  • ldapsearch, ldapmodify ¤ò»È¤¦¥µ¥ó¥×¥ë
  • psagers / ansible-ldap — Bitbucket
    • ansible-ldap is very simple and useful — ¥Ú¥ó¥®¥ó¤ÈÌû²÷¤Êµ¡³£¤ÎÆü¡¹
    • playbook¤ÈƱ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡¢library/ldap_entry ¤È¤Ê¤ë¤è¤¦¤ËÇÛÃÖ¤¹¤ë
    • objectClass: ldapPublicKey, sshPublicKey: ... ¤Ç»î¤·¤Æ¤ß¤¿¤¬¡¢OK¤È¤Ê¤ë¤â¤Î¤Î¡¢ÅÐÏ¿¤µ¤ì¤Ê¤¤
    • Ʊ̾¤Î°À­¤òÊ£¿ôÅÐÏ¿¤·¤¿¤¤¾ì¹ç¡¢description: [dev, stg, prod] ¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡£
    • ¥µ¥ó¥×¥ë
          - name: ldapPublicKey
            ldap_entry:
              server_uri: "{{ uri }}"
              bind_dn: "{{ binddn }}"
              bind_pw: "{{ bindpw }}"
              dn: "{{ item.dn }}"
              state: present
              objectClass: ldapPublicKey
              sshPublicKey: "{{ item.sshPublicKey }}"
            with_items: "{{ ldap_users }}"
      
          - name: override description exactly
            ldap_attr:
              server_uri: "{{ uri }}"
              bind_dn: "{{ binddn }}"
              bind_pw: "{{ bindpw }}"
              dn: "{{ item.dn }}"
              name: description
              state: exact
              values: "{{ item.description }}"
            with_items: "{{ ldap_users }}"

SSH¤Î¥í¥°¤«¤é¥¢¥¯¥»¥¹IP¤òÎóµó¤¹¤ë

  • 2016-07,08·î¤Î¥í¥°¤«¤é¡¢¥í¥°¥¤¥ó¤·¤¿IP¤òÎóµó
    ansible -i hosts.ini -m shell -a "zgrep Accepted /var/log/secure-20160[7,8]*.gz | grep -o -P 'from ([^\s]+)' | sort | uniq -c | sort -nr" --sudo localhost
    
    localhost | SUCCESS | rc=0 >>
         79 from 192.168.10.1
         22 from 192.168.10.128
         22 from 127.0.0.1

¥¤¥ó¥¹¥È¡¼¥ëºÑ¤ß¥Ñ¥Ã¥±¡¼¥¸°ìÍ÷

yum¥â¥¸¥å¡¼¥ë¤Ç¤Ï¥¤¥ó¥¹¥È¡¼¥ëºÑ¤ß°ìÍ÷¤Ï¼èÆÀ¤Ç¤­¤ë¤¬¡¢°ìÉô¤Î¥Ñ¥Ã¥±¡¼¥¸¤À¤±¤Ï»ØÄê¤Ç¤­¤Ê¤¤¡£(name¤Èlist¤¬ÇÓ¾»ØÄê)

  • playbook.yml
      tasks:
        - name: yum list installed
          yum: list=installed
          register: result
          ignore_errors: yes
          changed_when: False
    
        - debug: var=result
  • ¼Â¹Ô·ë²Ì:
    ok: [127.0.0.1] => {
        "result": {
            "changed": false, 
            "results": [
                {
                    "arch": "x86_64", 
                    "epoch": "0", 
                    "name": "MAKEDEV", 
                    "nevra": "0:MAKEDEV-3.24-6.el6.x86_64", 
                    "release": "6.el6", 
                    "repo": "installed", 
                    "version": "3.24", 
                    "yumstate": "installed"
                }, 
                ...

ssh¸ø³«¸°¤ÎÅÐÏ¿

  • www01¥Û¥¹¥È¤Îuser01¤Ë~/.ssh/id_rsa.pub¤òÅÐÏ¿¤¹¤ë
    ansible -i hosts.ini -m authorized_key -a 'user=user01 key="{{lookup("file","~/.ssh/id_rsa.pub")}}" state=present' --sudo www01

¸½ºß¤Înameserver¤ò¼èÆÀ

/etc/resolv.conf¤Înameserver¤ÎÃͤò»²¾È¤·¤¿¤¤¡£

  • CentOS6.x EPEL: ansible 2.1.0.0 ¤Ç¤Ï°Ê²¼¤Î¤è¤¦¤Ë¼èÆÀ¤Ç¤­¤ë¡£
    ansible -m setup localhost
    ...
            "ansible_dns": {
                "nameservers": [
                    "192.168.1.1"
                ], 
                "search": [
                    "localdomain"
                ]
            },

Ansible2.0


Prompts: ¥æ¡¼¥¶ÆþÎϤòÂÔ¤Ä

  • playbook
    - hosts: all
      gather_facts: False
      connection: local
      vars_prompt:
        - name: "user_name"
          prompt: "Please enter name"
          private: no
      tasks:
        - debug: var=user_name
  • ¼Â¹Ô
    ansible-playbook -i hosts.ini test.yml
    Please enter name: hoge
    
    TASK: [debug var=user_name] *************************************************** 
    ok: [localhost] => {
        "var": {
            "user_name": "hoge"
        }
    }
  • -e "var1=value1 var2=value2" ¤ÎÍͤ˼¹Իþ¤ËÃͤòÅϤ»¤ë¡£¤³¤Î¾ì¹ç¤Ï¥×¥í¥ó¥×¥È¤Ïɽ¼¨¤µ¤ì¤Ê¤¤¡£
    ansible-playbook -i hosts.ini test.yml -e "user_name=hogehoge"
    
    TASK: [debug var=user_name] *************************************************** 
    ok: [localhost] => {
        "var": {
            "user_name": "hogehoge"
        }
    }
  • Îã¡§ºï½ü³Îǧ¡£"no"¤Ê¤éÃæ»ß
      vars_prompt:
        - name: "confirm"
          prompt: "Do you really want to delete ? [yes/no]"
          private: no
    
      tasks:
        - name: confirm
          fail: msg="aborted"
          when: confirm != "yes"

Ǥ°Õ¤Îssh¥ª¥×¥·¥ç¥ó¤Ä¤±¤Æ¼Â¹Ô

ansible.cfgÆâ¤Ç¡Össh_args = ¡×¤ÇǤ°Õ¤Î¥ª¥×¥·¥ç¥ó¤ò»ØÄê¤Ç¤­¤ë¡£
¥Ç¥Õ¥©¥ë¥È¤Î¥ª¥×¥·¥ç¥ó¤Ï¾å½ñ¤­¤µ¤ì¤ë¤¿¤á¡¢¥Ç¥Õ¥©¥ë¥È¤Î¥ª¥×¥·¥ç¥ó+ÄɲäΥª¥×¥·¥ç¥ó¤È½ñ¤¤¤¿Êý¤¬Îɤµ¤½¤¦¡£
´Ä¶­ÊÑ¿ô¤Ë ANSIBLE_SSH_ARGS ¤¬¤¢¤ë¤È¡¢ansible.cfg¤è¤ê¤âÍ¥À褵¤ì¤ë¡£

  • playbook¤ÈƱ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤Ë ansible.cfg ¤òÃÖ¤¯¡£
    [defaults]
    forks = 5
    timeout = 30
    # CentOS6¤Çparamiko¤ò»È¤¦¾ì¹ç¡¢False¤Ë¤¹¤ë»ö¤ÇÁ᤯¤Ê¤ë
    record_host_keys = False
    
    [ssh_connection]
    ansible_connection = ssh
    ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -F ssh-config
    # True¤Ë¤¹¤ë¤È¹â®²½¤¹¤ë¤¬¡¢/etc/sudoers¤Çrequiretty¤ò¥³¥á¥ó¥È¥¢¥¦¥È¤¹¤ëɬÍפ¬¤¢¤ë
    pipelining = True

³ÈÄ¥»Ò¤ò½ü¤¤¤¿¥Õ¥¡¥¤¥ë̾¤Î¼èÆÀ

  • v1.9.4¤Ç¼Â¸½¤¹¤ë¡£v2.0°Ê¹ß¤Ç¤Ï¡Ösplitext ¡×¤¬»È¤¨¤ë¡£
    - debug: msg="{{ '/etc/httpd/conf/httpd.conf' | basename | regex_replace('\.conf$', '') }}" # httpd
  • v2.0°Ê¹ß
    - debug: msg="{{ '/etc/httpd/httpd.conf' | basename | splitext }}" # httpd
    - debug: msg="{{ '/etc/httpd/httpd.conf.j2' | basename | splitext | first }}" # httpd.conf

tarball ¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë

  • ´Ä¶­
    • CentOS 6.x 64bit
    • ansible v1.9.4
  • Îã¡§phantomjs
    • bitbucket¤Î¥Õ¥¡¥¤¥ë¼ÂÂΤÏAWS S3¤Ë¤¢¤ë¤è¤¦¤Ç¡¢¥ê¥ó¥¯¤òƧ¤à¤È¡ÖLocation: https://xxxx.s3.amazonaws.com/...¡×¤Î¤è¤¦¤ËÊ֤äƤ¯¤ë¡£¤·¤«¤·¡¢unarchive¥â¥¸¥å¡¼¥ë¤Ï¤½¤ì¤ò¥À¥¦¥ó¥í¡¼¥É¤Ç¤­¤Ê¤«¤Ã¤¿¡£get_url¥â¥¸¥å¡¼¥ë¤À¤ÈOK
    • ¤¤¤Þ¤¤¤Á¤ÊÅÀ¡§/tmp/phantomjs.tar.bz2 ¤ò¥Ð¡¼¥¸¥ç¥ó¤ÎȽÃǤ˻ȤäƤ¤¤ë¤Î¤Ç¡¢»Ä¤Ã¤¿¤Þ¤Þ¤Ë¤Ê¤ë¡£ºï½ü¤¹¤ë¤ÈºÆ¥À¥¦¥ó¥í¡¼¥É¤«¤é»Ï¤Þ¤ë
  • roles/phantomjs/defaults/main.yml
    phantomjs_install_dir: /usr/local/bin
    phantomjs_url:
      - url: https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.8-linux-x86_64.tar.bz2
        sha256sum: "a1d9628118e270f26c4ddd1d7f3502a93b48ede334b8585d11c1c3ae7bc7163a" # sha256sum phantomjs-1.9.8-linux-x86_64.tar.bz2
  • roles/phantomjs/tasks/main.yml
    - name: Download PhantomJS
      get_url: url={{ phantomjs_url[0].url }} sha256sum={{ phantomjs_url[0].sha256sum }} dest=/tmp/phantomjs.tar.bz2 force=no
      register: new_archive
      tags:
        - phantomjs
    
    - name: Unarchive PhantomJS
      unarchive: src=/tmp/phantomjs.tar.bz2 dest=/tmp copy=no creates=yes
      when: new_archive|changed
      tags:
        - phantomjs
    
    - name: Install PhantomJS
      shell: cp -f /tmp/{{ phantomjs_url[0].url | basename | regex_replace('\.tar\.bz2|\.tar\.gz$', '') }}/bin/phantomjs {{ phantomjs_install_dir }}/
      when: new_archive|changed
      tags:
        - phantomjs

register¤Î·ë²Ì¤ò»È¤Ã¤ÆÊ£¿ô²ó¥ë¡¼¥×¤¹¤ë

  • Îã¡§user01¤¬mysql¤Î¥í¥°¤ò¸«¤¨¤ë¤è¤¦¤Ë¡¢¤Þ¤¿wheel¥°¥ë¡¼¥×¤Ë¤âÄɲÃ
    - hosts: all
      gather_facts: true
      become: yes
      vars:
        - user_name: user01
        - user_groups:
          - wheel
          - mysql
        - debug: 0
    
      pre_tasks:
    
      roles:
    
      tasks:
        - name: Check if user exists
          shell: /usr/bin/id -u {{ item }}
          register: result_id
          with_items: user_groups
          ignore_errors: yes
          changed_when: False
    
        - debug: var=result_id
          when: debug != 0
    
        - name: Modify user groups
          user: name={{ user_name }} groups={{ item.item }} append=yes
          when: item.rc == 0
          with_items: "{{ result_id.results }}"
    
      handlers:
    
      post_tasks:

1.9¤«¤ésudo¤¬É¬Íפʻþ¤Ïbecome¤ò»È¤¦

root¸¢¸Â¤¬É¬Íפʾì¹ç¡¢1.9¤«¤é¡Öbecome: yes¡×¤¬¿ä¾©¡£
¡Ösudo: true¡×¤ÏÈó¿ä¾©¤Ë¤Ê¤Ã¤¿¡£


Ť¤¹Ô¤ò²þ¹Ô¤¹¤ë

YAML¹½Ê¸¤ò»È¤Ã¤ÆÊ¬³ä¤¹¤ë¡£

  • '>' : folded blockµ­Ë¡¡£²þ¹Ô¤òȾ³Ñ¥¹¥Ú¡¼¥¹¤ËÃÖ´¹¡£ºÇ½ª¹Ô¤Î²þ¹Ô¤ÏÊݸ¡£1¹Ô¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤ë¡£
    # "echo foo var\n"¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤ë
    - shell: >
        echo foo
        var
  • '|' : literal blockµ­Ë¡¡£²þ¹Ô¤ÏÊݸ¤µ¤ì¤ë¡£
    # "echo foo\n echo var"¤È¤·¤Æ¼Â¹Ô¤µ¤ì¤ë
    - shell: |
        echo foo
        echo var

¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¥Á¥å¡¼¥Ë¥ó¥°

  • SSH
    • OpenSSH 5.5°Ê²¼¤Î¾ì¹ç(CentOS6/openssh-5.3p1-118.1.el6_8.x86_64)
      • paramiko¥é¥¤¥Ö¥é¥ê¤¬»ÈÍѤµ¤ì¤ë¡£ansible_connection¥ª¥×¥·¥ç¥ó¤Çssh¤òÌÀ¼¨Åª¤Ë»ØÄê¤Ç¤­¤ë¡£
      • record_host_keys=False ¤Ë¤¹¤ë¡£ record_host_keys
    • OpenSSH 5.6°Ê¾å(CentOS7/openssh-6.6.1p1-25.el7_2.x86_64)
      • ¼«Æ°Åª¤Ëssh¤¬»È¤ï¤ì¤ë¡£
      • ansible.cfg
        [defaults]
        # ÌÀ¼¨Åª¤Ëssh¤ò»È¤¦
        transport      = ssh
        
        [ssh_connection]
        # sshÀܳ¤ÎºÆÍøÍѤò¤¹¤ë¡£¥¿¥¤¥à¥¢¥¦¥È¤Î»þ´Ö¤ò±ä¤Ð¤¹
        ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -F ssh-config
        # ¥Û¥¹¥È̾¤¬Ä¹¤¤»þ¤Ë¥¨¥é¡¼¤Ë¤Ê¤ë¤Î¤òËɤ°
        control_path = %(directory)s/%%h-%%r
        # True¤Ë¤·¤¿¤¤¾ì¹ç¡¢Á´¥¯¥é¥¤¥¢¥ó¥È¤Î/etc/sudoers¤Îrequiretty¤ò̵¸ú¤Ë¤¹¤ëɬÍפ¬¤¢¤ë¡£sudo»þ¤Ë¥¨¥é¡¼¤Ë¤Ê¤ë¡£
        pipelining = True
    • OpenSSH 6.7°Ê¹ß:
      • ansible.cfg
        [ssh_connection]
        # '%C' by a hash of the concatenation: %l%h%p%r.
        control_path=%(directory)s/%%C
      • ssh-configÆâ¤Ç¡ÖHostName¡×¤ËƱ̾¥Û¥¹¥È¤ò»ØÄꤷ¤Ê¤¤¤è¤¦¤ËÃí°Õ¡£Æ±¤¸¥»¥Ã¥·¥ç¥ó¤¬»È¤¤²ó¤µ¤ì¡¢¸í¤Ã¤¿¥Û¥¹¥È¤ØÀܳ¤µ¤ì¤ë»ö¤¬¤¢¤ë
  • fact¥­¥ã¥Ã¥·¥å
    • Fact Caching memcached/redis/json ¤Ø¥­¥ã¥Ã¥·¥å²Äǽ
  • copy¥â¥¸¥å¡¼¥ë¤ÎÂå¤ï¤ê¤Ë¡¢synchronize¥â¥¸¥å¡¼¥ë¤ò»È¤¦
    • Ê£¿ô¥Õ¥¡¥¤¥ë»þ¡¢CentOS6¤À¤Èparamiko¥é¥¤¥Ö¥é¥ê¤¬»È¤ï¤ìÈó¾ï¤ËÃÙ¤¤¤«¥¿¥¤¥à¥¢¥¦¥È¤¹¤ë¡£
    • synchronize¥â¥¸¥å¡¼¥ë¤Ï¡¢ÆâÉô¤Çrsync¤ò»È¤¦¤¿¤á¿ôÉäǤ¹¤à¡£
    • copy¥â¥¸¥å¡¼¥ë¤È°ã¤¤¡¢owner¤ägroup¤¬ÊѤï¤é¤Ê¤¤¤Î¤Ç¡¢file¥â¥¸¥å¡¼¥ë¤ÇÊѤ¨¤ë
    • ansible.cfg¤Çssh_args¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¡Öuse_ssh_args=yes¡×¤Ë¤¹¤ë

validate:ÀßÄê¥Õ¥¡¥¤¥ëÅù¤Î¸¡¾Ú¤·¤Æ¤«¤é¹¹¿·

  • template, lineinfile, blockinfile¤Ïvalidate='command %s'¤Ç¸¡¾Ú¤ò¹Ô¤Ã¤Æ¡¢À®¸ù¤·¤¿¾ì¹ç(exit code=0)¤Î¤ß¹¹¿·¤¹¤ë»ö¤¬¤Ç¤­¤ë¡£
  • sshd_config¤ÎÎã
    validate='sshd -t -f %s'
  • visudo¤ÎÎã
    validate='visudo -cf %s'
  • httpd¤ÎÎã¡§httpd.conf¤Î¤ßÂбþ¡£conf.d/°Ê²¼¤Î¥Õ¥¡¥¤¥ë¤ò»ØÄꤹ¤ë¤È¥¨¥é¡¼¤Ë¤Ê¤ë
    validate: 'apachectl -t -f %s'
  • php¤ÎÎã
    alidate='php -l %s'

yum groupinstallÁêÅö

  • yum groupinstallÁêÅö¤ò¤·¤¿¤¤
    sudo yum groupinstall "Japanese Support"
  • yum group-id¤òÄ´¤Ù¤ë¡£¡Ögroup name (group-id)¡×¤Î¤è¤¦¤Ëɽ¼¨¤µ¤ì¤ë
    LANG=C yum grouplist -v
    ...
       Japanese Support (japanese-support) [ja]
    ...
  • with_items¤Ç»ØÄꤹ¤ë¾ì¹ç
    - hosts: all
      sudo: True
      tasks:
        - name: yum groupinstall
          yum: name="{{ packages }}" state=present
          vars:
            packages:
            - "@japanese-support"

Extras Modules¤ò»È¤¦

  • Extras Modules
    • stable¤Ç¤Ï¤Ê¤¤¥â¥¸¥å¡¼¥ë¤¬Æþ¤Ã¤Æ¤¤¤ë¡£¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤²ÄǽÀ­¤¬¤¢¤ë¡£
  • ÆÈ¼«¥é¥¤¥Ö¥é¥ê¤Î»ØÄê¤Ï¤¤¤¯¤Ä¤«¤¢¤ë
    • playbook.yml¤ÈƱ¤¸³¬ÁØ¤Ë library ¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤¹¤ë
    • export ANSIBLE_LIBRARY=...
    • --module-path=...
  • Îã¡§ ansible 1.9¤«¤é pam_limits(v2.0¸þ¤±) ¤ò»È¤¦
    git clone https://github.com/ansible/ansible-modules-extras.git
    export ANSIBLE_LIBRARY=ansible-modules-extras
    ansible-playbook -i hosts.ini playbook.yml

ssh¤Ç·Ò¤¬¤ºlocal¤Ç¼Â¹Ô

  • playbook.yml: connection: local ¤ò»ØÄꤹ¤ë
    - hosts: localhost
      gather_facts: True
      sudo: False
      connection: local

¥Ñ¥Ã¥±¡¼¥¸¤¬¥¤¥ó¥¹¥È¡¼¥ëºÑ¤ß¤«¤Î¥Á¥§¥Ã¥¯

  • yum/rpm¤ò»È¤ï¤º¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ¤¤¤ë¾ì¹ç(yum repoÅù)¡¢stat¤Ç¥Õ¥¡¥¤¥ë¤Î̵ͭÅù¤ÇȽÃǤ·¤¿Êý¤¬Îɤµ¤½¤¦
    - name: Check if Package is installed
      stat:
        path: /etc/yum.repos.d/epel.repo
      register: result
      ignore_errors: yes
      changed_when: False
    
    # ¥Ñ¥Ã¥±¡¼¥¸¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Î½èÍý
    - debug: var=result
      when: result.stat.exists == false
  • rpm¥³¥Þ¥ó¥É¤ò»È¤¦¤È¡Ö[WARNING]: Consider using yum, dnf or zypper module rather than running rpm¡×¤¬½Ð¤ë¤Î¤Ç¡¢¡Öwarn: no¡×¤Ç̵»ë¤·¤Æ¤¤¤ë¡£
    • ¡Öyum: list=installed¡×¤Ç¥¤¥ó¥¹¥È¡¼¥ëºÑ¤ß¥Ñ¥Ã¥±¡¼¥¸°ìÍ÷¤¬¼èÆÀ¤Ç¤­¤ë¤¬¡¢Á´¤ÆÎóµó¤µ¤ì¤ë¤¿¤áÃÙ¤¤&»È¤¤¤Ë¤¯¤¤¡£
      - name: Check if Package is installed
        shell: rpm -q {{ package }} > /dev/null; echo $?
        args:
          warn: no
        register: result
        ignore_errors: yes
        changed_when: False
      
      # ¥Ñ¥Ã¥±¡¼¥¸¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¤Î½èÍý
      - debug: var=result
        when: result.stdout == "0"
  • remote host¤Î /home/<user> ¤ò40²ó¥ë¡¼¥×¤·¤¿·ë²Ì(¸ºß¤·¤Æ¤¤¤ëuser: 20, ÉÔºßuser: 20)
    • ¥Õ¥¡¥¤¥ë¤Î¸ºß¥Á¥§¥Ã¥¯(stat.exists)¤Î¤ß¤ÇÎɤ¤¾ì¹ç¤Ï¡¢ÃÙ¤¯¤Ê¤ë¥ª¥×¥·¥ç¥ó¤Ï̵¸ú²½¤Ç¤­¤ë¡£
    • get_checksum¤ÏµðÂç¤Ê¥Õ¥¡¥¤¥ë¤òÂоݤˤ¹¤ë¤ÈÆÃ¤ËÃÙ¤¤
    • ansible 2.9.6
      stat¤Î¥ª¥×¥·¥ç¥óÉÿô
      path¤Î¤ß67
      get_attributes: no61
      get_checksum: no63
      get_mime: no67
      get_attributes: no
      get_checksum: no
      59

Êѹ¹°·¤¤¤Ë¤·¤Ê¤¤

  • changed_when: False
    Ëè²ó¼Â¹Ô¤¹¤ë¤¬¡¢Êѹ¹°·¤¤¤Ë¤·¤Ê¤¤¡£¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤ë¤«¤Î¥Á¥§¥Ã¥¯Åù¤ËÊØÍø
    - name: Check if git v1 is installed
      shell: rpm -q git > /dev/null
      ignore_errors: yes
      register: result
      changed_when: False

handlers

  • Intro to Playbooks
    • °ìÈֺǸå¤Ë¼Â¹Ô¤µ¤ì¤ë
    • ÀßÄê¥Õ¥¡¥¤¥ë¤òÊ£¿ô½ñ¤­´¹¤¨¤¿¸å¤Ë¥µ¡¼¥Ó¥¹¤ÎºÆµ¯Æ°¤¬É¬Íפʻþ¤Ê¤É¤Ë»È¤¨¤ë
  • when¤Î¾ò·ï¤ËÃí°Õ¡£¥µ¡¼¥Ó¥¹¤ò»ß¤á¤¿¤Þ¤Þ¤Ë¤·¤¿¤¯¤È¤â¡¢notify¤¬È¯À¸¤¹¤ë¤Èhandler¤¬¼Â¹Ô¤µ¤ì¤ë¤¿¤á¡¢ÀßÄê¥Õ¥¡¥¤¥ë¤¬½ñ¤­´¹¤ï¤Ã¤¿¾ì¹ç¤Ê¤É¡¢Í½´ü¤»¤º¥µ¡¼¥Ó¥¹¤¬µ¯Æ°¤¹¤ë»ö¤¬¤¢¤ë¡£¤½¤Î¤¿¤áÊÑ¿ô(Îã¡§iptables_state)¤òÍѰդ·¤Æ¾ò·ï¤ËÆþ¤ì¤Æ¤ª¤¯¡£
    • handlers/main.yml
      - name: restart iptables
        service: name=iptables state=restarted
        when: ansible_os_family in [ "RedHat" ] and iptables_state == "started"

roles

  • tag¤¬ÉÕ¤¤¤Æ¤¤¤Ê¤¤role¤Ëtag¤òÉÕ¤±¤Æ¼Â¹Ô¡£¡Ö-t terraform¡×¤Ç»ØÄê¥í¡¼¥ë¤À¤±¼Â¹Ô¤Ç¤­¤ë¡£roleÆâ¤Î»ØÄê¤Î¥¿¥°¤Î¤ß¼Â¹Ô¤¹¤ë¥ª¥×¥·¥ç¥ó¤Ç¤Ï̵¤¤¡£
      roles:
      - { role: andrewrothstein.terraform, tags: terraform }
  • roles¤ÎÁ°¸å¤Ç¼Â¹Ô¤·¤¿¤¤¾ì¹ç¤Ï¡Öpre_tasks¡×¡Öpost_tasks¡×¤ò»È¤¦
  • role-dependencies
    • role¤Î°Í¸´Ø·¸¤òÀßÄê¤Ç¤­¤ë¡£°Í¸Àè¤Îrole¤¬Àè¤Ë¼Â¹Ô¤µ¤ì¤ë¡£
    • Ê£¿ô¤Îrole¤«¤é°Í¸¤¬¤¢¤Ã¤Æ¤â1²ó¤À¤±¼Â¹Ô¤µ¤ì¤ë¡£¡Ömeta/main.yml¡×¤Ç¡Öallow_duplicates: true¡×¤È¤¹¤ë¤È¡¢½ÅÊ£¼Â¹Ô¤µ¤ì¤ë¡£
    • role´Ö¤ÇÊÑ¿ô¤òÀßÄꤹ¤ë»þ¤Ï¡Övars¡×¤ò»È¤¦
    • roles/zabbix_agent/meta/main.yml
      dependencies:
      - role: epel
        vars:
          epel_enabled: yes
  • »ØÄê¤Î¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥ó¡¢¥Ð¡¼¥¸¥ç¥ó¤Î¾ì¹ç¤Î¤ßrole¤ò¼Â¹Ô¤¹¤ë¡£Îã¡§CentOS7¤Î¾ì¹ç¤Î¤ßfirewalld¤Îrole¤ò»È¤¦
    - hosts: webservers
      roles:
      - { role: firewalld, when: "ansible_os_family == 'RedHat' and ansible_distribution_major_version|int >= 7" }
  • playbook¼Â¹Ô»þ¡¢roles¤ÎÃæ¤ÎÊÑ¿ô(Îã¡§roles/foo/defaults/main.yml)¤ò¾ò·ïʸ¤Ë»È¤¦¤ÈÁ´¤Æ¥¹¥­¥Ã¥×¤¹¤ë¡£Í½¤áhosts, group_vars, host_varsÅù¤ÇÄêµÁ¤¹¤ì¤ÐÀµ¾ï¤Ëưºî¤¹¤ë
    - hosts: webservers
      roles:
        - { role: some_role, when: "some_role_enabled == 'yes'" }

³«È¯


°Í¸´Ø·¸


¼«ºî¥â¥¸¥å¡¼¥ë

Developing Modules — Ansible Documentation


¥³¥Þ¥ó¥É¤Îjson½ÐÎϤòÊÑ¿ô¤È¤·¤Æ¼è¤ê¹þ¤à

  • Îã¡§awscli¤Îjson½ÐÎϤòÊÑ¿ô¤Ë¼è¤ê¹þ¤à¡£
      - name: list-hosted-zones
        local_action: shell aws --profile {{ aws_profile }} route53 list-hosted-zones --output json
        register: route53_result
    
      - set_fact:
          route53_hostedzone: "{{ (route53_result.stdout|from_json).HostedZones }}"
      - debug: var=route53_hostedzone

´Ä¶­ÊÑ¿ô¤Î»ØÄê

  • ¥³¥Þ¥ó¥É¼Â¹Ô»þ¤Ë /opt/bin ¤òÄɲ乤ë
    - hosts: all
      gather_facts: True
      tasks:
      - shell: test.sh
        environment:
          PATH: "/opt/bin:{{ ansible_env.PATH }}"
        register: result
      - debug: var=result.stdout
  • ¥¿¥¤¥à¥¾¡¼¥ó¤òÊѹ¹¤¹¤ë
        - shell: date
          environment:
            TZ: "{{ lookup('env', 'TZ') }}"
    • ¥¿¥¤¥à¥¾¡¼¥ó¤òÊѹ¹¤·¤Æ¼Â¹Ô
      TZ=JST ansible-playbook -l 127.0.0.1 -i hosts.ini playbook.yml
      TZ=UTC ansible-playbook -l 127.0.0.1 -i hosts.ini playbook.yml

shell:/command: ¥³¥Þ¥ó¥É¤Î¼Â¹Ô

  • command
    • ´Ä¶­ÊÑ¿ô¤Ï̵¸ú
    • ¥Ñ¥¤¥×"|", ¥ê¥À¥¤¥ì¥¯¥È"><"¤Ï»ÈÍÑÉÔǽ
  • shell
    • shell(¥Ç¥Õ¥©¥ë¥È:/bin/sh)¤ò·Ðͳ¤·¤Æ¼Â¹Ô¤µ¤ì¤ë
    • ¥Ñ¥¤¥×"|", ¥ê¥À¥¤¥ì¥¯¥È"><"¤¬»ÈÍѲÄǽ
    • ´Ä¶­ÊÑ¿ô¤ÏÍ­¸ú
    • Ê£¿ô¹Ô¤Î¾ì¹ç¡¢";"¤Ç¶èÀÚ¤ë»ö¤¬¤Ç¤­¤ë
        - shell: >
            echo foo;
            echo var;
    • /.bashrcÅù¤ÏÆÉ¤ß¹þ¤Þ¤ì¤Ê¤¤¡£~/.bashrc ¤ÎÃæ¤ÇPATH¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢1¹Ô¤Ç¼Â¹Ô¤¹¤ëɬÍפ¬¤¢¤Ã¤¿¡£

      # À®¸ù
      shell:
        cmd: "/bin/bash -l -c 'tfenv install latest'"
      
      # ¼ºÇÔ
      shell:
        cmd: "tfenv install latest"
        executable: "/bin/bash -l"

shell:¤äcommand:Æâ¤ÇÊ£»¨¤Ê½èÍý

  • jinja2¥Æ¥ó¥×¥ì¡¼¥È¹½Ê¸¤¬»È¤¨¤ë¤Î¤Ç¡¢Ê£»¨¤Ê»ö¤¬¤Ç¤­¤ë¡£¤·¤«¤·¡¢¸«Æñ¤¯¤Ê¤ë¤Î¤Ç¤ª´«¤á¤Ï¤·¤Ê¤¤
  • Îã¡§dict_var1.option2.value¤¬¶õ¤Î¾ì¹ç¡¢command¼Â¹Ô»þ¤Î¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë
    • File not found: "playbook.jinja2-example1.zip" at page "Memo/Ansible"[źÉÕ]


shell:Ãæ¤Çread¥³¥Þ¥ó¥É¤¬¤¢¤Ã¤Æ¤âÂÔµ¡¤·¤Ê¤¤

  • Î㤨¤Ð script.sh¤ÎÃæ¤Ç¡Öread -p "(y/n)"¡×Åù¤Îµ­½Ò¤¬¤¢¤Ã¤¿¾ì¹ç¡¢playbook¼Â¹Ô¤¹¤ë¤È¡¢¥×¥í¥ó¥×¥È¤Îɽ¼¨¤Ï¤Ê¤¯¡¢ÃæÃǤ¹¤ë¤¬À®¸ù°·¤¤¤È¤Ê¤ê¡¢¼ºÇԤ˵¤¤Å¤­¤Ë¤¯¤¤¡£
    shell: /path/to/script.sh

localhost¤Ç¼Â¹Ô¤¹¤ë

  • Delegation
    • playbookÁ´ÂΤòlocal¤ËÂФ·¤Æ¼Â¹Ô¤·¤¿¤¤¾ì¹ç¡¢¡Öconnection: local¡×¤«¡Öhosts: localhost¡×¤ò»È¤¦
    • playbook¤Î°ìÉôtask¤òlocal¤ËÂФ·¤Æ¼Â¹Ô¤·¤¿¤¤»þ¡¢¡Ölocal_action:¡×¤¬»È¤¨¤ë
    • local_action:¤òÊ£¿ô¹Ô¤Ëʬ¤±¤Æ½ñ¤­¤¿¤¤¾ì¹ç¡¢module:¤Èmodule¤Î¥Ñ¥é¥á¡¼¥¿¤Ëʬ¤±¤Æ½ñ¤¯
        tasks:
          - name: Send summary mail
            local_action:
              module: mail
              subject: "Summary Mail"
              to: "{{ mail_recipient }}"
              body: "{{ mail_body }}"
            run_once: True
  • Îã:uptime ¥³¥Þ¥ó¥É¤ò localhost ¤Ç¼Â¹Ô
    - hosts: localhost
      gather_facts: False
      tasks:
      - name: uptime
        local_action: command uptime
        register: result
      - debug: var=result
  • --sudo ¤òÉÕ¤±¤Æ¼Â¹Ô¤·¤¿¾ì¹ç¡¢local_action ¤Î·ë²Ì¤âroot¥æ¡¼¥¶¤Ç¼Â¹Ô¤·¤¿»ö¤Ë¤Ê¤ë
    • Î㤨¤Ð¼Â¹Ô»þ¤Î¥æ¡¼¥¶¤ÎÀßÄê¥Õ¥¡¥¤¥ë(/home/user01/.aws/config) ¤ò»²¾È¤¹¤ë¤¬¡¢--sudo¤òÉÕ¤±¤¿¤¤¾ì¹ç¤ËÌäÂ꤬µ¯¤­¤ë¡£/root/.aws/config¤òõ¤½¤¦¤È¤¹¤ë
    • ¡Ölocal_action:¡×¤À¤±local user¤ò»È¤¤¤¿¤¤¾ì¹ç¡¢task¤Ë¡Öbecome: false¡×¤òÉÕ¤±¤ë
    • playbook.yml
      - hosts: localhost
        gather_facts: False
        tasks:
        - name: pwd
          local_action: shell echo $HOME
          register: result
        - debug: var=result.stdout
    • --sudo ¤òÉÕ¤±¤Æ¼Â¹Ô¤·¤¿¾ì¹ç
      ansible-playbook -i hosts.ini -l localhost --sudo playbook.yml
      ...
      TASK: [debug var=result.stdout] ***********************************************
      ok: [127.0.0.1] => {
          "result.stdout": "/root"
      }

SELinux

  • ɸ½à¤Ç selinux ¥â¥¸¥å¡¼¥ë¤¬¤¢¤ë
  • state=disabled¤ËÀßÄê¸å¡¢getenforce¤¹¤ë¤È"Enforcing(Í­¸ú)"¤À¤Ã¤¿¡£ (ansible-1.7-1.el6.noarch¤Ç³Îǧ)
    • "setenforce 0" ¤¹¤ë¤«¡¢ºÆµ¯Æ°¤¹¤ëɬÍפ¬¤¢¤Ã¤¿

target uses selinux but python bindings (libselinux-python) aren't installed!

  • /etc/hosts¤òÊѹ¹¤·¤è¤¦¤È¤·¤¿¤È¤³¤í°Ê²¼¤Î¥¨¥é¡¼¤¬½Ð¤¿
    msg: Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!
  • Âоݥۥ¹¥È¤Ë¥í¥°¥¤¥ó¤·¤ÆSElinux¤ò³Îǧ¤¹¤ë¤È Permissive ¤À¤Ã¤¿
    getenforce
    Permissive
  • CentOS 6/7: libselinux-python¤ò¥¤¥ó¥¹¥È¡¼¥ë¸å¡¢Àµ¾ï¤Ëưºî¤·¤¿
    sudo yum install libselinux-python -y
  • Ubuntu
    sudo apt install python-selinux

split: ʸ»úÎó¤Îʬ³ä

  • ansible-1.7-1.el6.noarch
  • test.yml
    - hosts: 127.0.0.1
      gather_facts: False
      vars:
        keys: ""
      tasks:
        - name: split
          debug: var="{{ item }}"
          with_items: "{{ keys.split(',') }}"
  • ¼Â¹Ô
    ansible-playbook -i hosts.ini test.yaml --extra-vars 'pub_keys=aaa,bbb,ccc'
    
    TASK: [split] *****************************************************************
    ok: [127.0.0.1] => (item=aaa) => {
        "aaa": "{{ aaa }}",
        "item": "aaa"
    }
    ok: [127.0.0.1] => (item=bbb) => {
        "bbb": "{{ bbb }}",
        "item": "bbb"
    }
    ok: [127.0.0.1] => (item=ccc) => {
        "ccc": "{{ ccc }}",
        "item": "ccc"
    }

--check»þ¤Ëµóư¤òÊѹ¹¤¹¤ë

°Ê²¼¤Î¤è¤¦¤Ë¡¢shell: ¤Î·ë²Ì¤ò¸µ¤ËȽÄꤹ¤ë¤è¤¦¤Ê¾ì¹ç¡¢¡Ö--check¡×¤Ç¤Ï¡¢¥Á¥§¥Ã¥¯task¤¬¼Â¹Ô¤µ¤ì¤Ê¤¤¤¿¤á¡¢¥¨¥é¡¼¤È¤Ê¤ë¤Î¤ò²óÈò¤¹¤ë¡£

  • ¥µ¥ó¥×¥ë
    - name: check if epel exists
      shell: rpm -q epel-release > /dev/null; echo $?
      args:
        warn: no
      register: result
      changed_when: False
    
    - name: install epel repository
      yum:
        name="http://ftp.riken.jp/Linux/fedora/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm"
        state=present
      when: result.stdout != "0"
      ignore_errors: "{{ ansible_check_mode }}" # ansible 2.1
  • Check Mode (¡ÈDry Run¡É) — Ansible Documentation
    • shell¤äcommand module¤Ïcheck mode»þ(--check)¤Ï¼Â¹Ô¤µ¤ì¤Ê¤¤¤¿¤á¡¢register¤ÇÅÐÏ¿¤µ¤ì¤¿ÊÑ¿ô¤ò¡¢debug module¤Çɽ¼¨¤·¤è¤¦¤È¤¹¤ë¤È¥¨¥é¡¼¤Ë¤Ê¤ë¡£
    • ansible 2.2: check_mode: ¤¬Äɲ䵤줿¡£
      • no: ¾ï¤Ënormal mode¤È¤·¤Æ¼Â¹Ô¡£command module¤ËÉÕ¤±¤¿¾ì¹ç¡¢--check¤Ç¤â¼Â¹Ô¤µ¤ì¤ë¡£
      • yes: ¾ï¤Ëcheck mode¤È¤·¤Æ¼Â¹Ô¡£¼Â¹Ô¤µ¤ì¤Ê¤¤¤¿¤á¡¢module¤Î¥Æ¥¹¥È»þ¤Ë»È¤¨¤ë¡©
        check_mode: no
    • ansible 2.1: ansible_check_mode ¤ò»È¤¦¡£--check»þ¤Î¥¨¥é¡¼¤ò̵»ë¤¹¤ë¤è¤¦¤Ë¤Ï¤Ç¤­¤ë
      ignore_errors: "{{ ansible_check_mode }}"

ansible-playbook¥ª¥×¥·¥ç¥ó

  • --check: dry-run¥â¡¼¥É
  • --diff: Êѹ¹ÅÀ¤òɽ¼¨¡£--check¤ÈƱ»þ¤Ë»ØÄꤹ¤ë¤ÈÎɤ¤
  • -v: verbose mode, Î㤨¤Ðcommand¤¬À®¸ù¤·¤¿»þ¤Î¥í¥°¤ÏÄ̾ï¤Ç¤Æ¤³¤Ê¤¤¤¬¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤È¸«¤¨¤ë
    • e, --extra-vars 'var1=val1 var2=val2': ÊÑ¿ô̾¤ÈÃͤò¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤éÅϤ¹¡£vars_prompt¤ÎÊÑ¿ô̾¤ò»ØÄꤹ¤ì¤Ð¡¢prompt¤Îɽ¼¨¤¬Ìµ¤¯¤Ê¤ë¤¿¤áÊØÍø

¥Õ¥¡¥¤¥ë/¥Ç¥£¥ì¥¯¥È¥ê¤Î¥³¥Ô¡¼

  • ¥í¡¼¥«¥ë¥Õ¥¡¥¤¥ë¤ò¥ê¥â¡¼¥È¤Ë¥³¥Ô¡¼
    ansible -i hosts.ini -m copy -a "copy: src=/src/myfiles/foo.conf dest=/etc/foo.conf" --user <username> --ask-pass --sudo <hostname>
  • ¥í¡¼¥«¥ë¥Ç¥£¥ì¥¯¥È¥ê¤ò¥ê¥â¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤Ë¥³¥Ô¡¼
    ansible -i hosts.ini -m copy -a "copy: src=/src/myfiles/ dest=/tmp/myfiles/" --user <username> --ask-pass --sudo <hostname>

¼Â¹Ô½ç½ø

  • ´ðËÜŪ¤Ë¤Ï¾å¤«¤é²¼¤À¤¬¡¢pre_tasks > roles > tasks > handlers > post_tasks ½ç½ø¤Ç¼Â¹Ô¤µ¤ì¤ë
  • ¥Û¥¹¥È¤¬Ê£¿ô¤¢¤ë¾ì¹ç¤Ï¡¢1¥¿¥¹¥¯¤ò¤¹¤Ù¤Æ¤Î¥Û¥¹¥È¤Ë¼Â¹Ô¤·¤Æ¤«¤é¡¢¼¡¤Î¥¿¥¹¥¯¤Ø¡£
  • Á´¤Æ¤Î¥Û¥¹¥È¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¡¢ÃæÃǤ¹¤ë
  • Îã: ansible 1.9.4
    • hosts.ini
      [web]
      web01.example.com
      web02.example.com
    • test.yml
      - hosts: web
        gather_facts: True
        vars:
      
        pre_tasks:
          - debug: msg="pre_tasks01"
      
        roles:
          - role01
      
        tasks:
          - name: task01
            file: path=/tmp/task01 state=touch
            notify: handler01
      
        handlers:
          - name: handler01
            debug: msg="handler01"
      
        post_tasks:
          - debug: msg="post_tasks01"
    • ¼Â¹Ô
      ansible-playbook -i hosts.ini test.yml
      ...
      TASK: [debug msg="pre_tasks01"] ***********************************************
      ok: [web01.example.com] => {
          "msg": "pre_tasks01"
      }
      ok: [web02.example.com] => {
          "msg": "pre_tasks01"
      }
      
      TASK: [role01 | debug msg="role01"] *******************************************
      ok: [web02.example.com] => {
          "msg": "role01"
      }
      ok: [web01.example.com] => {
          "msg": "role01"
      }
      
      TASK: [task01] ****************************************************************
      changed: [web02.example.com]
      changed: [web01.example.com]
      
      NOTIFIED: [handler01] *********************************************************
      ok: [web01.example.com] => {
          "msg": "handler01"
      }
      ok: [web02.example.com] => {
          "msg": "handler01"
      }
      
      TASK: [debug msg="post_tasks01"] **********************************************
      ok: [web01.example.com] => {
          "msg": "post_tasks01"
      }
      ok: [web02.example.com] => {
          "msg": "post_tasks01"
      }
      
      PLAY RECAP ********************************************************************
      web01.example.com          : ok=6    changed=1    unreachable=0    failed=0
      web02.example.com          : ok=6    changed=1    unreachable=0    failed=0

Module ¥â¥¸¥å¡¼¥ë

file

  • ¥Ç¥£¥ì¥¯¥È¥ê¤Èsymlink¤òºî¤ë
      - name: Create directory
        file: path=/tmp/test_dir state=directory owner=root group=root mode=0755
    
      - name: Create symlink
        file: src=/tmp/test_dir dest=/tmp/test_link state=link

Conditionals: ¾ò·ïʬ´ô

  • ÊÑ¿ô¤¬Ì¤ÄêµÁ¤Î¾ì¹ç: var1 is not defined
  • ÊÑ¿ô¤¬¶õ("")¤Î¾ì¹ç: var1 == None
  • when: ¤Çʸ»úÎó¤È¿ôÃͤòÈæ³Ó¤¹¤ë¾ì¹ç¤Ï¡¢'|int'¤¬É¬Í×
    when: ansible_distribution_major_version|int >= 7
  • 'yes', 'no', 'True', 'False'¤òboolÃͤȤ·¤ÆÈæ³Ó¤·¤¿¤¤¾ì¹ç
    when: is_enabled|bool
  • resultÊÑ¿ô¤ÎÃæ¤Ë¡Östr1¡×ʸ»ú¤¬´Þ¤Þ¤ì¤ë¤«¤Î¥Á¥§¥Ã¥¯¡£ÈÝÄê¤Ï¡Önot in¡×
    # ansible 2.9.6 ¤Ç¤Ï whenÁ´ÂΤò¥À¥Ö¥ë¥¯¥ª¡¼¥È¤Ç°Ï¤à¤È¡¢¾ï¤ËÀ®¸ù¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿¤Î¤ÇÉÔÍÑ
    when: 'str1' in result
    
    # ¤½¤ì°ÊÁ°¤Ç¤Ï¡¢¥À¥Ö¥ë¥¯¥ª¡¼¥È¤Ç³ç¤é¤Ê¤¤¤È¥¨¥é¡¼¤Ë¤Ê¤ë¤Ï¤º
    when: "'str1' in result"
  • ÇÛÎó
    when: ansible_distribution in [ 'CentOS', 'Red Hat Enterprise Linux' ]
  • Àµµ¬É½¸½
    # ¥Ñ¥¹¥ï¡¼¥É¤Ë¿ô»ú¤¬Æþ¤Ã¤Æ¤Ê¤¤¾ì¹ç¤ò¥Á¥§¥Ã¥¯
    when: password is not regex('\d+')
    
    # ÀèÆ¬°ìÃס£"| match(str)" ¤Ïv2.9¤ÇÇÑ»ßͽÄê¡£
    when: ansible_hostname is match("^web")
    
    # Éôʬ°ìÃ×
    when: ansible_hostname is search("web")
    
    # ¤½¤ì°Ê³°¤ÎÀµµ¬É½¸½
    when: ansible_hostname is regex("web")
  • register:¤ÈÁȤ߹ç¤ï¤»¤Æ»È¤¨¤ëÆÃÊ̤ʾò·ï
    when: result is failed
    when: result is succeeded
    when: result is skipped
    
    # ÈÝÄê¤Ï 
    when: var1 is not skipped
  • result.var1¤¬Ì¤ÄêµÁ¤Ê»þ¡¢default()¤ò»È¤¦¤È¾ò·ï¤òÁý¤ä¤µ¤º¤Ë¥·¥ó¥×¥ë¤Ë½ñ¤±¤ë
    when: (result.var1 | default("")) != "foo"

Error Handling ¥¨¥é¡¼¥Ï¥ó¥É¥ê¥ó¥°

  • ¥Ç¥Õ¥©¥ë¥È(v1.7.1)¤Ç¤Ï¡¢Æ±¤¸¥³¥Þ¥ó¥É¤¬Á´¤Æ¤Î¥Û¥¹¥È¤Ç¼ºÇÔ¤·¤¿¾ì¹ç¤ËÄä»ß¤¹¤ë¤è¤¦¤À
  • failed_when: ¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤¿»þ¤Ë²¿¤«¤¹¤ë
    • Controlling What Defines Failure
    • ½ªÎ»¥³¡¼¥É > 2¤Î»þ¤Ë¼ºÇԤȤ¹¤ë
      - hosts: 127.0.0.1
        gather_facts: False
        tasks:
        - name: test
          local_action: shell exit 2
          register: result
          failed_when: result.rc > 2
        - debug: var=result
  • ignore_errors: yes / ¥¨¥é¡¼¤¬µ¯¤­¤Æ¤â¡¢¥¹¥­¥Ã¥×¤¹¤ë
      - name: Stop services
        service: name="{{ item }}" state=stopped enabled=no
        with_items:
          - cups
        ignore_errors: yes

¿·µ¬¥Õ¥¡¥¤¥ë¤òºî¤ë

  • blockinfile¤ÏÊ£¿ô¹Ô¤â°·¤¨¤ë¡£ansible v2.0°Ê¹ß
  • lineinfile ¤ò»È¤Ã¤Æ¡¢1¹Ô¤À¤±¤Î¥Õ¥¡¥¤¥ë¤òºî¤ë¡£Îã¡§sudoÍÑ¤Ë /etc/sudoers.d/user01 ¤òºî¤ë
    - name: Add user to the sudoers
        lineinfile: dest="/etc/sudoers.d/user01"
          owner=root
          group=root
          mode=0440
          state=present
          create=yes
          regexp="^user01 .*"
          line="user01 ALL=(ALL) NOPASSWD{{':'}} ALL"
          validate='visudo -cf %s'

ÆÃÄê¥æ¡¼¥¶¤À¤±¥ê¥â¡¼¥Èssh¤«¤ésudo¤Ç¤­¤ë¤è¤¦¤Ë

¥Ç¥Õ¥©¥ë¥È¤Ç¤Ïtty¤Ê¤·¤Îssh¤Ç¤Ï¡¢sudo¤Ç¤­¤Ê¤¤¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤¬Â¿¤¤¡£

  • root¥æ¡¼¥¶¤À¤±tty¤Ê¤·¤Ç¤âsudoµö²Ä
    sudo visudo
    --
    Defaults    requiretty
    Defaults:root    !requiretty
    --
  • ÆÃÄê¤Îuser, group¤À¤±¤ò»ØÄꤹ¤ë¾ì¹ç
    • /etc/sudoers.d/<user or group name>
      sudo visudo
      --
      user: !requiretty
      %group: !requiretty
      --

ping module¤ÇÀܳ¥Æ¥¹¥È


¿ÃÊssh´Ä¶­¤Ç¼Â¹Ô

Àܳ¤Ëssh¤ò»È¤¦¤è¤¦¤Ë¤·¡¢ssh¦¤Ç¿ÃÊÀßÄê¤ò¤¹¤ë¡£
¥Û¥¹¥È¤ÎÀܳ¤Ë¤Ï̾Á°¤ò»È¤¦¡£DNS¤ÏÉÕ¤±¤Ê¤¯¤Æ¤âÎɤ¤¡£

  • ¿ÃÊssh¤Ï°Ê²¼¤Î¤è¤¦¤ËÀßÄêºÑ¤ß¤Ç¡¢client.host¤«¤éľÀÜssh¤Çother.host¤ØÀܳ¤Ç¤­¤ë¤â¤Î¤È¤¹¤ë¡£
  • client.host¤«¤é other.host ¤Ë¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤µ¤»¤¿¤¤¾ì¹ç
    • CentOS 6.x, ansible 1.9.4
    • ´Ä¶­ÊÑ¿ô¤Ë ANSIBLE_SSH_ARGS="-F $HOME/.ssh/config" ¤¬¤¢¤ë¤È¡¢ansible.cfg¤è¤ê¤âÍ¥À褵¤ì¤ë¤Î¤Ç¡Öunset ANSIBLE_SSH_ARGS¡×¤Ç̵¸ú¤Ë¤·¤Æ¤ª¤¯
    • ¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤Ë ansible.cfg ¤òÍѰÕ
    • ssh-config
      Host *
        StrictHostKeyChecking=no
        UserKnownHostsFile=/dev/null
        LogLevel ERROR
        ForwardAgent yes
      
      Host gateway.host
        HostName     192.168.1.10
        User         gw_user
        IdentityFile ~/.ssh/id_rsa
        ProxyCommand none
      
      Host other.host
        HostName     192.168.1.11
        User         other_user
        IdentityFile /.ssh/id_rsa
        ProxyCommand ssh -F ssh-config -W %h:%p gateway.host
    • ssh¥³¥Þ¥ó¥É¤ÇÀܳ³Îǧ
      ssh -F ssh-config other.host
    • ansible ping¤ÇÀܳ³Îǧ
      ansible hosts.ini -m ping other.host
    • ssh-agent¤ÇÈëÌ©¸°¤òÊ£¿ôÅÐÏ¿¤Ç¤­¤ë¡£¤½¤Î¾ì¹ç¤Ïssh-config¡ÖIdentityFile¡×¤Î»ØÄê¤ÏÉÔÍפˤʤ롣
      ssh-agent bash
      ssh-add ~/.ssh/id_rsa
  • ¡ÖConnection timed out during banner exchange¡×¥¨¥é¡¼¤¬½Ð¤ë¾ì¹ç¡¢sshÊÂÎóÅÙ¤¬¹â¤¹¤®¤ë¤Î¤ÇÍî¤È¤¹
    # »Ä¤Ã¤Æ¤¤¤ëansible ssh¥×¥í¥»¥¹¤ò½ªÎ»
    killall ansible
    
    vi ansible.cfg
    ----
    [defaults]
    forks = 5
    ----

Ê£¿ô¥µ¡¼¥Ð¤Îrpm¥Ð¡¼¥¸¥ç¥ó¤ÎÄ´ºº¤È¹¹¿·

  • Âоݥۥ¹¥È¤òÎóµó¤·¤¿ÀßÄê¥Õ¥¡¥¤¥ë¤òºî¤ë
    vim stg.hosts
    ----
    [stg:children]
    stg_web
    
    [stg_web]
    stg-web-[01:02].example.com
    
    [stg_web:vars]
    ansible_ssh_user=ec2-user
    ansible_ssh_private_key_file=~/.ssh/stg-web.pem
    ----
  • Îã: bash¤Î¥Ð¡¼¥¸¥ç¥óÄ´ºº¤È¹¹¿·
    • Ä´ºº
      ansible -i stg.hosts -m shell -a 'rpm -qv bash' stg
      
      stg-web-01.example.com | success | rc=0 >>
      bash-4.1.2-9.el6_2.x86_64
      
      stg-web-02.example.com | success | rc=0 >>
      bash-4.1.2-15.el6_5.2.x86_64
    • ¹¹¿·
      ansible --sudo -i stg.hosts -m shell -a 'yum -y update bash' stg

YAMLÃæ¤Ç¥³¥í¥ó(:)¤òÆþ¤ì¤ë¤È Syntax Error

YAMLÃæ¤Ç"foo: bar"¤Îʸ»úÎó¤À¤ÈSyntax Error¤¬È¯À¸¤¹¤ë¡£"foo:bar"¤ÏÌäÂê¤Ê¤¤¡£

  • ansible 1.9.4
  • colon.yml
    - hosts: 127.0.0.1
      vars:
        colon: ':'
      tasks:
    #    - debug: msg="foo: bar" # Syntax Error
        - debug: msg="foo:bar" # OK
        - debug: msg="foo{{ colon }} bar" # OK
        - debug: msg="foo"":"" bar" # OK(1.9) / NG(2.0)
        - debug: msg="foo{{':'}} bar" # OK(1.9) / OK(2.0)
  • ¼Â¹Ô
    ansible-playbook colon.yml
    
    TASK: [debug msg="foo:bar"] ***************************************************
    ok: [127.0.0.1] => {
        "msg": "foo:bar"
    }
    
    TASK: [debug msg="foo{{ colon }} bar"] ****************************************
    ok: [127.0.0.1] => {
        "msg": "foo: bar"
    }
    
    TASK: [debug msg="foo"":"" bar"] **********************************************
    ok: [127.0.0.1] => {
        "msg": "foo\"\":\"\" bar"
    }
    
    TASK: [debug msg="foo: bar"] **************************************************
    ok: [127.0.0.1] => {
        "msg": "foo: bar"
    }

debug : ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤Î½ÐÎÏ

  • debug - Print statements during execution Ansible Documentation ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤǤ­¤ë
    • ʸ»úÎó¤Î²þ¹Ô¤¬¼«Æ°Åª¤Ë¡Ö\n¡×¤Ë¥¨¥¹¥±¡¼¥×¤µ¤ì¤ë¡£
    • ÊÑ¿ô¤Ïjson¤È¤·¤Æ½ÐÎϤµ¤ì¤ë¡£
    • regsiter¤Ç¼èÆÀ¤·¤¿·ë²Ì¤¬JSON¤Î¾ì¹ç¡¢¡Öreg | from_json¡×¤È¤¹¤ë¤ÈåºÎï¤Ëɽ¼¨¤µ¤ì¤ë¡£
  • playbook.yml
    ---
    - hosts: localhost
      connection: local
      gather_facts: false
      become: false
      vars:
      - msg1: |
             first line.
             second line, inventory_hostname: {{ inventory_hostname }}
      - users:
          - user: user1
            email: user1@example.com
          - user: user2
            email: user2@example.com
    
      tasks:
      - debug:
          var: msg1
      - debug:
          msg:
            - first line
            - second line
      - debug:
          msg: "{{ msg1.split('\n') }}"
      - debug:
          msg: "{{ _msg.split('\n') }}"
        with_items: "{{ users }}"
        vars:
          _msg: |
            User: {{ item.user }}
            Email: {{ item.email }}
  • ¼Â¹Ô
    ansible-playbook playbook.yml
    ...
    TASK [debug] *******************************************************************************************************************************************************
    ok: [localhost] => {
        "msg1": "first line.\nsecond line, inventory_hostname: localhost\n"
    }
    
    TASK [debug] *******************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            "first line", 
            "second line"
        ]
    }
    
    TASK [debug] *******************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            "first line.", 
            "second line, inventory_hostname: localhost", 
            ""
        ]
    }
    
    TASK [debug] *******************************************************************************************************************************************************
    ok: [localhost] => (item={u'user': u'user1', u'email': u'user1@example.com'}) => {
        "msg": [
            "User: user1", 
            "Email: user1@example.com", 
            ""
        ]
    }
    ok: [localhost] => (item={u'user': u'user2', u'email': u'user2@example.com'}) => {
        "msg": [
            "User: user2", 
            "Email: user2@example.com", 
            ""
        ]
    }
    ...

tags : ¥¿¥°¤òÉÕ¤±¤Æ¼Â¹Ô¤¹¤ë¥¿¥¹¥¯¤ò»ØÄꤹ¤ë

  • tags.yml
    - hosts: 127.0.0.1
      tasks:
      - name: job1
        debug: msg="job1"
        tags:
        - job1
      - name: job2
        debug: msg="job2"
        tags:
        - job2
      - name: job2
        debug: msg="job3"
        tags:
        - job3
  • ¼Â¹Ô
    # job1, job2¤À¤±¼Â¹Ô
    ansible-playbook -t job1,job2 tags.yml
    
    # job2 °Ê³°¤ò¼Â¹Ô
    ansible-playbook --skip-tags job2 tags.yml

ÆÃÊ̤ʥ¿¥°

Î㤨¤Ðpre_task:¤Ç¥Á¥§¥Ã¥¯½èÍý¤ò¤·¤Æ¤¤¤ë¾ì¹ç¡¢-t ¤Ç¥¿¥°»ØÄꤷ¤¿¾ì¹ç¼Â¹Ô¤µ¤ì¤Ê¤¤¡£

  • Îã: RHEL/CentOS°Ê³°¤ÏÃæ»ß
      pre_tasks:
      - block:
        - name: Validate OS
          fail: msg="Unsupported OS{{':'}} {{ ansible_os_family }}"
          when: ( ansible_os_family not in [ "RedHat" ] )
        tags:
        - always
        - validate

Inventory ¥Õ¥¡¥¤¥ë

  • ini·Á¼°¤Î¾ì¹ç
    • ¥³¥á¥ó¥È¹Ô¤Ï¡¢¹ÔƬ '#'
    • ¥Û¥¹¥È̾ñÂΡ¢¥°¥ë¡¼¥×̾¤ò¥³¥Þ¥ó¥É¤«¤é»ØÄê¤Ç¤­¤ë
    • ¥Û¥¹¥È̾¤¬Ï¢È֤ξì¹ç¤Ï [01:50], [a:f] Åù»ØÄê¤Ç¤­¤ë
    • ¼Â¹Ô»þ¤Ë¤Ï web* Åù¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¤â»È¤¨¤ë

¥Û¥¹¥È¤ò»ØÄꤷ¤Æ¼Â¹Ô

  • Patterns Ansible Documentation
  • ¤¹¤Ù¤Æ
    ansible -i hosts.ini -m ping all
  • Ê£¿ô¤Î¥°¥ë¡¼¥×»ØÄê¡£':'¶èÀÚ¤ê¤ÇÊ£¿ô»ØÄê
    ansible -i hosts.ini -m ping webservers:dbservers
  • webservers¥°¥ë¡¼¥×¤Îweb03¤À¤±½ü³°
    ansible -i hosts.ini -m ping webservers:\!web03

IP¥¢¥É¥ì¥¹¤Ë̾Á°¤òÉÕ¤±¤ë

  • DNS¤òÉÕ¤±¤Æ¤¤¤Ê¤¯¤È¤â̾Á°¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë
vim hosts.ini
----
[web]
web01 ansible_ssh_host=192.168.61.101
----

ansible -i hosts.ini -m ping web01

¥°¥ë¡¼¥×Ëè¤Ë°Û¤Ê¤ëÊÑ¿ô¤ò»È¤¦

  • stg_web ¥°¥ë¡¼¥×¤Ë ssh¥æ¡¼¥¶¡¢ÈëÌ©¸°¤ò»ØÄꤹ¤ë
    [stg_web]
    stb_web_[01:02]
    
    [stg_web:vars]
    ansible_ssh_user=ec2-user
    ansible_ssh_private_key_file=~/.ssh/ec2-user.pem
  • ¥Û¥¹¥È¡¢¥°¥ë¡¼¥×Ëè¤Ë¥Õ¥¡¥¤¥ë¤Ëʬ³ä¤â¤Ç¤­¤ë
    group_vars/stg_web
    host_vars/stb_web_01

¥Û¥¹¥È¤Î¥°¥ë¡¼¥×²½

  • [prod:children] ¤Î¤è¤¦¤Ë ":children"¤òÉÕ¤±¤ë
  • hosts
    [stg:children]
    stg_web
    stg_DB
    
    [prod:children]
    prod_web
    prod_db
    
    [stg_web]
    stg_web_01
    
    [stg_DB]
    stg_db_01
    
    [prod_web]
    prod_web_01
    
    [prod_db]
    prod_db_01
  • stg_web_01 ¥Û¥¹¥ÈñÂΤ˥³¥Þ¥ó¥É¤ò¼Â¹Ô
    ansible stg_web_01 -i hosts -m shell -a 'uname -a'
  • stg_web¥°¥ë¡¼¥×¤Ë¥³¥Þ¥ó¥É¤ò¼Â¹Ô
    ansible stg_web -i hosts -m shell -a 'uname -a'
  • prod¥°¥ë¡¼¥×¤Ëplaybook¤ò¼Â¹Ô
    ansible-playbook -l prod -i hosts playbook.yml
  • ¥ï¥¤¥ë¥É¥«¡¼¥É¤Ç»ØÄê
    ansible-playbook *_web_01 -i hosts playbook.yml

¼Â¹Ô¾ò·ï¤ò»ØÄꤹ¤ë

  • ¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥óËè¤Ë¥¤¥ó¥¹¥È¡¼¥ëÊýË¡¤ò»ØÄꤹ¤ë(ansible_os_family, ansible_distribution)
      tasks:
      # OS¥Õ¥¡¥ß¥ê¡¼Ëè¤Ë»ØÄê
      - include: RedHat.yml
        when: ansible_os_family in [ "RedHat" ]
      - include: Debian.yml
        when: ansible_os_family in [ "Debian" ]
      # ¥Ç¥£¥¹¥È¥ê¥Ó¥å¡¼¥·¥ç¥óËè¤Ë»ØÄê
      - yum: name=ntp state=installed
        when: ansible_distribution in [ 'CentOS', 'Red Hat Enterprise Linux' ]
    
      - apt: name=ntp state=installed
        when: ansible_distribution in [ 'Debian', 'Ubuntu' ]
    
      - service: name=ntpd state=started enabled=yes

ÆÃÄê¹Ô¤Î¥³¥á¥ó¥È¥¢¥¦¥È

  • ansible 1.7.1¤Çưºî³Îǧ
  • /etc/sudoers ¤Î "Defaults requiretty" ¤ò¥³¥á¥ó¥È¥¢¥¦¥È¤·¤¿¤¤¾ì¹ç¡£¤â¤·¹½Ê¸¥¨¥é¡¼¤¬¤¢¤ì¤ÐÃæ»ß¤·¤Æ¤¯¤ì¤ë
    - name: disable Defaults requiretty
      lineinfile: dest=/etc/sudoers regexp='^(Defaults\s+requiretty)$' line='#\1' backrefs=true  validate='visudo -cf %s' backup=true
  • ¥³¥á¥ó¥È¥¢¥¦¥È¤ò¸µ¤ËÌ᤹¡£'#key=value', 'key='¤Î¾ì¹ç¤Ç¤â'key=value'¤ËÃÖ¤­´¹¤¨¤ë
      - lineinfile: dest=test.txt regexp='^#?\s*key=' line='key=value' state=present

źÉÕ¥Õ¥¡¥¤¥ë: fileaws.ec2.list-instance.zip 624·ï [¾ÜºÙ]

¥È¥Ã¥×   ÊÔ½¸ Åà·ë º¹Ê¬ ¥Ð¥Ã¥¯¥¢¥Ã¥× źÉÕ Ê£À½ ̾Á°Êѹ¹ ¥ê¥í¡¼¥É   ¿·µ¬ °ìÍ÷ ñ¸ì¸¡º÷ ºÇ½ª¹¹¿·   ¥Ø¥ë¥×   ºÇ½ª¹¹¿·¤ÎRSS
Last-modified: 2021-01-05 (²Ð) 18:11:59 (60d)