Introduction digitalocean.com What does DO do? Simple, - - PowerPoint PPT Presentation

introduction
SMART_READER_LITE
LIVE PREVIEW

Introduction digitalocean.com What does DO do? Simple, - - PowerPoint PPT Presentation

Introduction digitalocean.com What does DO do? Simple, Developer-focused Cloud Hosting digitalocean.com What are we using Ansible for? digitalocean.com Example Deployment digitalocean.com Example Project Layout digitalocean.com Project


slide-1
SLIDE 1
slide-2
SLIDE 2

digitalocean.com

Introduction

slide-3
SLIDE 3

digitalocean.com

What does DO do?

Simple, Developer-focused Cloud Hosting

slide-4
SLIDE 4

digitalocean.com

What are we using Ansible for?

slide-5
SLIDE 5

digitalocean.com

Example Deployment

slide-6
SLIDE 6

digitalocean.com

Example Project Layout

slide-7
SLIDE 7

digitalocean.com

Project Layout

  • Inventories
  • Local Module Library
  • Group Variables / Host Variables
  • Roles

○ Component roles ○ Project Specific Roles

  • Playbooks

○ Server Templates ○ Cluster Configuration ○ Actions

  • Makefiles
slide-8
SLIDE 8

digitalocean.com

Inventories

  • List hosts (by environment)
  • Define groups
  • Guardrails

ansible-playbook -i inventories/development ...

slide-9
SLIDE 9

digitalocean.com

Inventories

  • List hosts (by environment)
  • Define groups
  • Guardrails

all: children: mysql: children: mysql_managed: hosts: test-mysql-0[1:3].atlantic.com: test-mysql-0[1:6].pacific.com: mysql_unmanaged:

slide-10
SLIDE 10

digitalocean.com

Inventories

  • List hosts (by environment)
  • Define groups
  • Guardrails

ansible-playbook ... --extra-vars="target_env=development” ... Playbook:

  • hosts: mysql:!mysql_unmanaged:&{{ target_env }}

...

slide-11
SLIDE 11

digitalocean.com

Inventories: Constructed Groups

plugin: constructed strict: false groups: dev: inventory_hostname.startswith('dev-')

slide-12
SLIDE 12

digitalocean.com

Inventories: Constructed Groups

plugin: constructed strict: false groups: dev_mysql: (group_names|intersect(['mysql', 'dev']))|length >= 2

slide-13
SLIDE 13

digitalocean.com

Inventories: Ordering

inventories

  • development
  • 10_mysql.yml
  • 90_environment.yml
  • 99_dev_mysql.yml
  • production
  • staging
slide-14
SLIDE 14

digitalocean.com

Variable Order of Precedence

