devops:ansible
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
devops:ansible [2023/11/01 07:15] – removed - external edit (Unknown date) 127.0.0.1 | devops:ansible [2023/11/01 07:15] (current) – ↷ Page moved from camunda:devops:ansible to devops:ansible skipidar | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Ansible ====== | ||
+ | |||
+ | === Experimenting environment === | ||
+ | |||
+ | Here is an environment for experimenting: | ||
+ | |||
+ | < | ||
+ | https:// | ||
+ | </ | ||
+ | |||
+ | |||
+ | === Configuration of ansible === | ||
+ | |||
+ | Add hosts here: **/ | ||
+ | < | ||
+ | local ansible_host=127.0.0.1 | ||
+ | |||
+ | slave ansible_host=10.0.0.11 ansible_user=vagrant ansible_ssh_private_key_file=/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | Add the ssh **private-key** in openSSH form here, which will be used by ansible | ||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Example: | ||
+ | < | ||
+ | -----BEGIN RSA PRIVATE KEY----- | ||
+ | MIIEoQIBAAKCAQEAxQRyoCBSijfLHpuQKR+0/ | ||
+ | zRr/ | ||
+ | NylHAm4+ATuU68agYOVTPycY19DXaAgQBqtJlRVHhMB9ZJ+ugAdKINjpW// | ||
+ | HisH6GYbA5zWugNHmyfNLdYdJcdozTUprHFkRz6E2HyCxEuhurbcHtsEEfgCd93f | ||
+ | bHn2utRg24VIRFNZF24C6N/ | ||
+ | itgBbyVqIID++XwxNCl8wAjUWFEHvA+xyf4ZywIBJQKCAQB/ | ||
+ | RP/ | ||
+ | RN+3s7DyHK/ | ||
+ | Dj2RIo9BWkN/ | ||
+ | 315KRjO9TgH3ORz43I62rFwSiEaP2VDWhG8nOiMp8wONhaES41uZ05pGA6F9cAdO | ||
+ | DvPpK4QcwZ8KZdkJQJBhXu3UvfIS1C6AZ7b08lf+ifU5shqZMerVPxY6RC6FzSRV | ||
+ | rs7tAoGBAPSrlQjDhHcCLFd/ | ||
+ | 4v3W24dnZb51xhk4SOFOXC2lxR0q56MxVsZwl+5vRJEt7wlVYy4yK8JH4r1shDZG | ||
+ | / | ||
+ | E8s5JlaUSIDws5f7axrOGy8lwWNzDtnHmVqoX/ | ||
+ | ej9lU+eqaYWfPbLo+LnrIadaMPxQAG7DS0PILoPJAVgZl3PGUfjvk0kEH03YE8cj | ||
+ | OiRpefS9rbp2z1HtYQ30iQZzdmS+Q2c9ptqVAoGALkn5md/ | ||
+ | C91g09pVR0ielitUsiN9/ | ||
+ | XOTeeTelMDkfYqFzoPS8K6y8May/ | ||
+ | s+19/ | ||
+ | +hWjc8NUocb5sHVo1r2xkO9VcQgqoDBFEqbFdFUs1oWVDll4BN5FWjElXpKYfDQ1 | ||
+ | tINbL1Nvicq4F4keMvXKQiUoN073iaBGvLBE5D6OloE0xDmdMjA5gIz2kaa0Rxh8 | ||
+ | egkCgYB7QihLpX+8sDAyENjs5ylJgsOV8N6e2Twhqjy1B0j0SZoXToOB/ | ||
+ | BZOsSCeSn4Qb+N8aX0EFXuUHCZVXsYnv8fpiZEYReXNij0mi5MbYby8eY24V9iuO | ||
+ | Xixof23aO5mPprsvg/ | ||
+ | -----END RSA PRIVATE KEY----- | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | Add the ssh **public-key** in openSSH form here, which will be used by ansible | ||
+ | < | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | Example: | ||
+ | < | ||
+ | ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAxQRyoCBSijfLHpuQKR+0/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | Configure the ssh-key permissions. Ansible will check them and if someone else can access the keys decine the usage of the key. | ||
+ | < | ||
+ | chmod -R 700 / | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Debugging the connection ==== | ||
+ | |||
+ | Try connecting to the server using ssh | ||
+ | < | ||
+ | ssh ec2-user@48.114.120.127 -p 22 -i / | ||
+ | </ | ||
+ | |||
+ | Try using the **-vvvv** parameter. | ||
+ | < | ||
+ | ansible slave -vvvv -m ping | ||
+ | </ | ||
+ | ==== Introduction ==== | ||
+ | Here is a good introduction: | ||
+ | https:// | ||
+ | |||
+ | |||
+ | ==== Commands ==== | ||
+ | |||
+ | Send a command to all ansible hosts | ||
+ | < | ||
+ | ansible all -m ping -u " | ||
+ | </ | ||
+ | |||
+ | |||
+ | Send a command to slave only | ||
+ | < | ||
+ | ansible slave -m ping -u " | ||
+ | </ | ||
+ | |||
+ | |||
+ | Execute a shell command remotely. \\ | ||
+ | The module used here is shell - it is not that the shell is executed remotely, but using the argument **-m** an ansible **module** is used. | ||
+ | The **-a** flag is used to pass any **arguments** to the module | ||
+ | < | ||
+ | ansible all -s -m shell -a ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Playbook ==== | ||
+ | |||
+ | Hierarchy: | ||
+ | |||
+ | * Playbook | ||
+ | * Tasks - declarative describtion of as to be state | ||
+ | * Handlers - secondary, after tasks | ||
+ | |||
+ | === Tasks === | ||
+ | |||
+ | Create the following playbook in a file addmycowsay.yaml | ||
+ | < | ||
+ | --- | ||
+ | - hosts: local | ||
+ | tasks: | ||
+ | - name: install cowsay | ||
+ | apt: pkg=cowsay state=installed update_cache=true | ||
+ | </ | ||
+ | |||
+ | And execute the playbook | ||
+ | < | ||
+ | ansible-playbook addmycowsay.yaml | ||
+ | </ | ||
+ | |||
+ | So the syntax is the following: | ||
+ | < | ||
+ | --- | ||
+ | - hosts: < | ||
+ | tasks: | ||
+ | - name: < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | |||
+ | === Handlers === | ||
+ | |||
+ | < | ||
+ | --- | ||
+ | - hosts: local | ||
+ | tasks: | ||
+ | - name: Install Nginx | ||
+ | apt: pkg=nginx state=installed update_cache=true | ||
+ | | ||
+ | - Start Nginx | ||
+ | |||
+ | handlers: | ||
+ | - name: Start Nginx | ||
+ | | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Become non root ==== | ||
+ | |||
+ | To allow becoming non priviledged user to things must be set to True in **/ | ||
+ | |||
+ | **Important**: | ||
+ | |||
+ | < | ||
+ | allow_world_readable_tmpfiles = True | ||
+ | pipelining = True | ||
+ | </ | ||
+ | |||
+ | To uncomment them programmatically do | ||
+ | |||
+ | < | ||
+ | sed -i ' | ||
+ | sed -i ' | ||
+ | </ | ||
+ | |||
+ | Here is an example playbook, which shows how to become the user " | ||
+ | < | ||
+ | # Setup the infrastructure for Faktura | ||
+ | - hosts: " | ||
+ | become: yes | ||
+ | become_method: | ||
+ | become_user: | ||
+ | vars: | ||
+ | allow_world_readable_tmpfiles: | ||
+ | tasks: | ||
+ | |||
+ | |||
+ | # an error is thorwn when becoming unpriviledged user. Hence use sudo | ||
+ | - name: install oracle client | ||
+ | shell: | | ||
+ | whoami | ||
+ | args: | ||
+ | chdir: /tmp/client | ||
+ | environment: | ||
+ | DISTRIB: /tmp/client | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Remove Old SSH Key Fingerprint ==== | ||
+ | |||
+ | When connecting to an unknown host - your are asked whether to trust it. | ||
+ | Linux then stores a fingerprint of the key associated with the host. | ||
+ | |||
+ | If the host then changes, e.g. because of the replacement of the EC2 machine behind the host - connection will fail. | ||
+ | |||
+ | To remove the fingerprint do: | ||
+ | < | ||
+ | ssh-keygen -R ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Extra vars alias arguments ==== | ||
+ | |||
+ | Pass external variables as arguments to the playbook, to e.g. define hosts outside of the playbook. | ||
+ | |||
+ | < | ||
+ | ansible-playbook myplaybook.yaml --extra-vars " | ||
+ | </ | ||
+ | |||
+ | And here is myplaybook: | ||
+ | < | ||
+ | - hosts: "{{ host }}" | ||
+ | become: true | ||
+ | become_method: | ||
+ | become_user: | ||
+ | | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Ansible behind proxy ==== | ||
+ | |||
+ | If you configure the Hosts to use corkscrew, then ansible will be able to reach the machines: | ||
+ | |||
+ | Open / | ||
+ | < | ||
+ | Host * | ||
+ | ProxyCommand corkscrew 194.138.0.33 9400 %h %p | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Galaxy ==== | ||
+ | You can use the galaxy (https:// | ||
+ | |||
+ | A role " | ||
+ | < | ||
+ | ansible-galaxy install cmacrae.sensu | ||
+ | </ | ||
+ | |||
+ | After that you can embed the role into your playbooks: | ||
+ | |||
+ | < | ||
+ | --- | ||
+ | - name: Install sensu | ||
+ | hosts: slave | ||
+ | become: true | ||
+ | roles: | ||
+ | - { role: cmacrae.sensu, | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== MODULE FAILURE - rc 127 ==== | ||
+ | |||
+ | When ssh works, but the ping fails with | ||
+ | < | ||
+ | $ ansible slaves -m ping -vvvv | ||
+ | |||
+ | ansible 2.5.0 | ||
+ | config file = / | ||
+ | configured module search path = [u'/ | ||
+ | ansible python module location = / | ||
+ | executable location = / | ||
+ | python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609] | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Then it will help to ssh to the remote host and install python | ||
+ | < | ||
+ | ssh 34.242.178.166 -l ubuntu -i / | ||
+ | ubuntu@34.242.178.166: | ||
+ | </ | ||
+ | |||
+ | Check https:// | ||
+ | |||
+ | |||
+ | ==== AWX installation ==== | ||
+ | The UI, which enables team management and delegation is available as the AWX project | ||
+ | https:// | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Importing and Including ==== | ||
+ | |||
+ | |include*|Is done evaluated at runtime| | ||
+ | |Import*|Is done at compile time. PREFER THAT.| | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | === import_tasks === | ||
+ | Can be used, to extract equal steps you want to reuse in a separate file. | ||
+ | |||
+ | |import_tasks*| Allows passing variables. Requires the imported file to have only tasks, no " | ||
+ | |||
+ | |||
+ | Usecase: requirements for a Renderer/ | ||
+ | |||
+ | common_requirements.yaml | ||
+ | It is important, that you dont have the header here. Only tasks | ||
+ | < | ||
+ | |||
+ | - name: Creates product configuration file | ||
+ | file: | ||
+ | path: / | ||
+ | state: touch | ||
+ | owner: ubuntu | ||
+ | group: ubuntu | ||
+ | mode: 0700 | ||
+ | |||
+ | - name: product config content | ||
+ | copy: | ||
+ | dest: "/ | ||
+ | content: | | ||
+ | Acquire:: | ||
+ | Verify-Peer " | ||
+ | Verify-Host " | ||
+ | |||
+ | SslCert "/ | ||
+ | SslKey "/ | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | Renderer: | ||
+ | < | ||
+ | --- | ||
+ | - hosts: "{{ host }}" | ||
+ | become: true | ||
+ | become_method: | ||
+ | become_user: | ||
+ | tasks: | ||
+ | |||
+ | - name: Install product requirements | ||
+ | import_tasks: | ||
+ | vars: | ||
+ | host: aws | ||
+ | |||
+ | - name: Install renderer | ||
+ | become: true | ||
+ | apt: product_renderer | ||
+ | </ | ||
+ | |||
+ | Viewer: | ||
+ | < | ||
+ | --- | ||
+ | - hosts: "{{ host }}" | ||
+ | become: true | ||
+ | become_method: | ||
+ | become_user: | ||
+ | tasks: | ||
+ | |||
+ | - name: Install product requirements | ||
+ | import_tasks: | ||
+ | vars: | ||
+ | host: aws | ||
+ | |||
+ | - name: Install VIEWER, reusing the tasks | ||
+ | become: true | ||
+ | apt: product_viewer | ||
+ | </ | ||
+ | |||
+ | |||
+ | === import_playbook === | ||
+ | |||
+ | Unfortunately lacks the possibility to pass in variables. | ||
+ | Which makes it unusable | ||
+ | |||
+ | |||
+ | |||
+ | ==== Read remote files ==== | ||
+ | To read remote file do use slurp | ||
+ | |||
+ | |||
+ | < | ||
+ | - name: set facts | ||
+ | set_fact: | ||
+ | dest_timestamp: | ||
+ | | ||
+ | | ||
+ | - name: Slurp timestamp file | ||
+ | slurp: | ||
+ | src: "{{ dest_timestamp }}" | ||
+ | register: slurpfile | ||
+ | |||
+ | - name: set the timestamp fact | ||
+ | set_fact: | ||
+ | timestamp: "{{ slurpfile[' | ||
+ | |||
+ | - name: timestamp variable | ||
+ | debug: msg=" | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Execute a shell script, as a user with a valid environment ==== | ||
+ | Sometimes you face the issues, that the environment variables defined by some tool, installed for a special user - are not defined, when you execute the tool. | ||
+ | |||
+ | To execute some installed software in a valid environment, | ||
+ | with / | ||
+ | with / | ||
+ | etc | ||
+ | |||
+ | use the following approach. | ||
+ | |||
+ | < | ||
+ | # unfortunately the environment defined by tool in / | ||
+ | - name: processing step | ||
+ | shell: | ||
+ | sudo -iu ubuntu yourtool.sh | ||
+ | args: | ||
+ | executable: /bin/bash | ||
+ | |||
+ | |||
+ | -i [command] | ||
+ | The -i (simulate initial login) option runs the shell specified in the passwd(5) entry of the target user as a login shell. | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | </ | ||
+ | See https:// | ||
+ | |||
+ | UNfortunately the aproach with become_user - does not have the same result | ||
+ | |||