diff --git a/Ansible/Ansible-Cheat_Sheet_Edureka.pdf b/Ansible/Ansible-Cheat_Sheet_Edureka.pdf new file mode 100644 index 0000000..b4ac587 Binary files /dev/null and b/Ansible/Ansible-Cheat_Sheet_Edureka.pdf differ diff --git a/Ansible/ansible.md b/Ansible/ansible.md new file mode 100644 index 0000000..d2f6ef9 --- /dev/null +++ b/Ansible/ansible.md @@ -0,0 +1,1041 @@ +# [ansible](https://www.ansible.com/) +* [doc](https://docs.ansible.com/) +* [variables](https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html#) +* [cheat-sheet](https://cheat.readthedocs.io/en/latest/ansible/index.html) +* [best practices](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html) +* [ansible modules](https://docs.ansible.com/ansible/latest/collections/index_module.html) +* [ansible roles, ansible galaxy, ready roles](https://galaxy.ansible.com/) +* [examples](https://github.com/ansible/ansible-examples) +* [examples 2](https://github.com/mmumshad/ansible-training-answer-keys) +* [examples 3](https://github.com/mmumshad/ansible-training-answer-keys-2) +* [Jinja2 templating](https://jinja.palletsprojects.com/en/2.10.x/templates/) + + +## installation +```sh +yum install ansible +apt install ansible +``` +```sh +pip3 install ansible +# for python2 - default installation +pip install ansible +``` +remote machine should have 'python' - 'gather_facts: False' or 'gather_facts: no' otherwise + +## uninstall +```sh +rm -rf $HOME/.ansible +rm -rf $HOME/.ansible.cfg +sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible +sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible-2.5.4.dist-info +sudo rm -rf /usr/local/bin/ansible +sudo rm -rf /usr/local/bin/ansible-config +sudo rm -rf /usr/local/bin/ansible-connection +sudo rm -rf /usr/local/bin/ansible-console +sudo rm -rf /usr/local/bin/ansible-doc +sudo rm -rf /usr/local/bin/ansible-galaxy +sudo rm -rf /usr/local/bin/ansible-inventory +sudo rm -rf /usr/local/bin/ansible-playbook +sudo rm -rf /usr/local/bin/ansible-pull +sudo rm -rf /usr/local/bin/ansible-vault +sudo rm -rf /usr/lib/python2.7/dist-packages/ansible +sudo rm -rf /usr/local/lib/python2.7/dist-packages/ansible +``` + +## ansible configuration places +* path variable $Ansible_Config +* ~/.ansible.cfg +* /etc/ansible/ansible.cfg +```sh +ansible-config view +# list of possible environment variables +ansible-config dump +``` + +### configuration for external roles +filename: ~/.ansible.cfg +```properties +[defaults] +roles_path = ~/repos/project1/roles:~/repos/project2/roles +``` + +### check configuration +```sh +ansible-config view +``` + +## inventory +### without inventory inline host ip +``` +ansible all -i desp000111.vantage.zur, --user=my_user -m "ping" -vvv +``` + +### without inventory with pem ssh private ssh key +generate PEM file +```sh +ssh-keygen -t rsa -b 4096 -m PEM -f my_ssh_key.pem +ll my_ssh_key.pem + +ansible all -i desp000111.vantage.zur, --user=vitalii.cherkashyn -e ansible_ssh_private_key_file=my_ssh_key.pem -m "ping" -vvv +``` + +### ini file +```properties +# example cfg file +[web] +host1 +host2 ansible_port=222 # defined inline, interpreted as an integer + +[web:vars] +http_port=8080 # all members of 'web' will inherit these +myvar=23 # defined in a :vars section, interpreted as a string +``` + +## execute with specific remote python version, remote python, rewrite default variables, rewrite variables, override variable +``` +--extra-vars "remote_folder=$REMOTE_FOLDER ansible_python_interpreter=/usr/bin/python" +``` + +## execute ansible for one host only, one host, one remove server, verbosity +```sh +ansible-playbook -i "ubs000015.vantage.org , " mkdir.yaml + +ansible-playbook welcome-message.yaml -i airflow-test-account-01.ini --limit worker --extra-vars="ACCOUNT_ID=QA01" --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -vvv + +ansible all -i airflow-test-account-01.ini --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -m "ping" -vvv +ansible main,worker -i airflow-test-account-01.ini --user=ubuntu --ssh-extra-args="-i $EC2_KEY" -m "ping" +``` +simple file for creating one folder +```yaml +- hosts: all + tasks: + - name: Creates directory + file: + path: ~/spark-submit/trafficsigns + state: directory + mode: 0775 + - name: copy all files from folder + copy: + src: "/home/projects/ubs/current-task/nodes/ansible/files" + dest: ~/spark-submit/trafficsigns + mode: 0775 + + - debug: msg='folder was amazoncreated for host {{ ansible_host }}' +``` + +## execute ansible locally, local execution +```sh +# --extra-vars="mapr_stream_path={{ some_variable_from_previous_files }}/some-argument" \ + +ansible localhost \ + --extra-vars="deploy_application=1" \ + --extra-vars=@group_vars/all/vars/all.yml \ + --extra-vars=@group_vars/ubs-staging/vars/ubs-staging.yml \ + -m include_role \ + -a name="roles/labeler" +``` + + +## execute ansible-playbook with external paramters, bash script ansible-playbook with parameters, extra variables, external variables, env var +```j2 +# variable from env +{{ lookup('env','DB_VARIANT_USERNAME') }} +``` +```sh +ansible-playbook -i inventory.ini playbook.yml --extra-vars "$*" +``` +with path to file for external parameters, additional variables from external file +```sh +ansible-playbook -i inventory.ini playbook.yml --extra-vars @/path/to/var.properties +ansible-playbook playbook.yml --extra-vars=@/path/to/var.properties +``` + +## external variables inline +```sh +ansible-playbook playbook.yml --extra-vars="oc_project=scenario-test mapr_stream_path=/mapr/prod.zurich/vantage/scenario-test" +``` + +## check is it working, ad-hoc command +```sh +ansible remote* -i inventory.ini -m "ping" +ansible remote* -i inventory.ini --module-name "ping" +``` +```sh +ansible remote* -i inventory.ini -a "hostname" +``` + +## loop example +```sh + - name: scripts {{ item }} + template: + mode: 0777 + src: "templates/{{ item }}" + dest: "{{ root_folder }}/{{ item }}" + loop: + - "start-all.sh" + - "status.sh" + - "stop-all.sh" +``` + +## repeat execution +```sh +--limit {playbookfile}.retry +``` + +## start with task, execute from task, begin with task, skip previous tasks +```sh +ansible-playbook playbook.yml --start-at-task="name of the start to be started from" +``` + +## replace variables inside file to dedicated file, move vars to separate file +* before +```yaml + vars: + db_user: my_user + db_password: my_password + ansible_ssh_pass: my_ssh_password + ansible_host: 192.168.1.14 +``` +* after +*( 'vars' block is empty )* +filepath: +```sh +./host_vars/id_of_the_server +``` +or groupvars: +```sh +./group_vars/id_of_the_group_into_square_brakets +``` +code +```yaml +db_user: my_user +db_password: my_password +ansible_ssh_pass: my_ssh_password +ansible_host: 192.168.1.14 +``` + +## move code to separate file, tasks into file +cut code from original file and paste it into separate file ( with appropriate alignment !!! ), +write instead of the code: +```yaml + - include: path_to_folder/path_to_file +``` +approprate file should be created: +```sh +./path_to_folder/path_to_file +``` + +## skip/activate some tasks with labeling, tagging +```yaml +tasks: +- template + src: template/activation.sh.j2 + dest: /usr/bin/activation.sh + tags: + - flag_activation +``` +multitag, multi-tag +```yaml +tasks: +- template + src: template/activation.sh.j2 + dest: /usr/bin/activation.sh + tags: + - flag_activation + - flag_skip +``` + +```sh +ansible-playbook previous-block.yml --skip-tags "flag_activation" +# ansible-playbook previous-block.yml --skip-tags=flag_activation +# ansible-playbook previous-block.yml --tags "flag_activation" +# ansible-playbook previous-block.yml --tags=flag_activation +``` +# Debug +## [debug playbook](https://docs.ansible.com/ansible/latest/user_guide/playbooks_debugger.html) +```bash +export ANSIBLE_STRATEGY=debug +# revert it afterwards ( avoid "ERROR! Invalid play strategy specified: "): +# export ANSIBLE_STRATEGY=linear +``` +print variables +```python +task.args +task.args['src'] +vars() +``` +change variables +```python +del(task.args['src']) +task.args['src']="/new path to file" +``` +set variable +``` +- name: Set Apache URL + set_fact: + apache_url: 'http://example.com/apache' + +- name: Download Apache + shell: wget {{ apache_url }} +``` +shell == ansible.builtin.shell + +manage palying +``` +redo +continue +quit +``` + +```yaml +- name: airflow setup for main (web server) and workers + hosts: all + tasks: + - name: airflow hostname + debug: msg="{{ lookup('vars', 'ansible_host') }}" + - name: all variables from host + debug: msg="{{ vars }}" + when: run_mode == "debug" +``` + +## debug command +``` + - debug: + msg: "print variable: {{ my_own_var }}" +``` +``` + - shell: /usr/bin/uptime + register: result + + - debug: + var: result +``` + +## env variables bashrc +```sh +- name: source bashrc + sudo: no + shell: . /home/username/.bashrc && [the actual command you want run] +``` + +## rsync copy files +``` + - name: copy source code + synchronize: + src: '{{ item.src }}' + dest: '{{ item.dest }}' + delete: yes + recursive: yes + rsync_opts: + - "--exclude=.git" + - "-avz" + - '-e ssh -i {{ key }} ' + with_items: + - { src: '{{ path_to_repo }}/airflow-dag/airflow_shopify/', dest: '/home/ubuntu/airflow/airflow-dag/airflow_shopify/' } + +``` + +## ec2 managing airflow ec2 +``` +export PATH=$PATH:/home/ubuntu/.local/bin +nohup airflow webserver +``` + +## debug module +argument file ( args.json ) +```json +{ + "ANSIBLE_MODULE_ARGS": { + "task_parameter_1": "just a string", + "task_parameter_2": 50 + } +} +``` +execute file +```bash +python3 -m pdb library/oc_collaboration.py args.json +``` +set breakpoint +```python +import pdb +... +pdb.set_trace() +``` +run until breakpoint +```sh +until 9999 +next +``` + +## debug module inline, execute module inline, adhoc module check +```sh +ansible localhost -m debug --args msg="my custom message" +# collect facts +ansible localhost -m setup +``` + +## task print all variables +```yaml +- name: "Ansible | List all known variables and facts" + debug: + var: hostvars[inventory_hostname] +``` + +## ansible-console +```sh +ansible-console +debug msg="my custom message" +shell pwd +``` + +# error handling, try catch +## stop execution of steps (of playbook) when at least one server will throw error +```yaml + any_errors_fatal:true +``` +## not to throw error for one certain task +```yaml + - mail: + to: 1@yahoo.com + subject: info + body: das ist information + ignore_errors: yes +``` +## fail when, fail by condition, parse log file for errors +```yaml + - command: cat /var/log/server.log + register: server_log_file + failed_when : "'ERROR' in server_log_file.stdout" +``` + +# template, Jinja2 templating, pipes, [ansible filtering](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html) +default value +``` +default path is {{ my_custom_path | default("/opt/program/script.sh") }} +``` +escape special characters +``` +{{ '{{ filename }}.log' }} +``` + +operation with list +``` +{{ [1,2,3] | min }} +{{ [1,2,3] | max }} +{{ [1,2,3] | first }} +{{ [1,2,3] | last }} +{{ [1,2,3,2,3,] | unique }} +{{ [1,2,3] | union([1,2]) }} +{{ [1,2,3] | intersect([3]) }} +{{ 100 | random }} +{{ ["space", "separated", "value"] | join(" ") }} +{{'latest' if (my_own_value is defined) else 'local-build'}} +``` +file name from path (return 'script.sh') +``` +{{ "/etc/program/script.sh" | basename }} +``` +## copy file and rename it, pipe replace suffix +```yaml +- name: Create DAG config + template: src={{ item }} dest={{ airflow_dag_dir }}/config/{{ item | basename | regex_replace('\.j2','') }} + with_fileglob: + - ../airflow_dags/airflow_dags_gt/config/*.py.j2 +``` + +## copy reverse copy from destination machine +``` +- name: Fetch template + fetch: + src: '{{ only_file_name }}' + dest: '{{ destination_folder }}' + flat: yes + tags: deploy +``` + +## directives for Jinja +for improving indentation globally in file, add one of next line in the beginning +```yaml +#jinja2: lstrip_blocks: True +#jinja2: trim_blocks:False +#jinja2: lstrip_blocks: True, trim_blocks: True +``` +for improving indentation only for the block +```j2 +
+ {%+ if something %}hello{% endif %} +
+``` +condition example +```j2 +{% if lookup('env','DEBUG') == "true" %} + CMD ["java", "start-debug"] +{% else %} + CMD ["java", "start"] +{% endif %} +``` + +### directives for loop, for last, loop last +``` +[ +{% for stream in deployment.streams %} + { + "stream": "{{ stream.stream_name }}", + "classN": "{{ stream.class_name }}", + "script": "{{ stream.script_name }}", + "sibFolders": [ + {% for folder in stream.sub_folders %} + "{{ folder }}"{% if not loop.last %},{% endif %} + {% endfor %} + ] + }{% if not loop.last %},{% endif %} +{% endfor %} +] +``` + +## escaping +just a symbol +``` +{{ '{{' }} +``` +bigger piece of code +``` +{% raw %} + +{% endraw %} +``` + + +## template with tempfile +``` +- hosts: localhost + gather_facts: no + tasks: + - tempfile: + state: file + suffix: config + register: temp_config + + - template: + src: templates/configfile.j2 + dest: "{{ temp_config.path }}" +``` +# [modules](https://github.com/ansible/ansible/tree/devel/lib/ansible/modules) +* [create custom module](https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html) +## settings for modules +also need to 'notify' ansible about module giving one of the next option: +* add your folder with module to environment variable ANSIBLE_LIBRARY +* update $HOME/.ansible.cfg + ```properties + library=/path/to/module/library + ``` + +## module documentation +``` +ansible-doc -t module {name of the module} +``` + +## minimal module +``` +from ansible.module_utils.basic import AnsibleModule +def main(): + input_fields = { + "operation": {"required": True, "type": "str"}, + "file": {"required": True, "type": "str"}, + "timeout": {"required": False, "type": "int", "default": "120"} + } + module = AnsibleModule(argument_spec=input_fields) + operation = module.params["operation"] + file = module.params["file"] + timeout = module.params["timeout"] + # module.fail_json(msg="you must be logged in into OpenShift") + module.exit_json(changed=True, meta={operation: "create"}) +``` + +# [plugins](https://github.com/ansible/ansible/tree/devel/lib/ansible/plugins/) +example of plugin +``` +{{ list_of_values | average }} +``` +python code for plugin +``` +dev average(list): + return sum(list) / float(len(list)) + +class AverageModule(object): + def filters(self): + return {'average': average} +``` +execution +``` +export ANSIBLE_FILTER_PLUGINS=/full/path/to/folder/with/plugin +ansible-playbook playbook.yml +``` + +## lookups +```sh +# documentation +ansible-doc -t lookup -l +ansible-doc -t lookup csvfile +``` + +replace value from file with special format +```python +{{ lookup('csvfile', 'web_server file=credentials.csv delimiter=,') }} +{{ lookup('ini', 'password section=web_server file=credentials.ini') }} +{{ lookup('env','DESTINATION') }} +{{ lookup('file','/tmp/version.txt') }} +``` +lookups variables +``` +{{ hostvars[inventory_hostname]['somevar_' + other_var] }} + +For ‘non host vars’ you can use the vars lookup plugin: +{{ lookup('vars', 'somevar_' + other_var) }} +``` + +```yaml +- name: airflow setup for main (web server) and workers + hosts: all + tasks: + - name: airflow hostname + debug: msg="{{ lookup('vars', 'ansible_host') }}" + - name: variable lookup + debug: msg="lookup data {{ lookup('vars', 'ansible_host')+lookup('vars', 'ansible_host') }}" + - name: read from ini, set variable + set_fact: + queues: "{{ lookup('ini', lookup('vars', 'ansible_host')+' section=queue file=airflow-'+lookup('vars', 'account_id')+'-workers.ini') }}" + - name: airflow lookup + debug: msg=" {{ '--queues '+lookup('vars', 'queues') if lookup('vars', 'queues') else '' }}" +``` + +# inventory file +--- +## inventory file, inventory file with variables, [rules](https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html) +``` +[remote_ssh] +172.28.128.3 ansible_connection=ssh ansible_port=22 ansible_user=tc ansible_password=tc +``` +## dynamic inventory +python inventory.py (with 'py' extension) instead of txt +``` +import json +data = {"databases": {"hosts": ["host1", "host2"], "vars": {"ansible_ssh_host":"192.168.10.12", "ansible_ssh_pass":"Passw0rd"} }} +print(json.dumps(data)) +``` +also next logic should be present +``` +inventory.py --list +inventory.py --host databases +``` +[prepared scripts](https://github.com/ansible/ansible/tree/devel/contrib/inventory) + +## inventory file with variables ( python Jinja templating) +``` +[remote_ssh] +172.28.128.3 ansible_connection=ssh ansible_port=22 ansible_user=tc ansible_password=tc http_port=8090 +``` +playbook usage: +``` +'{{http_port}}' +``` + +## execution with inventory examples +for one specific host without inventory file +```sh +ansible-playbook playbook.yml -i 10.10.10.10 +``` +with inventory file +```sh +ansible-playbook -i inventory.ini playbook.yml +``` +issue with execution playbook for localhost only, local execution +```text +Note that the implicit localhost does not match 'all' +... +skipping: no hosts matched +``` +solution +```sh +ansible-playbook --inventory="localhost," --connection=local --limit=localhost --skip-tag="python-script" playbook.yaml + +# example with external variables +ansible-playbook --inventory="localhost," --connection=local --limit=localhost \ +--extra-vars="oc_project=scenario-test mapr_stream_path=/mapr/prod.zurich/vantage/scenario-test" \ +--tag="scenario-service" deploy-scenario-pipeline.yaml +``` + +solution2 +```sh +#vim /etc/ansible/hosts +localhost ansible_connection=local +``` + + +# strategy +--- +``` + strategy: linear +``` +* linear ( default ) +*after each step waiting for all servers* +* free +*independently for all servers - someone can finish installation significantly earlier than others* + +additional parameter - specify amount of servers to be executed at the time ( for default strategy only ) +``` + serial: 3 +``` +``` + serial: 20% +``` +``` + serial: [5,15,20] +``` + +default value "serial" into configuration **ansible.cfg** +``` +forks = 5 +``` + +# async execution, nowait task, command execution +**not all modules support this operation** +execute command in asynchronous mode ( with preliminary estimation 120 sec ), +with default poll result of the command - 10 ( seconds ) +``` + async: 120 +``` +execute command in asynchronous mode ( with preliminary estimation 120 sec ), +with poll result of the command - 60 ( seconds ) +``` + async: 120 + poll: 60 +``` +execute command and forget, not to wait for execution +``` + async: 120 + poll: 0 +``` +execute command in asynchronous mode, +register result +checking result at the end of the file +``` +- command: /opt/my_personal_long_run_command.sh + async: 120 + poll: 0 + register: custom_command_result + +- name: check status result + async_status: jid={{ custom_command_result.ansible_job_id }} + register: command_result + until: command_result.finished + retries: 20 +``` + + +# roles +--- +## init project ansible-galaxy, create new role, init role +execute code into your project folder './roles' +``` +ansible-galaxy init {project/role name} +``` +result: +``` +./roles/{project/role name} + /defaults + /handlers + /meta + /tasks + /tests + /vars +``` +insert into code +``` + roles: + - {project/role name} +``` +all folders of the created project will be applied to your project ( tasks, vars, defaults ) +*in case of manual creation - only necessary folders can be created* + +## ansible search for existing role +``` +ansible-galaxy search {project/role name} +``` + +## import existing roles from [ansible galaxy](https://galaxy.ansible.com/list) +``` +cd roles +ansible-galaxy import {name of the project/role} +``` +insert into code +``` + roles: + - {project/role name} +``` +all folders of the imported project will be applied to your project ( tasks, vars, defaults ) + +## import task from role, role.task, task inside role +```yaml +- hosts: localhost + # hosts: all + # hosts: + tasks: + - name: first step + include_role: + name: mapr-kafka + tasks_from: cluster-login +``` + +## export +create/update file: +``` +./roles/{project/role name}/meta/main.yml +``` + +## local run local start playbook +```yaml +- hosts: localhost + tasks: + - name: Ansible create file with content example + copy: + dest: "/tmp/remote_server.txt" + content: | + dog + tiger +``` +### minimal playbook +```yaml +- hosts: localhost + tasks: + - name: Ansible create file with content example + copy: + dest: "/tmp/remote_server.txt" + content: | + {{ lookup('env','TEST_1') }} + {{ lookup('env','TEST_2') }} +``` + +```sh +ansible-playbook ansible-example.yml +``` + +## execute role, role execution, start role locally, local start, role local execution +```sh +ansible localhost \ + --extra-vars="deploy_application=1" \ + --extra-vars=@group_vars/all/defaults/all.yaml \ + --extra-vars=@group_vars/all/vars/all.yaml \ + --extra-vars="mapr_stream_path={{ some_variable_from_previous_files }}/some-argument" \ + -m include_role \ + -a name="new_application/new_role" +``` +where "include_role" - module to run ( magic word ) +where "new_application/new_role" - subfolder to role +where @group_vars/all/default/all.yaml - sub-path to yaml file with additional variables + +## console output with applied roles should looks like +``` +TASK [{project/role name}: {task name}] *********************************** +``` +for example +``` +TASK [java : install java with jdbc libraries] *********************************** +``` + +# file encryption, vault +``` +ansible-vault encrypt inventory.txt +ansible-vault view inventory.txt +ansible-vault create inventory.txt +``` +ask password via command line +``` +ansible-playbook playbook.yml -i inventory.txt -ask-vault-pass +``` +file should contain the password +``` +ansible-playbook playbook.yml -i inventory.txt -vault-password-file ./file_with_pass.txt +``` +script should return password +``` +ansible-playbook playbook.yml -i inventory.txt -vault-password-file ./file_with_pass.py +``` + +# modules +[list of all modules](https://docs.ansible.com/ansible/devel/modules/list_of_all_modules.html) +[custom module playground](https://ansible-playable.com) +[custom module creation doc](docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html) + +### [apt](https://docs.ansible.com/ansible/latest/modules/apt_module.html), python installation +``` +- name: example of apt install + apt: name='{{ item }}' state=installed + with_items: + - python + - python-setuptools + - python-dev + - build-essential + - python-pip +``` + +### [service](https://docs.ansible.com/ansible/latest/modules/service_module.html) +``` +- name: example of start unix service + service: + name: mysql + state: started + enabled: yes +``` + +### [pip](https://docs.ansible.com/ansible/latest/modules/pip_module.html) +``` +- name: manage python packages via pip + pip: + name: flask +``` + +### include variables import variables +```json +- name: External variables + include_vars: roles/marker-table/defaults/main.yaml + tags: deploy +``` + +### echo +add flag for ```ansible``` or ```ansible-playbook```:-vvv(3) -vv (2) or -v (1) +``` +- debug: + msg: ">>> {{ data_portal_deploy_folder }}/data-portal.jar" + var: src + verbosity: 2 +``` + +### [copy](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html?extIdCarryOver=true&sc_cid=701f2000001OH7nAAG#ansible-collections-ansible-builtin-copy-module) +``` +- name: Ensure MOTD file is in place + copy: + src: files/motd + dest: /etc/motd + owner: root + group: root + mode: 0644 + +- name: Ensure MOTD file is in place + copy: + content: "Welcome to this system." + dest: /etc/motd + owner: root + group: root + mode: 0644 +``` + +### [template](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html#ansible-collections-ansible-builtin-template-module) +```json +- name: Ensure MOTD file is in place + template: + src: templates/motd.j2 + dest: /etc/motd + owner: root + group: root + mode: 0644 +``` + +### [user](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html) +```json +- name: Ensure user1 exists + user: + name: user1 + group: users + groups: wheel + uid: 2001 + password: "{{ 'mypassword' | password_hash('sha512') }}" + state: present +``` + +### [package](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html) +```json +- name: Ensure Apache package is installed + package: + name: httpd + state: present +``` + +### [firewalld](https://docs.ansible.com/ansible/latest/collections/ansible/posix/firewalld_module.html) +```json +- name: Ensure port 80 (http) is open + firewalld: + service: http + state: enabled + permanent: yes + immediate: yes +``` + +### [file](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html) +```json +- name: Ensure directory /app exists + file: + path: /app + state: directory + owner: user1 + group: docker + mode: 0770 +``` + +### [lineinfile](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/lineinfile_module.html) +```json +- name: Ensure host my-own-host in hosts file + lineinfile: + path: /etc/hosts + line: 192.168.0.36 my-own-host + state: present + +- name: Ensure root cannot login via ssh + lineinfile: + path: /etc/ssh/sshd_config + regexp: '^PermitRootLogin' + line: PermitRootLogin no + state: present +``` + +### [unarchive](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/unarchive_module.html) +```json +- name: Extract content from archive + unarchive: + src: /home/user1/Download/app.tar.gz + dest: /app + remote_src: yes +``` + +### [command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html) +```json +- name: Run bash script + command: "/home/user1/install-package.sh" +``` + +### TBD +* system +* commands +* database +* cloud +* windows + + +# [ansible awx](https://github.com/ansible/awx) + +# issues + +## fingerprint checking +``` +fatal: [172.28.128.4]: FAILED! => {"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host."} +``` +resolution +``` +export ANSIBLE_HOST_KEY_CHECKING=False +ansible-playbook -i inventory.ini playbook-directory.yml +``` diff --git a/Ansible/ansible_curso/facts/apache_facts.yml b/Ansible/ansible_curso/facts/apache_facts.yml new file mode 100644 index 0000000..a153eb6 --- /dev/null +++ b/Ansible/ansible_curso/facts/apache_facts.yml @@ -0,0 +1,30 @@ +--- + +- hosts: grupo1 + tasks: + - name: Instalando Apache + yum: + name: httpd + state: latest + + - name: Arrancando servicios + service: + name: httpd + state: started + enabled: true + + - name: Abrir firewall + firewalld: + service: http + immediate: true + permanent: true + state: enabled + + - name: Contenido del index + copy: + content: "Bienvenido a mi web. Yo soy {{ ansible_hostname }} y mi ip es la {{ ansible_default_ipv4.address }}" + dest: /var/www/html/index.html + mode: 0644 + +... + diff --git a/Ansible/ansible_curso/facts/crear_directorio.yml b/Ansible/ansible_curso/facts/crear_directorio.yml new file mode 100644 index 0000000..a0ba6ec --- /dev/null +++ b/Ansible/ansible_curso/facts/crear_directorio.yml @@ -0,0 +1,16 @@ +--- +- hosts: grupo3 + tasks: + - name: Crear directorio + file: + path: /etc/ansible/facts.d + state: directory + recurse: true + + - name: Copiar archivo nuevo + copy: + src: new.fact + dest: /etc/ansible/facts.d/ + +... + diff --git a/Ansible/ansible_curso/facts/new.fact b/Ansible/ansible_curso/facts/new.fact new file mode 100644 index 0000000..e69de29 diff --git a/Ansible/ansible_curso/facts/play1.yml b/Ansible/ansible_curso/facts/play1.yml new file mode 100644 index 0000000..bbefc0a --- /dev/null +++ b/Ansible/ansible_curso/facts/play1.yml @@ -0,0 +1,28 @@ +--- +- hosts: grupo1 + tasks: + - name: Instalar Apache + yum: + name: httpd + state: latest + + - name: Abrir firewall + firewalld: + service: http + permanent: true + immediate: true + state: enabled + + - name: fact + copy: + content: Hola, soy {{ansible_hostname}} y mi IP es {{ ansible_default_ipv4.address }} + dest: /var/www/html/index.html + + - name: servicio + service: + name: httpd + state: started + enabled: true + +... + diff --git a/Ansible/ansible_curso/inclusiones/ejercicio1.yml b/Ansible/ansible_curso/inclusiones/ejercicio1.yml new file mode 100644 index 0000000..6e2a945 --- /dev/null +++ b/Ansible/ansible_curso/inclusiones/ejercicio1.yml @@ -0,0 +1,13 @@ +--- +- name: Trabajando con inclusiones (al empezar con name para describirlo el hosts no tiene guion) + hosts: grupo2 + tasks: + - name: Incluyendo vbles del fichero tasks.inc + include: tasks.inc.yml + vars: + paquete: samba + servicio: smb + estado: started + +... + diff --git a/Ansible/ansible_curso/inclusiones/ejercicio2.yml b/Ansible/ansible_curso/inclusiones/ejercicio2.yml new file mode 100644 index 0000000..d48f6a7 --- /dev/null +++ b/Ansible/ansible_curso/inclusiones/ejercicio2.yml @@ -0,0 +1,24 @@ +--- +- hosts: grupo3 + vars_files: + - paquetes.inc.yml + tasks: + - name: Instalando paquetes + yum: + name: "{{ paquetes.mi_pkg }},{{ paquetes.mi_pkg2 }}" + state: latest + + - name: Iniciando servicios + service: + name: "{{ servicios.mi_srv }}" + state: started + enabled: true + + - name: Iniciando servicios 2 + service: + name: "{{ servicios.mi_srv2 }}" + state: started + enabled: true + +... + diff --git a/Ansible/ansible_curso/inclusiones/paquetes.inc.yml b/Ansible/ansible_curso/inclusiones/paquetes.inc.yml new file mode 100644 index 0000000..675adef --- /dev/null +++ b/Ansible/ansible_curso/inclusiones/paquetes.inc.yml @@ -0,0 +1,12 @@ +--- +item: + +paquetes: + mi_pkg: vsftpd + mi_pkg2: tftp-server + +servicios: + mi_srv: vsftpd + mi_srv2: tftp +... + diff --git a/Ansible/ansible_curso/inclusiones/tasks.inc.yml b/Ansible/ansible_curso/inclusiones/tasks.inc.yml new file mode 100644 index 0000000..e77ef16 --- /dev/null +++ b/Ansible/ansible_curso/inclusiones/tasks.inc.yml @@ -0,0 +1,14 @@ +--- +- name: Instalando {{ paquete }} + yum: + name: "{{ paquete }}" + state: latest + +- name: Iniciando {{ servicio }} + service: + name: "{{ servicio }}" + state: "{{ estado }}" + enabled: true + +... + diff --git a/Ansible/ansible_curso/lab_facts/copy_facts.yml b/Ansible/ansible_curso/lab_facts/copy_facts.yml new file mode 100644 index 0000000..96d2b70 --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/copy_facts.yml @@ -0,0 +1,17 @@ +--- +- hosts: directorio:archivo + vars: + remote_dir: /etc/ansible/facts.d + fact_file: custom.fact + tasks: + - name: Crear directorio destino + file: + path: "{{ remote_dir }}" + state: directory + recurse: yes + - name: Copiar facts + copy: + src: "{{ fact_file }}" + dest: "{{ remote_dir }}" +... + diff --git a/Ansible/ansible_curso/lab_facts/custom.fact b/Ansible/ansible_curso/lab_facts/custom.fact new file mode 100644 index 0000000..ea6d71e --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/custom.fact @@ -0,0 +1,12 @@ +[paquetes] +smb_pkg=samba +ftp_pkg=vsftpd +db_pkg=mariadb-server +web_pkg=httpd + +[servicios] +smb_srv=smb +ftp_srv=vsftpd +db_srv=mariadb +web_srv=httpd + diff --git a/Ansible/ansible_curso/lab_facts/play.yml b/Ansible/ansible_curso/lab_facts/play.yml new file mode 100644 index 0000000..f0d7f56 --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/play.yml @@ -0,0 +1,43 @@ +--- +- hosts: directorio + tasks: + - name: Incluyendo variables + include_vars: vars/allvars.yml + - name: Incluyendo tasks para grupo directorio + include: tasks/directorio.yml + - name: Abrir firewall + firewalld: + service: ftp + state: enabled + immediate: true + permanent: true + - name: Creando contenido ftp + copy: + content: "Bienvenidos al servidor ftp {{ ansible_hostname }} con ip {{ ansible_default_ipv4.address }}\n" + dest: "{{ ftp_root }}/motd" + - name: Reinicio de ftp + service: + name: vsftpd + state: restarted + +- hosts: archivo + tasks: + - name: Incluyendo variables + include_vars: vars/allvars.yml + - name: Incluyendo tasks para grupo archivo + include: tasks/archivo.yml + - name: Abrir firewall + firewalld: + service: http + state: enabled + immediate: true + permanent: true + - name: Crendo contenido web + copy: + content: "Hola yo soy {{ ansible_hostname }} y mi ip es la {{ ansible_default_ipv4.address }}\n" + dest: "{{ web_root }}/index.html" + - name: Reinicio de apache + service: + name: httpd + state: restarted +... diff --git a/Ansible/ansible_curso/lab_facts/tasks/archivo.yml b/Ansible/ansible_curso/lab_facts/tasks/archivo.yml new file mode 100644 index 0000000..7f4e74d --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/tasks/archivo.yml @@ -0,0 +1,21 @@ +--- +- name: Instalando samba y web + yum: + name: + - "{{ ansible_local.custom.paquetes.smb_pkg }}" + - "{{ ansible_local.custom.paquetes.web_pkg }}" + state: latest + +- name: Iniciando servicio samba + service: + name: "{{ ansible_local.custom.servicios.smb_srv }}" + state: started + enabled: true + +- name: Iniciando servicio web + service: + name: "{{ ansible_local.custom.servicios.web_srv }}" + state: started + enabled: true +... + diff --git a/Ansible/ansible_curso/lab_facts/tasks/directorio.yml b/Ansible/ansible_curso/lab_facts/tasks/directorio.yml new file mode 100644 index 0000000..b089baf --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/tasks/directorio.yml @@ -0,0 +1,20 @@ +--- +- name: Instalando database y ftp + yum: + name: + - "{{ ansible_local.custom.paquetes.db_pkg }}" + - "{{ ansible_local.custom.paquetes.ftp_pkg }}" + state: latest + +- name: Iniciando servicio ftp + service: + name: "{{ ansible_local.custom.servicios.ftp_srv }}" + state: started + enabled: true + +- name: Iniciando servicio mariadb + service: + name: "{{ ansible_local.custom.servicios.db_srv }}" + state: started + enabled: true +... diff --git a/Ansible/ansible_curso/lab_facts/vars/allvars.yml b/Ansible/ansible_curso/lab_facts/vars/allvars.yml new file mode 100644 index 0000000..2476f7e --- /dev/null +++ b/Ansible/ansible_curso/lab_facts/vars/allvars.yml @@ -0,0 +1,5 @@ +--- +web_root: /var/www/html +ftp_root: /var/ftp/pub +... + diff --git a/Ansible/ansible_curso/playbooks/apache.yml b/Ansible/ansible_curso/playbooks/apache.yml new file mode 100644 index 0000000..ae0003f --- /dev/null +++ b/Ansible/ansible_curso/playbooks/apache.yml @@ -0,0 +1,36 @@ +--- + +- hosts: grupo1 + tasks: + - name: Instalando Apache + yum: + name: httpd + state: latest + + - name: Arrancando servicios + service: + name: httpd + state: started + enabled: true + + - name: Abrir firewall + firewalld: + service: http + immediate: true + permanent: true + state: enabled + + - name: Contenido del index + copy: + content: "Bienvenido a mi web" + dest: /var/www/html/index.html + mode: 0644 + + - name: Cambiando el index + lineinfile: + path: /var/www/html/index.html + regexp: '^Bienvenido' + line: 'Hola a todos y bienvenidos' + +... + diff --git a/Ansible/ansible_curso/playbooks/apache_con_groups_vars.yml b/Ansible/ansible_curso/playbooks/apache_con_groups_vars.yml new file mode 100644 index 0000000..c19e862 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/apache_con_groups_vars.yml @@ -0,0 +1,15 @@ +--- +- hosts: grupo1 + tasks: + - name: Instalar {{ package1 }} + yum: + name: "{{ package1 }}" + state: latest + - name: Iniciar {{ service1 }} + service: + name: "{{ service1 }}" + state: started + enabled: true + +... + diff --git a/Ansible/ansible_curso/playbooks/crear_usuarios.yml b/Ansible/ansible_curso/playbooks/crear_usuarios.yml new file mode 100644 index 0000000..9567c68 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/crear_usuarios.yml @@ -0,0 +1,13 @@ +--- +- hosts: grupo3 + vars_files: + - users.yml + tasks: + - name: Crear usuarios + user: + name: "{{ users.rob.login }}" + comment: "{{ users.rob.first_name }} {{ users.rob.last_name }}" + home: "{{ users.rob.home_dir }}" + shell: " {{ users.rob.shell }} " +... + diff --git a/Ansible/ansible_curso/playbooks/group_vars/grupo1 b/Ansible/ansible_curso/playbooks/group_vars/grupo1 new file mode 100644 index 0000000..f49ac31 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/group_vars/grupo1 @@ -0,0 +1,2 @@ +package1: httpd +service1: httpd diff --git a/Ansible/ansible_curso/playbooks/group_vars/grupo2 b/Ansible/ansible_curso/playbooks/group_vars/grupo2 new file mode 100644 index 0000000..5f30c36 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/group_vars/grupo2 @@ -0,0 +1,2 @@ +package1: mariadb-server +service1: mariadb diff --git a/Ansible/ansible_curso/playbooks/group_vars/grupo3 b/Ansible/ansible_curso/playbooks/group_vars/grupo3 new file mode 100644 index 0000000..d3612ad --- /dev/null +++ b/Ansible/ansible_curso/playbooks/group_vars/grupo3 @@ -0,0 +1,2 @@ +package1: vsftpd +service1: vsftpd diff --git a/Ansible/ansible_curso/playbooks/instala.yml b/Ansible/ansible_curso/playbooks/instala.yml new file mode 100644 index 0000000..1ad4e08 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/instala.yml @@ -0,0 +1,37 @@ +--- + +- hosts: grupo1 + tasks: + - name: Instalar Apache + yum: + name: httpd + state: latest + + - name: Instalar Samba + yum: + name: samba + state: latest + + - name: Iniciar servicios + service: + name: "{{ item }}" + enabled: true + state: started + with_items: + - httpd + - smb + + - name: Abrir firewall + firewalld: + service: http + permanent: true + immediate: true + state: enabled + + - name: Copiando contenido + copy: + content: "Bienvenido a mi web" + dest: /var/www/html/index.html + +... + diff --git a/Ansible/ansible_curso/playbooks/mariadb_con_vbles.yml b/Ansible/ansible_curso/playbooks/mariadb_con_vbles.yml new file mode 100644 index 0000000..2a62be1 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/mariadb_con_vbles.yml @@ -0,0 +1,18 @@ +--- +- hosts: grupo2 + vars_files: + - mariadb_vbles.yml + + tasks: + - name: Instalar {{ package }} + yum: + name: "{{ package }}" + state: latest + - name: Iniciar {{ service }} + service: + name: "{{ service }}" + state: started + enabled: true + +... + diff --git a/Ansible/ansible_curso/playbooks/mariadb_vbles.yml b/Ansible/ansible_curso/playbooks/mariadb_vbles.yml new file mode 100644 index 0000000..76b1166 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/mariadb_vbles.yml @@ -0,0 +1,2 @@ +package: mariadb-server +service: mariadb diff --git a/Ansible/ansible_curso/playbooks/play1.yml b/Ansible/ansible_curso/playbooks/play1.yml new file mode 100644 index 0000000..9fd9477 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/play1.yml @@ -0,0 +1,11 @@ +--- +- hosts: all:!grupo1:!grupo2 + tasks: + - name: Hacer echo + shell: + cmd: echo {{ item }} + with_items: + - casa + - edificios + - oficinas +... diff --git a/Ansible/ansible_curso/playbooks/users.yml b/Ansible/ansible_curso/playbooks/users.yml new file mode 100644 index 0000000..6768f0a --- /dev/null +++ b/Ansible/ansible_curso/playbooks/users.yml @@ -0,0 +1,7 @@ +users: + rob: + first_name: Rob + last_name: Smith + home_dir: /home/rsmith + login: rsmith + shell: /sbin/nologin diff --git a/Ansible/ansible_curso/playbooks/vsftpd_con_vbles.yml b/Ansible/ansible_curso/playbooks/vsftpd_con_vbles.yml new file mode 100644 index 0000000..679e285 --- /dev/null +++ b/Ansible/ansible_curso/playbooks/vsftpd_con_vbles.yml @@ -0,0 +1,19 @@ +--- +- hosts: grupo3 + vars: + package: vsftpd + service: vsftpd + + tasks: + - name: Instalar {{ package }} + yum: + name: "{{ package }}" + state: latest + - name: Iniciar {{ service }} + service: + name: "{{ service }}" + state: started + enabled: true + +... + diff --git a/Grabar todas las llamadas en Ubuntu Touch.txt b/Grabar todas las llamadas en Ubuntu Touch.txt new file mode 100644 index 0000000..8b22b08 --- /dev/null +++ b/Grabar todas las llamadas en Ubuntu Touch.txt @@ -0,0 +1,37 @@ +CÓMO GRABAR TODAS LAS LLAMADAS EN UBUNTU TOUCH AUTOMÁTICAMENTE. +Comparto un pack de scripts que crean un servicio hechos por @Br1 para grabar todas las llamadas, sin intervención, en Ubuntu Touch. Lo que hace este servicio es grabar todas las llamadas, que recibamos y hagamos, y guardarlas en la carpeta MyRec. El script, por defecto, borrará todas las grabaciones que tengan más de un mes, pero ese comportamiento lo podemos modificar para que las borre antes o más tarde o nunca. Este artículo es un «filtrado» y traducción del hilo del blog de Br1 de UBports, los agradecimientos allí. +Comprobar compatibilidad +Para realizar esto debes estar familiarizado con la línea de comandos, aconsejo hacerlo por ssh o adb, tened en cuenta que si lo hacéis en la terminal del móvil tendréis que marcar en UT Twek Tool que no entre en suspensión está. +El primer paso es ejecutar: +1 arecord file.wav +hacer una llamada y luego detener la grabación con Ctrl+C +reproduce la llamada grabada, la grabación está en la home, si las voces no se oyen claramente, desafortunadamente esto ya ha terminado +De lo contrario puede continuar … +Manos a la obra +@Br1 lo ha hecho tan fácil como le ha sido posible, sólo tienes que hacer tres pasos: +En primer lugar, utilizar el navegador Morph o Teleports para descargar ( simplemente haga clic) callrecorder.tar.gz desde aquí (enlace caído) o desde aquí (revisado y subido por mi). +En segundo lugar, abra el Gestor de archivos, vaya a Downloads o donde lo haya guardado, haga clic en callrecorder.tar.gz y seleccione extraer archivo. +Tercero, para ejecutar callrec-install abra el Terminal y escriba : +1 sudo Downloads/callrecorder/callrec-install +callrec-install script le pedirá que elija: + +1 Para instalar callrecorder (se requiere reiniciar)?2 Para desinstalarlo?3 Para salir del script +1 +2 +3 +4 +5 +6 +7 +8 phablet@ubuntu-phablet:~$ sudo Downloads/callrecorder/callrec-install + + - You can install / uninstall CallRecorder - + +1) Install +2) Uninstall +3) Quit +Please enter your choice : 1 +Usted no tiene que hacer nada más. +Las llamadas grabadas están en el directorio MyRec, al iniciar el dispositivo el script prepare.sh borrará las que tengan más de 30 días. +Recomiendo ejecutar callrec-install para desinstalar callrecorder antes de proceder a la actualización OTA. +Y eso es todo, si quieres saber como modificar el script prepare.sh para que borre las llamadas cuando tengan más o menos de 30 días o no las borre nunca, está en el hilo, si no te aclaras dímelo y lo añado en la entrada. \ No newline at end of file diff --git a/RedHat Cheat Sheets/advanced-linux-commands-cheat-sheet-red-hat-developer.pdf b/RedHat Cheat Sheets/advanced-linux-commands-cheat-sheet-red-hat-developer.pdf new file mode 100644 index 0000000..4c67af7 Binary files /dev/null and b/RedHat Cheat Sheets/advanced-linux-commands-cheat-sheet-red-hat-developer.pdf differ diff --git a/RedHat Cheat Sheets/bash-shell-cheat-sheet.pdf b/RedHat Cheat Sheets/bash-shell-cheat-sheet.pdf new file mode 100644 index 0000000..97e13d9 Binary files /dev/null and b/RedHat Cheat Sheets/bash-shell-cheat-sheet.pdf differ diff --git a/RedHat Cheat Sheets/docker_cheatsheet_r4v2.pdf b/RedHat Cheat Sheets/docker_cheatsheet_r4v2.pdf new file mode 100644 index 0000000..0d1748a Binary files /dev/null and b/RedHat Cheat Sheets/docker_cheatsheet_r4v2.pdf differ diff --git a/RedHat Cheat Sheets/dotnet_cheatsheet_r5v1.pdf b/RedHat Cheat Sheets/dotnet_cheatsheet_r5v1.pdf new file mode 100644 index 0000000..62bd0ff Binary files /dev/null and b/RedHat Cheat Sheets/dotnet_cheatsheet_r5v1.pdf differ diff --git a/RedHat Cheat Sheets/event-emitter.pdf b/RedHat Cheat Sheets/event-emitter.pdf new file mode 100644 index 0000000..fd1f4f8 Binary files /dev/null and b/RedHat Cheat Sheets/event-emitter.pdf differ diff --git a/RedHat Cheat Sheets/linux-intermediate.pdf b/RedHat Cheat Sheets/linux-intermediate.pdf new file mode 100644 index 0000000..df1e197 Binary files /dev/null and b/RedHat Cheat Sheets/linux-intermediate.pdf differ diff --git a/RedHat Cheat Sheets/linux_cheatsheet_bw.pdf b/RedHat Cheat Sheets/linux_cheatsheet_bw.pdf new file mode 100644 index 0000000..cec1f80 Binary files /dev/null and b/RedHat Cheat Sheets/linux_cheatsheet_bw.pdf differ diff --git a/RedHat Cheat Sheets/npm-cli-20211119.pdf b/RedHat Cheat Sheets/npm-cli-20211119.pdf new file mode 100644 index 0000000..37ff222 Binary files /dev/null and b/RedHat Cheat Sheets/npm-cli-20211119.pdf differ diff --git a/RedHat Cheat Sheets/openshift_cheat_sheet_r5v1.pdf b/RedHat Cheat Sheets/openshift_cheat_sheet_r5v1.pdf new file mode 100644 index 0000000..cb6d0f4 Binary files /dev/null and b/RedHat Cheat Sheets/openshift_cheat_sheet_r5v1.pdf differ diff --git a/RedHat Cheat Sheets/podman_basics.pdf b/RedHat Cheat Sheets/podman_basics.pdf new file mode 100644 index 0000000..10211f4 Binary files /dev/null and b/RedHat Cheat Sheets/podman_basics.pdf differ diff --git a/RedHat Cheat Sheets/promises-async-await.pdf b/RedHat Cheat Sheets/promises-async-await.pdf new file mode 100644 index 0000000..bdf0180 Binary files /dev/null and b/RedHat Cheat Sheets/promises-async-await.pdf differ diff --git a/RedHat Cheat Sheets/systemd-commands-red-hat-developer.pdf b/RedHat Cheat Sheets/systemd-commands-red-hat-developer.pdf new file mode 100644 index 0000000..687ee09 Binary files /dev/null and b/RedHat Cheat Sheets/systemd-commands-red-hat-developer.pdf differ