Differences
This shows you the differences between two versions of the page.
linux_wiki:ansible [2018/07/21 00:34] billdozor [Playbook Directory Structure] |
linux_wiki:ansible [2019/05/25 23:50] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Ansible ====== | ||
- | |||
- | **General Information** | ||
- | |||
- | Ansible is a tool for performing remote tasks on systems. (either ad-hoc or via " | ||
- | |||
- | You will need to use ansible as a user that has ssh keys setup on systems so you are not prompted for passwords during parallel command operations. | ||
- | |||
- | \\ | ||
- | If you already have Ansible installed/ | ||
- | |||
- | **Checklist** | ||
- | * Distro(s): Any | ||
- | |||
- | ---- | ||
- | |||
- | ====== Install ====== | ||
- | |||
- | Ansible comes in many distributions repos already. | ||
- | |||
- | CentOS 7 | ||
- | <code bash> | ||
- | yum install ansible | ||
- | </ | ||
- | |||
- | ---- | ||
- | |||
- | ====== Configure ====== | ||
- | |||
- | Main Ansible config file | ||
- | * / | ||
- | * Edit this file to point Ansible to your inventory files. | ||
- | |||
- | ===== Repo Controlled ===== | ||
- | |||
- | It is highly recommended to put Ansible playbooks, roles, and inventory into version control. (Example: git or svn) | ||
- | |||
- | One suggested directory structure/ | ||
- | * Shared, read-only/ | ||
- | * /ansible/ | ||
- | * Each system administrator would then clone a copy of the repo into their home directory for local changes/ | ||
- | * Have an automated job sync the shared location every so often. | ||
- | * Example: Have cron perform a git pull for /ansible/ every 30 mins. | ||
- | |||
- | \\ | ||
- | Model content tree under /ansible/ after [[http:// | ||
- | |||
- | ---- | ||
- | |||
- | ===== Inventory ===== | ||
- | |||
- | Inventory setup is the most important configure task. | ||
- | |||
- | \\ | ||
- | In order for Ansible to send commands to systems, they must be listed in inventory. | ||
- | |||
- | \\ | ||
- | Suggested directory structure (after [[http:// | ||
- | * Production Inventory: / | ||
- | * Systest Inventory: / | ||
- | * Development Inventory: / | ||
- | |||
- | ==== Auto Generated Inventory ==== | ||
- | |||
- | You will not want to introduce a manual inventory process. | ||
- | |||
- | Suggested workflow for auto generating your inventory files: | ||
- | |||
- | * Cron Job to execute inventory generation script: / | ||
- | * Example: Executes every 30 minutes. (*/30 * * * *) | ||
- | |||
- | * Script that generates inventory files: / | ||
- | * Source: The script should contact some sort of system via APIs that all newly deployed systems automatically register to. (Such as Spacewalk, Foreman/ | ||
- | |||
- | * Target directory for auto generated inventory files: / | ||
- | * Files are generated here and any changes committed to the repo (svn/ | ||
- | * Example: If there were committed changes, a repo sync job will pick them up and place them in / | ||
- | |||
- | * Example User Accounts Involved | ||
- | * autorepo -> Repo user account with read/write access to an ansible repo for inventory file changes. | ||
- | * autoadmin -> API user account for contacting the inventory source. | ||
- | |||
- | ---- | ||
- | |||
- | ====== Ansible Commands ====== | ||
- | |||
- | Examples of Ansible commands. | ||
- | |||
- | **Note: All host-patterns check the inventory files for matches ONLY. If a system is not in the inventory file(s), Ansible can't send a command to it.** | ||
- | |||
- | General Ansible command syntax< | ||
- | * see 'man ansible' | ||
- | |||
- | ---- | ||
- | |||
- | ===== List Hosts ===== | ||
- | |||
- | Listing hosts matched by the given pattern and do nothing else. | ||
- | |||
- | \\ | ||
- | List hosts in the webservers_nginx group from dev inventory< | ||
- | |||
- | \\ | ||
- | List all hosts from dev inventory< | ||
- | |||
- | \\ | ||
- | List all hosts in the " | ||
- | |||
- | \\ | ||
- | List all hosts matching " | ||
- | |||
- | ---- | ||
- | |||
- | ===== Test Connection ===== | ||
- | |||
- | The module ' | ||
- | |||
- | \\ | ||
- | Test connection to webservers_nginx in dev inventory only< | ||
- | |||
- | \\ | ||
- | Test connection to all systems in dev inventory< | ||
- | |||
- | \\ | ||
- | Test connection to **all** webservers_nginx (**from any inventory**)< | ||
- | |||
- | \\ | ||
- | Test connection to all systems in the " | ||
- | |||
- | \\ | ||
- | Test connection to systems matching a pattern (**from any inventory**)< | ||
- | |||
- | \\ | ||
- | Test connection to all systems (**from any inventory**)< | ||
- | |||
- | ---- | ||
- | |||
- | ===== Ad-Hoc Commands ===== | ||
- | |||
- | Ad-hoc commands are for one off commands that are not saved in a playbook. | ||
- | |||
- | * Ad-hoc Intro: http:// | ||
- | * Module Index: http:// | ||
- | |||
- | ---- | ||
- | |||
- | ==== Modules: Command and Shell ==== | ||
- | |||
- | If no module is specified, the " | ||
- | * The command module can execute basic commands, **but cannot do shell specific functions** such as piping and redirects | ||
- | * If you need that type of shell functionality, | ||
- | |||
- | \\ | ||
- | Check uptime of the group ' | ||
- | |||
- | \\ | ||
- | Check uptime of all systems in dev<code bash> | ||
- | |||
- | \\ | ||
- | Check uptime of the group ' | ||
- | |||
- | \\ | ||
- | Check the last 10 lines in / | ||
- | * -b => or ' | ||
- | |||
- | Equivalent command as the above< | ||
- | |||
- | \\ | ||
- | Piping example; the shell module must be specified< | ||
- | |||
- | ---- | ||
- | |||
- | ==== Modules: Copy and File ==== | ||
- | |||
- | Transferring files over scp using Ansible to multiple servers at once. | ||
- | |||
- | \\ | ||
- | Copy a local file (src=) to all systems in the ' | ||
- | |||
- | \\ | ||
- | Set a file's ownership and permissions< | ||
- | |||
- | \\ | ||
- | Remove a file< | ||
- | * This same command will recursively delete if a directory is the target | ||
- | |||
- | ---- | ||
- | |||
- | ==== Modules: Packages ==== | ||
- | |||
- | Managing packages with Ansible. | ||
- | |||
- | \\ | ||
- | Ensure a package is installed, do not update the package if it is installed< | ||
- | |||
- | \\ | ||
- | Ensure package is the latest version (update if not)< | ||
- | |||
- | \\ | ||
- | Ensure package is not installed (remove if it is)<code bash> | ||
- | |||
- | ---- | ||
- | |||
- | ==== Modules: Services ==== | ||
- | |||
- | Managing system services with Ansible. | ||
- | |||
- | Compatible with SysV and Systemd. | ||
- | * **Note**: For systemd specific commands such as " | ||
- | |||
- | \\ | ||
- | Ensure httpd is started (start if not)< | ||
- | |||
- | \\ | ||
- | Restart a service< | ||
- | |||
- | \\ | ||
- | Ensure a service is stopped< | ||
- | |||
- | ---- | ||
- | |||
- | ====== Ansible Playbooks ====== | ||
- | |||
- | " | ||
- | |||
- | More Details: http:// | ||
- | |||
- | ---- | ||
- | |||
- | ===== Playbook Directory Structure ===== | ||
- | |||
- | Playbooks should be repo controlled. | ||
- | |||
- | Following the examples on this page: | ||
- | * / | ||
- | |||
- | \\ | ||
- | **Playbooks map ansible groups to roles** | ||
- | * Example playbook< | ||
- | # Description: | ||
- | # Last Updated: 2018-04-08 | ||
- | # Recent Changes: | ||
- | |||
- | # hosts: group_name or ' | ||
- | - hosts: webservers_nginx | ||
- | |||
- | # roles: located in ../roles/ | ||
- | roles: | ||
- | # role: role to assign to hosts, tags: tag(s) to give entire role | ||
- | - { role: webservers-nginx, | ||
- | |||
- | # Gather host facts for this playbook | ||
- | gather_facts: | ||
- | * All systems in the ansible group " | ||
- | * webservers-nginx | ||
- | |||
- | * When a playbook is executed, all tasks in the assigned roles are run (unless only specific tasks/ | ||
- | |||
- | \\ | ||
- | **Gather a subset of facts** | ||
- | |||
- | If you do need to gather facts, consider gathering a subset of facts instead of everything in order to keep the fact collection fast. | ||
- | * Example: Collect only the ansible_distribution facts< | ||
- | gather_facts: | ||
- | # Gather only ansible_distribution info (OS attributes) | ||
- | gather_subset: | ||
- | - ' | ||
- | - ' | ||
- | - ' | ||
- | * Facts returned by the above subset< | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | * You can test your subset commands like this | ||
- | * ad-hoc< | ||
- | |||
- | \\ | ||
- | **See the Roles section** for what happens next. | ||
- | |||
- | ---- | ||
- | |||
- | ===== Roles Directory Structure ===== | ||
- | |||
- | Roles contain all of the tasks that will be run when a playbook is executed against it. | ||
- | |||
- | \\ | ||
- | Roles should be repo controlled. Top level directory example is: | ||
- | * / | ||
- | |||
- | An example role called " | ||
- | * / | ||
- | |||
- | The contents of a role directory are: | ||
- | * files | ||
- | * Files to be used with the ' | ||
- | |||
- | * handlers | ||
- | * Actions that are only executed when certain tasks report changes. Requires ' | ||
- | |||
- | * meta | ||
- | * Role dependencies. Requires ' | ||
- | |||
- | * **tasks** | ||
- | * Tasks/ | ||
- | |||
- | * templates | ||
- | * Files to be used with the ' | ||
- | |||
- | * vars | ||
- | * Variables associated with the role. Requires ' | ||
- | |||
- | ---- | ||
- | |||
- | ===== Playbook/ | ||
- | |||
- | How to create a new playbook and role. | ||
- | * Playbook: Maps Ansible group(s) to role(s) | ||
- | * Role: Defines tasks to complete against the hosts | ||
- | |||
- | External References | ||
- | * Intro to Playbooks: http:// | ||
- | * Intro to modules: http:// | ||
- | * All modules index: http:// | ||
- | |||
- | - Navigate to your local copy of the version controlled ansible repo. Example:< | ||
- | - Update your local copy of the version controlled ansible repo to the latest version< | ||
- | git pull | ||
- | |||
- | #svn | ||
- | svn update</ | ||
- | - **New Role** | ||
- | - Navigate to the roles directory, then copy your role template directory to a new name< | ||
- | cp -R template-role/ | ||
- | - Modify the role's files as needed to create tasks, files, handlers, etc. | ||
- | - Download zip archive of an {{ : | ||
- | - **New Playbook** | ||
- | - Navigate to the playbooks directory< | ||
- | - Copy your playbook template to a new playbook yaml file.< | ||
- | - Playbook Template< | ||
- | # Description: | ||
- | # Last Updated: 2018-03-15 | ||
- | # Recent Changes: | ||
- | |||
- | # hosts: group_name or ' | ||
- | - hosts: | ||
- | - group_name_here | ||
- | |||
- | # roles: located in ../roles/ | ||
- | roles: | ||
- | # role: role to assign to hosts, tags: tag(s) to give entire role | ||
- | - { role: role-name, tags: tag-name } | ||
- | |||
- | # Do not gather host facts for this playbook (comment out/remove if you need facts) | ||
- | gather_facts: | ||
- | </ | ||
- | - Edit the new playbook< | ||
- | - hosts: my_ansible_group | ||
- | roles: | ||
- | - { role: my-new-role, | ||
- | - In the above example, the playbook " | ||
- | - The tag can be anything, but keeping it the same as the role name is useful if you want to limit the execution of a playbook to a specific role using the " | ||
- | - Tags are inherited at all tasks below it. | ||
- | - When the playbook is executed, the tasks defined in the role will be executed against the group | ||
- | - **Test Playbook** | ||
- | - See the next section for details on testing the playbook before committing changes to a repo. | ||
- | |||
- | ---- | ||
- | |||
- | ==== Playbook Testing ==== | ||
- | |||
- | Test your playbook before committing it to a repo. | ||
- | |||
- | * Add these functions to your shell' | ||
- | #zsh = ~/.zshrc | ||
- | |||
- | # Enable Ansible test environment | ||
- | ansible_local_enable(){ | ||
- | export ANSIBLE_INVENTORY=" | ||
- | export ANSIBLE_ROLES_PATH=" | ||
- | echo -e " | ||
- | env | grep ANSIBLE | ||
- | } | ||
- | # Disable Ansible test environment | ||
- | ansible_local_disable(){ | ||
- | unset ANSIBLE_INVENTORY | ||
- | unset ANSIBLE_ROLES_PATH | ||
- | echo -e " | ||
- | env | grep ANSIBLE | ||
- | }</ | ||
- | * Source the file< | ||
- | source ~/.bashrc | ||
- | |||
- | #zsh | ||
- | source ~/ | ||
- | * Enable local variables< | ||
- | * Test playbook locally | ||
- | * Syntax check< | ||
- | * List tasks< | ||
- | * Run against a test system< | ||
- | * Tests successful, disable local variables< | ||
- | * Commit playbook/ | ||
- | |||
- | ---- | ||
- | |||
- | ===== Playbook Commands ===== | ||
- | |||
- | Different methods to run playbooks. | ||
- | |||
- | \\ | ||
- | **WARNING**: | ||
- | |||
- | \\ | ||
- | **NOTE**: If you need to use group_vars per inventory type (dev/ | ||
- | |||
- | ---- | ||
- | |||
- | ==== Playbook Commands: Syntax Check ==== | ||
- | |||
- | After creating a playbook, it is useful to check the syntax before running it to catch obvious errors. | ||
- | |||
- | Run a syntax check (will NOT execute the playbook)< | ||
- | |||
- | ---- | ||
- | |||
- | ==== Playbook Commands: Aliases ==== | ||
- | |||
- | Playbook commands can get rather long, some useful aliases to shorten them. | ||
- | |||
- | Put in your ~/.bashrc or ~/.zshrc file | ||
- | <code bash># Ansible aliases | ||
- | alias apd=' | ||
- | alias apt=' | ||
- | alias app=' | ||
- | </ | ||
- | |||
- | \\ | ||
- | Additionally, | ||
- | <code bash> | ||
- | ln -s / | ||
- | </ | ||
- | |||
- | \\ | ||
- | Now, your playbook commands can look like this | ||
- | <code bash> | ||
- | # Dev inventory | ||
- | apd / | ||
- | |||
- | # Test inventory | ||
- | apt / | ||
- | |||
- | # Prod inventory | ||
- | app / | ||
- | </ | ||
- | * limits, tags, etc can also be appended as normal. | ||
- | |||
- | ---- | ||
- | |||
- | ==== Playbook Commands: List ==== | ||
- | |||
- | Preparation/ | ||
- | |||
- | \\ | ||
- | **List** what hosts the playbook will run against (**from dev inventory**)< | ||
- | * -i or --inventory -> Path to the inventory (alternative is a comma separated list of hosts or single hostname with a trailing comma) | ||
- | |||
- | \\ | ||
- | **List** what tasks the playbook will execute (**from dev inventory**)< | ||
- | |||
- | ---- | ||
- | |||
- | ==== Playbook Commands: Run ==== | ||
- | |||
- | Commands to actually run a playbook. You SHOULD do the list commands first to make sure what you are about to run is expected. | ||
- | * The list commands (--list-hosts and --list-tasks) can be appended to any of the following commands to check them first before running. | ||
- | |||
- | \\ | ||
- | **Run playbook (dev env; all in group)** against all system groups defined in playbook **from dev inventory** using sudo for privilege escalation< | ||
- | * -b or --become -> Use privilege escalation (default of sudo) | ||
- | |||
- | \\ | ||
- | **Run playbook (dev env; all in group; only configure)** against all groups defined in playbook **from dev inventory** using sudo for privilege escalation, only execute actions with the matched tags " | ||
- | * --tags configure -> Only execute tasks in the playbook that have been tagged " | ||
- | * roles, import_tasks, | ||
- | |||
- | \\ | ||
- | **Run playbook (dev env; range of systems)** against all groups defined in playbook **from dev inventory** using sudo for privilege escalation, further limit to hosts web01-05"< | ||
- | * --limit " | ||
- | |||
- | \\ | ||
- | **Run playbook (dev env; one system)** against all groups defined in playbook **from dev inventory**, | ||
- | |||
- | ---- | ||