1. command values (eg “-u user”) 2. role defaults 3. inventory file or script group vars 4. inventory group_vars/all 5. playbook group_vars/all 6. inventory group_vars/* 7. playbook group_vars/* 8. inventory file or script host vars 9. inventory host_vars/* 10. playbook host_vars/* 11. host facts / cached set_facts 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 (always win precedence)

slide-15
SLIDE 15

digitalocean.com

Variable Management

  • Role defaults interface with the role
  • Define project level generic variables applicable to all environments

○ playbook group_vars/all ○ playbook group_vars/*

  • Host specific overrides

○ inventory host_vars/*

  • Variables we construct

○ role vars / include_vars / set_facts

  • Functional role variables

○ role (and include_role) params

  • Guardrails

○ extra vars (always win precedence)

slide-16
SLIDE 16

digitalocean.com

Variable Management Example - Defaults

  • ### proxysql install

proxysql_create_image: "{{ global_create_image | default(false) }}" proxysql_download_src: https://github.com/sysown/proxysql/releases/download proxysql_version: 1.4.10 proxysql_mysql_client_version: 5.7 proxysql_user: proxysql proxysql_group: proxysql proxysql_datadir: /var/lib/proxysql proxysql_restart_missing_heartbeats: 10 ... # autocommit proxysql_mysql_autocommit_false_is_transaction: false proxysql_mysql_autocommit_false_not_reusable: false proxysql_mysql_enforce_autocommit_on_reads: false proxysql_mysql_forward_autocommit: false ...

slide-17
SLIDE 17

digitalocean.com

Variable Management Example - Vars

  • ...

### percona required packages proxysql_release: "{{ proxysql_download_src }}/v{{ proxysql_version }}/proxysql_{{ proxysql_version }}-ubuntu18_amd64.deb" ... proxysql_mysql_variables: autocommit_false_is_transaction: variable: "autocommit_false_is_transaction" variable_value: "{{ proxysql_mysql_autocommit_false_is_transaction | to_json }}" autocommit_false_not_reusable: variable: "autocommit_false_not_reusable" variable_value: "{{ proxysql_mysql_autocommit_false_not_reusable | to_json }}" client_found_rows: variable: "client_found_rows" variable_value: "{{ proxysql_mysql_client_found_rows | to_json }}" ...

slide-18
SLIDE 18

digitalocean.com

Variable Management Example - Config

#jinja2: lstrip_blocks: "true" datadir="{{ proxysql_datadir }}" restart_on_missing_heartbeats={{ proxysql_restart_missing_heartbeats }} admin_variables= { {% for config_item in proxysql_admin_variables|dictsort %} {% if config_item.1.variable_value is not none %} {{ config_item.1.variable }}={{ config_item.1.variable_value | to_json }} {% endif %} {% endfor %} } mysql_variables= { {% for config_item in proxysql_mysql_variables|dictsort %} {% if config_item.1.variable_value is not none %} {{ config_item.1.variable }}={{ config_item.1.variable_value | to_json }} {% endif %} {% endfor %} }

slide-19
SLIDE 19

digitalocean.com

Anatomy of a Role

slide-20
SLIDE 20

digitalocean.com

Anatomy of a Role

  • A role should be map to a single unit of functionality that utilise a common set of variables.
  • Roles should be intuitive, and wherever possible mimic a common structure.
  • Role Variable Management

○ Where possible, a [component] role should be generic, and any variables should map to sensible defaults. ○ The interface into role customisation should be via scalar role defaults. ○ Role variables should be used for variables that shouldn't be overridden in normal circumstance, or as syntactic sugar to construct variables internal to the role.

  • A role should have repeatable logic and should avoid logical branching that might be

non-repeatable.

slide-21
SLIDE 21

digitalocean.com

Component Roles

slide-22
SLIDE 22

digitalocean.com

Role Versioning

  • name: role_mysql_proxysql

src: git+ssh://git@github.pacific.com/ansible/role_mysql_proxysql.git version: 1.1.1

slide-23
SLIDE 23

digitalocean.com

Example ProxySQL Deployment

slide-24
SLIDE 24

digitalocean.com

Testing Roles

slide-25
SLIDE 25

digitalocean.com

  • pip install --user molecule

○ pip install --user molecule[ec2] ○ pip install --user molecule[docker]

Molecule

slide-26
SLIDE 26

digitalocean.com

  • create / destroy / list / cleanup
  • prepare
  • dependency
  • login

Molecule Commands

slide-27
SLIDE 27

digitalocean.com

Anatomy of a Role

slide-28
SLIDE 28

digitalocean.com

  • lint
  • syntax
  • idempotence
  • verify
  • check

Molecule Commands

slide-29
SLIDE 29

digitalocean.com

  • converge
  • test
  • side-effects

Molecule Commands

slide-30
SLIDE 30

digitalocean.com

Role Development with Molecule

slide-31
SLIDE 31

digitalocean.com

Testing ProxySQL Example

slide-32
SLIDE 32

digitalocean.com

Molecule Configuration

dependency: name: galaxy driver: name: docker lint: name: yamllint platforms:

  • name: host1

image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu1804}-ansible:latest" command: ${MOLECULE_DOCKER_COMMAND:-""} volumes:

  • /sys/fs/cgroup:/sys/fs/cgroup:ro

privileged: true pre_build_image: true provisioner: name: ansible lint: name: ansible-lint

slide-33
SLIDE 33

digitalocean.com

Molecule Configuration

scenario: name: default converge_sequence: # - dependency

  • create

# - prepare

  • converge

test_sequence:

  • lint
  • destroy

# - dependency

  • syntax
  • create

# - prepare

  • converge
  • idempotence

# - side_effect

  • verify
  • destroy
slide-34
SLIDE 34

digitalocean.com

Molecule Configuration

verifier: name: testinfra env: PYTHONWARNINGS: "ignore:.*U.*mode is deprecated:DeprecationWarning"

  • ptions:

v: 1 lint: name: flake8

slide-35
SLIDE 35

digitalocean.com

Functional Testing with TestInfra

proxysql_file_attributes = ("proxysql_file," "proxysql_file_user," "proxysql_file_group," "proxysql_file_mode") @pytest.mark.parametrize(proxysql_file_attributes, [ ("/root/.my.cnf", None, None, 0o600), ("/etc/proxysql.cnf", "proxysql", "proxysql", 0o644), ]) def test_proxysql_files(host, proxysql_file, proxysql_file_user, proxysql_file_group, proxysql_file_mode): f = host.file(proxysql_file) assert f.exists assert f.is_file if proxysql_file_user: assert f.user == proxysql_file_user if proxysql_file_group: assert f.group == proxysql_file_group if proxysql_file_mode: assert f.mode == proxysql_file_mode

slide-36
SLIDE 36

digitalocean.com

Functional Testing with TestInfra

  • Host fixture

○ host.file ○ host.package ○ host.service ○ host.run

slide-37
SLIDE 37

digitalocean.com

Continuous Integration Pipeline

slide-38
SLIDE 38

digitalocean.com

User Management

slide-39
SLIDE 39

digitalocean.com

  • Deployment and maintenance of individual and Service users
  • Maintain user (dynamic) privileges
  • Manage secrets (securely)
  • Manage across both MySQL and ProxySQL

User Management Story

slide-40
SLIDE 40

digitalocean.com

Manual Worst Case Scenario

sammy sammy@10.21.% sammy@10.22.% sammy@10.23.% sammy@10.24.% sammy@10.25.%

slide-41
SLIDE 41

digitalocean.com

User Management Requirements

  • Deploy user control manifest to Ansible Project Role
  • Generate & Encrypt secrets in Ansible Vault
  • Consistent Delivery across technologies / tenancies / environments
  • Scalable solution
slide-42
SLIDE 42

digitalocean.com

Request > New UMC > Gen Secret > commit/PR > Peer Review > Dry Run > Deploy

New User Deploy Chain

+ >> >> >>

slide-43
SLIDE 43

digitalocean.com

User Control Manifest

sammy_ro: state: present active: true default_shard: atlantic default_hostgroup: swimming_pool default_schema: baby_shark enabled_schemas:

  • baby_shark
  • left_shark

cluster_privs: atlantic: env: dev:

  • '%’

privs:

  • 'baby_shark.*:SELECT'

pacific: env: dev:

  • '%’

privs:

  • 'left_shark.*:SELECT,INSERT,UPDATE,DELETE'
slide-44
SLIDE 44

digitalocean.com

docs.ansible.com/ansible/latest/modules/list_of_database_modules.html?#proxysql proxysql_mysql_users

proxysql_query_rules proxysql_replication_hostgroups proxysql_scheduler

ProxySQL Ansible Module

proxysql_backend_servers proxysql_global_variables proxysql_manage_config

slide-45
SLIDE 45

digitalocean.com

Secret Storage

slide-46
SLIDE 46

digitalocean.com

Secret storage

Ansible Vault

  • Used for shared secrets
  • Fine-grained access control
  • Simple, no dependencies
  • Stored in repo w/ inventory &

playbooks

slide-47
SLIDE 47

digitalocean.com

Ansible Vault

Vault file per environment (dev/stage/production)

  • monitoring_password: ooxalohquaiK8aidai0x

backup_password: ahvowooG9dohfashaCho ansible-vault encrypt $ANSIBLE_VAULT;1.2;AES256;production 3538653766323031333335306239343730333830 6536303737313838633736386164616334383631 3566613638356633666138326338356637636135 3637636231623034380a32633831636239353836 6663346365666465353266633865653963343063 6266656230626232316662386639343233656439

slide-48
SLIDE 48

digitalocean.com

Ansible Vault

sammy_ro: dev: '*100569F51F55F3599CECBCABB9AC59AB29F30283' stage2: '*712E505DB01097F24D1B72509A820E254A525528' production: '*1A0174A0F2F4692917994C19C158F96B1914A53F' sammy_rw: dev: '*0A5B11132F429A38988540A351C60A620DE5BBFA' stage2: '*8B5CCFF05B945DED591D603DF936805476E77837' production: '*C0BF0057A4AC079E7ABE2FEC54DC87A1680B95DC'

Two vault files for all password hashes

  • Passwords distributed to users via LastPass
  • Ansible never needs password, just hash
slide-49
SLIDE 49

digitalocean.com

Ansible Vault

Challenges of ansible-vault approach:

  • Merge conflicts
  • Visibility / discoverability
slide-50
SLIDE 50

digitalocean.com

diffing Ansible vaults $ git diff individuals.yml $ANSIBLE_VAULT;1.1;AES256

  • 6530653733663966316630613666393
  • 6139303463613133633262643034633
  • 3235346162366237366538653361653

... +3938303335363632343730656164356 +3433373263346136653730313636336 +3862633932353039616334303631376

slide-51
SLIDE 51

digitalocean.com

diffing Ansible vaults

.gitconfig: [diff "ansible-vault"] textconv = ansible-vault view cachetextconv = false .gitattributes: individuals.yml diff=ansible-vault

slide-52
SLIDE 52

digitalocean.com

diffing Ansible vaults $ git diff individuals.yml sammy_rw: dev: '*0A5B11132F429A3898854' stage2: '*8B5CCFF05B945DED59837'

  • production: '*C0BF0057A4AC0780B95DC'

+ production: '*B1E8174F9DCE654C25608'

slide-53
SLIDE 53

digitalocean.com

Similar config for merge

/usr/local/bin/ansible-vault-merge .gitconfig: [merge "ansible-vault"] name = ansible-vault merge driver driver = /usr/local/bin/ansible-vault-merge -- %O %A %B %P .gitattributes: individuals.yml diff=ansible-vault merge=ansible-vault

See github.com/building5/ansible-vault-tools

slide-54
SLIDE 54

digitalocean.com

Finding variables in vault

Where is backup_password defined?

  • Variable prefix

○ In vars.yml: backup_password: "{{ vault_backup_password }}" ○ In vault.yml: vault_backup_password: ahvowooG9dohfashaCho

  • git grep:

$ git grep --textconv backup_password vars.yml:backup_password: "{{ vault_backup_password }}" vault.yml:vault_backup_password: ahvowooG9dohfashaCho

slide-55
SLIDE 55

digitalocean.com

Ansible vault passwords

  • Store in local file

○ Exclude from git! ○ Can be executable

  • Can define multiple vault-ids:

[defaults] vault_identity_list = production@vault-keyring-client.py,stage@vault-keyring-client.py

slide-56
SLIDE 56

digitalocean.com

HashiCorp Vault For secrets shared with others

slide-57
SLIDE 57

digitalocean.com

HashiCorp Vault

# Set VAULT_ADDR $ vault login # Set VAULT_TOKEN $ vault write secret/sammy pass=Za6Uoy $ vault read secret/sammy Key Value

  • -- -----

pass Za6Uoy

slide-58
SLIDE 58

digitalocean.com

HashiCorp Vault

  • hashi_vault lookup plugin

○ https://docs.ansible.com/ansible/latest/plugins/lookup/hashi _vault.html

  • Various auth methods

○ We use approle and token

  • Auth secret stored in environment variable or in

Ansible vault

slide-59
SLIDE 59

digitalocean.com

HashiCorp Vault

  • copy:

content: >- {{ lookup('hashi_vault', 'secret=secret/sammy_cert:cert url=https://vault.example.com:8200 auth_method=approle role_id={{ role_id }} secret_id={{ secret_id }} ) }} dest: /etc/nginx/ssl/certificate.crt

slide-60
SLIDE 60

digitalocean.com

HashiCorp Vault

Why not HashiCorp Vault for everything?

  • External dependency
  • Changing policies requires another commit and

approval by another team

slide-61
SLIDE 61

digitalocean.com

Ansible Performance

slide-62
SLIDE 62

digitalocean.com

Performance Visibility

ansible.cfg callback_whitelist = profile_tasks, profile_roles, timer stdout_callback = actionable

slide-63
SLIDE 63

digitalocean.com

Performance

  • SSH optimisations
  • Gathering Facts
  • Play Logic
slide-64
SLIDE 64

digitalocean.com

Performance

  • SSH optimisations
  • Gathering Facts
  • Play Logic
slide-65
SLIDE 65

digitalocean.com

A mitogen is a chemical substance, usually a protein, that induces a cell to begin cell division

Mitogen for Ansible

An Ansible Plugin that replaces the use of SSH

slide-66
SLIDE 66

digitalocean.com

Mitogen for Ansible

  • Redesigned UNIX connection layer and module runtime for Ansible
  • Easy installation, minimal configuration
  • Immediate gains (immediately) 1% - 7% improvement in run duration

*unless you have and it didn’t help (Windows, Networking equipment)

slide-67
SLIDE 67

digitalocean.com

Performance Challenges

  • Loopy Loops
slide-68
SLIDE 68

digitalocean.com

Module Override

slide-69
SLIDE 69

digitalocean.com

With pushdown Without mitogen

slide-70
SLIDE 70

digitalocean.com

With pushdown With mitogen

slide-71
SLIDE 71

digitalocean.com

Without pushdown Without mitogen

slide-72
SLIDE 72

digitalocean.com

Without pushdown With mitogen

slide-73
SLIDE 73

digitalocean.com

Mitogen SSH Only Standard mysql_user 4m 23s 10m 6s Patched mysql_user 7m 33s 8m 19s

slide-74
SLIDE 74

We’re Hiring!

https://www.digitalocean.com/careers