mirror of
https://gitea.com/mcereda/oam.git
synced 2026-02-09 05:44:23 +00:00
chore(ansible): save outcomes of working with certificates, improve readability
This commit is contained in:
@@ -60,3 +60,9 @@ ansible-vault view 'ssh.key.pub' --vault-password-file 'password_file.txt'
|
||||
ansible-vault edit 'ssh.key.pub'
|
||||
ANSIBLE_VAULT_PASSWORD_FILE='password_file.txt' ansible-vault decrypt --output '.ssh/id_rsa' 'ssh.key'
|
||||
diff 'some_role/files/ssh.key.plain' <(ansible-vault view --vault-password-file 'password_file.txt' 'some_role/files/ssh.key.enc')
|
||||
|
||||
# List available 'lookup' plugins.
|
||||
ansible-doc -t 'lookup' -l
|
||||
|
||||
# Show plugin-specific docs and examples.
|
||||
ansible-doc -t 'lookup' 'fileglob'
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Debug tasks
|
||||
block:
|
||||
- ansible.builtin.debug:
|
||||
msg: I always display!
|
||||
- ansible.builtin.debug:
|
||||
msg: I only display with 'ansible-playbook -vvv' or with more 'v's
|
||||
verbosity: 3
|
||||
- debugger: on_failed
|
||||
ansible.builtin.fail:
|
||||
msg: Manual, enforced failure
|
||||
# print all variables at this point => p task_vars
|
||||
# continue => c
|
||||
# abort and quit => q
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Retry tasks
|
||||
ansible.builtin.command: /usr/bin/false
|
||||
retries: 3
|
||||
@@ -7,12 +24,73 @@
|
||||
register: command_result
|
||||
until: command_result is not failed
|
||||
|
||||
- name: Run tasks locally
|
||||
delegate_to: 127.0.0.1 # 'localhost' works too
|
||||
ansible.builtin.command: hostname
|
||||
|
||||
- name: Assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'package' in ['container', 'package']"
|
||||
- "'https://www.google.com/' is ansible.builtin.url"
|
||||
- "'domain.example.com' is community.general.fqdn_valid(min_labels=2)"
|
||||
fail_msg: What to say if any of the above conditions fail
|
||||
success_msg: What to say if all of the above conditions succeed
|
||||
|
||||
- name: Test types
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
# strings are classified as 'string', 'iterable' and 'sequence', but not 'mapping'
|
||||
- "'aa' is string"
|
||||
- "'aa' is iterable"
|
||||
- "'aa' is sequence"
|
||||
# numbers are classified as 'numbers', with 'integer' and 'float' being subclasses
|
||||
- 42 is number and 5 is integer
|
||||
- 21.34 is number and 12.1 is float
|
||||
# lists are classified as 'iterable' and 'sequence', but not as 'string' nor 'mapping'
|
||||
- "['list'] is iterable"
|
||||
- "['list'] is sequence"
|
||||
# dictionaries are classified as 'iterable', 'sequence' and 'mapping', but not as 'string'
|
||||
- "{'a': 'dict'} is iterable"
|
||||
- "{'a': 'dict'} is sequence"
|
||||
- "{'a': 'dict'} is mapping"
|
||||
# native booleans
|
||||
- true is boolean
|
||||
- True is boolean
|
||||
- false is boolean
|
||||
- False is boolean
|
||||
|
||||
- name: Type conversion
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- "'string' | int is integer"
|
||||
- "'string' | float is float"
|
||||
- 12 | float is float
|
||||
- 21.02 | int is integer
|
||||
- 43 | string is string
|
||||
- 74.93 | string is string
|
||||
- 4 | bool is boolean
|
||||
|
||||
- name: Elvis operator
|
||||
# (condition) | bool | ternary(value_for_true_condition, value_for_false_condition, optional_value_for_null_condition)
|
||||
ansible.builtin.set_fact:
|
||||
acme_directory: >-
|
||||
{{
|
||||
this_is_a_test_run
|
||||
| default(true)
|
||||
| bool
|
||||
| ternary(
|
||||
'https://acme-staging-v02.api.letsencrypt.org/directory',
|
||||
'https://acme-v02.api.letsencrypt.org/directory'
|
||||
)
|
||||
}}
|
||||
|
||||
- name: Create directories recursively
|
||||
ansible.builtin.file:
|
||||
path: /tmp/path/to/final/dir
|
||||
state: directory
|
||||
|
||||
- name: Write files from tasks
|
||||
- name: Define files content in tasks
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ ansible_user_dir }}/.tmux.conf"
|
||||
mode: u=rw,go=r
|
||||
@@ -20,12 +98,23 @@
|
||||
…
|
||||
|
||||
- name: Show input data type
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
should_be_string: "{{ 'this' | type_debug }}"
|
||||
|
||||
- name: Run locally
|
||||
delegate_to: 127.0.0.1 # 'localhost' works too
|
||||
command: hostname
|
||||
- name: Pretty print information
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{
|
||||
dict([
|
||||
[ 'install_method', install_method ],
|
||||
[ 'install_method in supported_install_methods', install_method in supported_install_methods ],
|
||||
])
|
||||
}}
|
||||
|
||||
- name: Use filters
|
||||
tags: filter
|
||||
ansible.builtin.set_fact:
|
||||
path_list_of_all_txt_files_in_dir: "{{ lookup('ansible.builtin.fileglob', '/my/path/*.txt') }}"
|
||||
|
||||
- name: Import tasks
|
||||
block:
|
||||
@@ -49,24 +138,6 @@
|
||||
ansible.builtin.import_tasks:
|
||||
file: "{{ filename }}"
|
||||
|
||||
- name: Assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- install_method in supported_install_methods
|
||||
- external_url is ansible.builtin.url
|
||||
fail_msg: What to say if any of the above conditions fail
|
||||
success_msg: What to say if all of the above conditions succeed
|
||||
|
||||
- name: Pretty print information
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
{{
|
||||
dict([
|
||||
[ 'install_method', install_method ],
|
||||
[ 'install_method in supported_install_methods', install_method in supported_install_methods ],
|
||||
])
|
||||
}}
|
||||
|
||||
- name: Generate passwords
|
||||
block:
|
||||
- name: Randomly
|
||||
@@ -130,17 +201,27 @@
|
||||
- name: Manipulate strings
|
||||
ansible.builtin.set_fact:
|
||||
string_with_first_letter_to_uppercase: "{{ 'all_lowercase' | capitalize }}"
|
||||
string_with_something_replaced: "{{ 'dots.to.dashes' | replace('.','-') }}"
|
||||
split_string: "{{ 'testMe@example.com' | split('@') | first }}"
|
||||
string_with_pattern_replaced: >-
|
||||
{{ '*.domain.com...' | regex_replace('*' | regex_escape, 'star') | regex_replace('\.+$', '') }}
|
||||
|
||||
- name: Manipulate lists
|
||||
block:
|
||||
- name: Add elements to lists
|
||||
set_fact:
|
||||
vars:
|
||||
programming_languages:
|
||||
- C
|
||||
- Python
|
||||
ansible.builtin.set_fact:
|
||||
programming_languages: "{{ programming_languages + ['Ruby'] }}"
|
||||
- name: Remove elements from lists
|
||||
set_fact:
|
||||
vars:
|
||||
dbs_list: ['primary', 'sales']
|
||||
ansible.builtin.set_fact:
|
||||
list_without_items: "{{ dbs_list | difference(['template0','template1','postgres','rdsadmin']) }}"
|
||||
- name: Get a random element
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
random_item: "{{ ['a','b','c'] | random }}"
|
||||
- name: Sort dict elements in list by attribute
|
||||
tags: order_by
|
||||
@@ -150,7 +231,7 @@
|
||||
create_time: '2024-06-25T00:52:55.127000+00:00'
|
||||
- name: test
|
||||
create_time: '2024-05-17T01:53:12.103220+00:00'
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
snapshot_latest: "{{ snapshots | sort(attribute='create_time') | last }}"
|
||||
- name: Give back the first not null value (coalesce-like)
|
||||
vars:
|
||||
@@ -159,21 +240,21 @@
|
||||
- null
|
||||
- something
|
||||
- something else
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
first_non_null_value: "{{ list_with_null_values | select | first }}"
|
||||
- name: Get values for a specific attribute in a list of dictionaries
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
vpc_security_group_ids: >-
|
||||
{{ instance_information.vpc_security_groups | map(attribute='vpc_security_group_id') }}
|
||||
volume_ids: "{{ instances_information.instances[0].block_device_mappings | map(attribute='ebs.volume_id') }}"
|
||||
- name: Return only elements with specific attributes matching a filter
|
||||
set_fact:
|
||||
available_rds_snapshots: snapshots_list | selectattr("status", "equalto", "available")
|
||||
mounts_with_path: ansible_facts.mounts | selectattr('mount', 'in', path)
|
||||
ansible.builtin.set_fact:
|
||||
available_rds_snapshots: "{{ snapshots_list | selectattr('status', 'equalto', 'available') }}"
|
||||
mounts_with_path: "{{ ansible_facts.mounts | selectattr('mount', 'in', path) }}"
|
||||
- name: Return all elements *but* the ones with specific attributes matching a filter
|
||||
set_fact:
|
||||
available_rds_snapshots: snapshots_list | rejectattr("status", "equalto", "creating")
|
||||
mounts_without_path: ansible_facts.mounts | rejectattr('mount', 'in', path)
|
||||
ansible.builtin.set_fact:
|
||||
available_rds_snapshots: "{{ snapshots_list | rejectattr('status', 'equalto', 'creating') }}"
|
||||
mounts_without_path: "{{ ansible_facts.mounts | rejectattr('mount', 'in', path) }}"
|
||||
- name: Remove lines about RDS protected users and permissions from a dump file
|
||||
# remove empty lines
|
||||
# remove comments
|
||||
@@ -198,15 +279,19 @@
|
||||
}}
|
||||
|
||||
- name: Manipulate dictionaries
|
||||
vars:
|
||||
organization:
|
||||
address: 123 common lane
|
||||
id: 123abc
|
||||
block:
|
||||
- name: Add keys to dictionaries
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
organization: "{{ organization | combine({ 'name': 'ExampleOrg' }) }}"
|
||||
- name: Sort keys in dictionaries
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
organization: "{{ organization | dictsort }}"
|
||||
- name: Pretty print dictionaries
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
organization: "{{ organization | to_nice_json }}"
|
||||
- name: Merge dictionaries
|
||||
vars:
|
||||
@@ -218,7 +303,7 @@
|
||||
z:
|
||||
- 4
|
||||
- test
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
merged_dict: "{{ dict1 | ansible.builtin.combine(dict_2, {'z':'new_value','w':[44]}) }}"
|
||||
recursively_merged_dict: >-
|
||||
{{ {'rest':'test'} | ansible.builtin.combine({'z':'new_value','w':[44]}, dict_1, dict_2, recursive=true) }}
|
||||
@@ -234,7 +319,7 @@
|
||||
})
|
||||
}}
|
||||
with_items: "{{ db_extensions_query.results }}"
|
||||
- name: FIXME
|
||||
- name: Register the list of extensions per DB as 'db:extensions[]' pairs
|
||||
vars:
|
||||
db_extensions:
|
||||
sales:
|
||||
@@ -280,16 +365,16 @@
|
||||
{%- endfor -%}
|
||||
{{ ns.devices_list }}
|
||||
|
||||
- name: "Use the users' home directory for something"
|
||||
- name: Use the users' home directory for something
|
||||
block:
|
||||
- name: Executing commands from specified users
|
||||
block:
|
||||
- name: "Get users' homedir back"
|
||||
- name: Get users' homedir back
|
||||
become: true
|
||||
become_user: "{{ item }}"
|
||||
become_flags: "-iH"
|
||||
become_flags: -iH
|
||||
check_mode: false
|
||||
command: >-
|
||||
ansible.builtin.command: >-
|
||||
echo "{{ item }}: $HOME"
|
||||
changed_when: false
|
||||
with_items:
|
||||
@@ -313,13 +398,13 @@
|
||||
path: "{{ item.value }}/placeholder"
|
||||
state: touch
|
||||
with_dict: "{{ users_homedir }}"
|
||||
- name: "From the system's entries"
|
||||
- name: From the system's entries
|
||||
block:
|
||||
- name: "Get raw information from the system's entries"
|
||||
- name: Get raw information from the system's entries
|
||||
ansible.builtin.getent:
|
||||
database: passwd
|
||||
key: "{{ item }}"
|
||||
split: ":"
|
||||
split: ':'
|
||||
with_items:
|
||||
- root
|
||||
- ec2-user
|
||||
@@ -363,21 +448,13 @@
|
||||
&& aws s3 cp "$FILENAME" 's3://backups/prometheus/'
|
||||
&& rm "$FILENAME"
|
||||
|
||||
- name: Debug tasks
|
||||
debugger: on_failed
|
||||
ansible.builtin.fail:
|
||||
msg: Manual, enforced failure
|
||||
# print all variables at this point => p task_vars
|
||||
# continue => c
|
||||
# abort and quit => q
|
||||
|
||||
- name: Error handling in blocks
|
||||
block:
|
||||
- name: This executes normally
|
||||
ansible.builtin.debug:
|
||||
msg: I execute normally
|
||||
- name: This errors out
|
||||
ansible.builtin.command: "/bin/false"
|
||||
ansible.builtin.command: /bin/false
|
||||
- name: This never executes
|
||||
ansible.builtin.debug:
|
||||
msg: I never execute due to the above task failing
|
||||
@@ -390,12 +467,45 @@
|
||||
ansible.builtin.debug:
|
||||
msg: I always execute
|
||||
|
||||
- name: Integrate Ansible Vault
|
||||
tags: ansible_vault
|
||||
block:
|
||||
- name: Use encrypted values
|
||||
ansible.builtin.set_fact:
|
||||
var_from_encrypted_value:
|
||||
# password: '1q2w3e4r', plaintext value: 'very secret string'
|
||||
!vault |
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
34646464653830386631363430386432666530356364313532313336373665613038633464376335
|
||||
3539363530613130623638313063363165386230646566640a313438386133366137383939336637
|
||||
33333365393337326239336264623462373064383663363234353635316538356461353061646563
|
||||
3037306464363439340a663430313739393439363936613862316361353330363638323065383063
|
||||
39613935613035343637336537643266313737666635313730353034373736353736
|
||||
- name: Use encrypted files
|
||||
# The 'unvault' filter requires files to exist beforehand, but it is fine for them to be plaintext. \_(-_-)_/
|
||||
tags: tls_certificate
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/haproxy/certificate.pem
|
||||
content: |
|
||||
{{ lookup('ansible.builtin.unvault', 'path/to/cert/key.pem') | string | trim }}
|
||||
{{ lookup('ansible.builtin.unvault', 'path/to/cert/full_chain.pem') | string | trim }}
|
||||
- name: Save data to encrypted files
|
||||
# Of fu*king course the 'vault' filter would use the 'filter_default' vault ID by default to encrypt content.
|
||||
# Set that parameter to '' to *not* specify a vault ID.
|
||||
vars:
|
||||
ansible_vault_password: >-
|
||||
{{ lookup('ansible.builtin.file', [playbook_dir, 'ansible_vault_password_file.txt'] | path_join) }}
|
||||
ansible.builtin.copy:
|
||||
dest: path/to/file
|
||||
decrypt: false # necessary if the file does not exist beforehand
|
||||
content: "{{ 'some string' | ansible.builtin.vault(ansible_vault_password, vault_id='') }}"
|
||||
|
||||
- name: AWS
|
||||
tags: aws
|
||||
block:
|
||||
- name: Get current IP ranges
|
||||
# too many to be put into security group rules
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
ip_ranges: >-
|
||||
lookup('url', 'https://ip-ranges.amazonaws.com/ip-ranges.json', split_lines=False)
|
||||
| from_json
|
||||
@@ -411,7 +521,7 @@
|
||||
secret_key: 123456789abcdefghijklmnopqrstuvwxyzABCDE # optional if defined as environment variable
|
||||
profile: someProfile # optional if defined as environment variable
|
||||
role_arn: "arn:aws:iam::123456789012:role/someRole"
|
||||
role_session_name: "someRoleSession"
|
||||
role_session_name: someRoleSession
|
||||
register: assumed_role
|
||||
- name: Use the assumed role to take action
|
||||
amazon.aws.ec2_tag:
|
||||
@@ -428,7 +538,7 @@
|
||||
amazon.aws.ec2_instance_info:
|
||||
filters:
|
||||
"tag:Application": K8S
|
||||
"instance-state-name": ["running"]
|
||||
instance-state-name: ["running"]
|
||||
- name: Clone EC2 instances
|
||||
vars:
|
||||
source_instance_id: i-0123456789abcdef0
|
||||
@@ -460,44 +570,44 @@
|
||||
block:
|
||||
- name: Create the snapshot
|
||||
amazon.aws.rds_instance_snapshot:
|
||||
db_instance_identifier: "db-identifier"
|
||||
db_snapshot_identifier: "db-identifier-snapshot"
|
||||
db_instance_identifier: identifier-for-db-instance
|
||||
db_snapshot_identifier: identifier-for-db-snapshot
|
||||
register: snapshot_creation
|
||||
- name: Wait for the snapshot to be in the 'available state'
|
||||
- name: Wait for the snapshot to be in the 'available' state
|
||||
when: snapshot_creation.snapshot_create_time is defined
|
||||
amazon.aws.rds_snapshot_info:
|
||||
db_snapshot_identifier: "{{ snapshot_creation.db_snapshot_identifier }}"
|
||||
register: snapshot_check
|
||||
retries: 3
|
||||
delay: 120
|
||||
until: snapshot_check.snapshots | selectattr("status", "equalto", "available") | length > 0
|
||||
- name: "Dump roles' privileges"
|
||||
until: snapshot_check.snapshots | selectattr('status', 'equalto', 'available') | length > 0
|
||||
- name: Dump roles' privileges
|
||||
block:
|
||||
- name: Dump to file
|
||||
environment:
|
||||
PGPASSWORD: "someRandomString"
|
||||
PGPASSWORD: someRandomString
|
||||
vars:
|
||||
out_file: /tmp/instance-id_roles.sql
|
||||
ansible.builtin.command: >-
|
||||
pg_dumpall
|
||||
--host 'instance-id.c4v563ptr321.eu-west-1.rds.amazonaws.com' --port '5432'
|
||||
--host 'instance-id.0123456789ab.eu-west-1.rds.amazonaws.com' --port '5432'
|
||||
--user 'postgres' --database 'postgres' --no-password
|
||||
--roles-only --no-role-passwords
|
||||
--file '{{ out_file }}'
|
||||
changed_when: false
|
||||
- name: Dump to variable for later use through 'dump_execution.stdout_lines'
|
||||
environment:
|
||||
PGPASSWORD: "someRandomString"
|
||||
PGPASSWORD: someRandomString
|
||||
ansible.builtin.command: >-
|
||||
pg_dumpall
|
||||
-h 'instance-id.c4v563ptr321.eu-west-1.rds.amazonaws.com' -p '5432'
|
||||
-h 'instance-id.0123456789ab.eu-west-1.rds.amazonaws.com' -p '5432'
|
||||
-U 'postgres' -l 'postgres' -w
|
||||
-r --no-role-passwords
|
||||
changed_when: false
|
||||
register: dump_execution
|
||||
- name: Wait for pending changes to be applied
|
||||
amazon.aws.rds_instance_info:
|
||||
db_instance_identifier: "{{ db_instance_identifier }}"
|
||||
db_instance_identifier: identifier-for-db-instance
|
||||
register: instance_check
|
||||
retries: 12
|
||||
delay: 15
|
||||
@@ -543,3 +653,14 @@
|
||||
awx.awx.export:
|
||||
all: true
|
||||
register: awx_export_output
|
||||
|
||||
- name: Let's Encrypt
|
||||
# The 'acme_certificate' module takes in file paths for the certificate's files; those need either to *not* exist
|
||||
# beforehand, or their content to be in specific formats.
|
||||
block:
|
||||
- name: Revoke test certificates with account key
|
||||
community.crypto.acme_certificate_revoke:
|
||||
acme_directory: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
acme_version: 2
|
||||
account_key_src: path/to/acme_account.key.pem
|
||||
certificate: path/to/certificate.crt.pem
|
||||
|
||||
@@ -9,6 +9,7 @@ python -m 'http.server'
|
||||
python -m 'http.server' '8080' --bind 'localhost' --directory '/files/to/serve' --protocol 'HTTP/1.1' --cgi
|
||||
|
||||
# Quick 'n' dirty web server
|
||||
# pip install --user 'twisted' 'pyopenssl'
|
||||
# https://twisted.org/
|
||||
# pip install --user 'twisted[tls]'
|
||||
twistd -no web
|
||||
twistd -no web --path '/files/to/serve' --https '8443' --certificate 'server.pem' --privkey 'server.pem'
|
||||
|
||||
Reference in New Issue
Block a user