From 745b75529622ae22b86ca8b20d89e7054c111cbc Mon Sep 17 00:00:00 2001 From: willtome Date: Tue, 7 Mar 2023 09:26:22 -0500 Subject: [PATCH] lint fixes --- .github/workflows/ansible-lint.yml | 16 ++ cloud/destroy_vm.yml | 19 -- .../cloud/roles/aws/tasks/create_infra.yml | 2 +- .../demo/cloud/roles/aws/tasks/create_vm.yml | 2 +- .../demo/cloud/roles/azure/defaults/main.yml | 17 -- .../cloud/roles/azure/tasks/create_infra.yml | 76 ------- .../cloud/roles/azure/tasks/create_vm.yml | 28 --- .../cloud/roles/azure/tasks/destroy_vm.yml | 8 - .../roles/report_server/files/css/new.css | 202 ------------------ .../files/redhat-ansible-logo.svg | 48 ----- .../roles/report_server/files/report.png | Bin 2098 -> 0 bytes .../report_server/files/webpage_logo.png | Bin 45921 -> 0 bytes .../tasks/linux_landing_page.yml | 34 --- .../roles/report_server/tasks/main.yml | 6 - .../tasks/windows_landing_page.yml | 34 --- .../roles/report_server/templates/header.j2 | 15 -- .../report_server/templates/linux_report.j2 | 42 ---- .../report_server/templates/windows_report.j2 | 42 ---- .../roles/report_server/vars/Win32NT.yml | 3 - .../roles/scap_client/tasks/main.yaml | 2 +- collections/requirements.yml | 8 +- linux/compliance.yml | 13 +- linux/deploy_application.yml | 38 ++-- linux/ec2_register.yml | 119 ++++++----- linux/fact_scan.yml | 15 +- linux/hardening.yml | 12 +- linux/insights_compliance_scan.yml | 13 +- linux/inventory.insights.yml | 4 +- linux/patching.yml | 72 ++++--- linux/patching_report.yml | 38 ---- linux/podman.yml | 81 ++++--- linux/run_script.yml | 16 +- linux/service_start.yml | 19 +- linux/service_stop.yml | 19 +- linux/setup.yml | 66 +++--- linux/system_roles.yml | 6 +- linux/temp_sudo.yml | 20 +- linux/tshoot.yml | 30 +-- network/report.yml | 6 +- network/setup.yml | 10 +- satellite/server_openscap.yml | 17 +- satellite/server_register.yml | 7 +- satellite/setup.yml | 14 +- satellite/setup_satellite.yml | 2 +- setup_demo.yml | 2 +- windows/backup.yml | 2 +- windows/create_ad_domain.yml | 80 +++---- windows/helpdesk_new_user_portal.yml | 62 +++--- windows/install_iis.yml | 10 +- windows/patching.yml | 39 ++-- windows/powershell.yml | 17 +- windows/powershell_dsc.yml | 66 +++--- windows/powershell_script.yml | 30 +-- windows/setup.yml | 38 ++-- windows/snow.yml | 32 --- windows/windows_choco_multiple.yml | 33 +-- windows/windows_choco_specific.yml | 8 +- 57 files changed, 525 insertions(+), 1135 deletions(-) create mode 100644 .github/workflows/ansible-lint.yml delete mode 100644 cloud/destroy_vm.yml delete mode 100644 collections/ansible_collections/demo/cloud/roles/azure/defaults/main.yml delete mode 100644 collections/ansible_collections/demo/cloud/roles/azure/tasks/create_infra.yml delete mode 100644 collections/ansible_collections/demo/cloud/roles/azure/tasks/create_vm.yml delete mode 100644 collections/ansible_collections/demo/cloud/roles/azure/tasks/destroy_vm.yml delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/files/css/new.css delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/files/redhat-ansible-logo.svg delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/files/report.png delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/files/webpage_logo.png delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/tasks/linux_landing_page.yml delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/tasks/main.yml delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/tasks/windows_landing_page.yml delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/templates/header.j2 delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/templates/linux_report.j2 delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/templates/windows_report.j2 delete mode 100644 collections/ansible_collections/demo/reporting/roles/report_server/vars/Win32NT.yml delete mode 100644 linux/patching_report.yml delete mode 100644 windows/snow.yml diff --git a/.github/workflows/ansible-lint.yml b/.github/workflows/ansible-lint.yml new file mode 100644 index 0000000..c8070fb --- /dev/null +++ b/.github/workflows/ansible-lint.yml @@ -0,0 +1,16 @@ +--- +name: Ansible Lint +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + # Important: This sets up your GITHUB_WORKSPACE environment variable + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # needed for progressive mode to work + + - name: Run ansible-lint + uses: ansible/ansible-lint-action@v6 diff --git a/cloud/destroy_vm.yml b/cloud/destroy_vm.yml deleted file mode 100644 index 94a6a4e..0000000 --- a/cloud/destroy_vm.yml +++ /dev/null @@ -1,19 +0,0 @@ ---- -- hosts: "{{ _hosts }}" - gather_facts: no - - tasks: - - name: list systems to be destroyed - debug: - msg: "{{ inventory_hostname }}" - - - name: pause for review... - pause: - seconds: 30 - prompt: "Systems listed above will be DESTROYED in 30 seconds. Cancel the job to Abort." - - - name: destroy vm - include_role: - name: "demo.cloud.aws" - tasks_from: destroy_vm - when: "'cloud_aws' in group_names or 'cloud_azure' in group_names" diff --git a/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_infra.yml b/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_infra.yml index 510aed5..5d296dd 100644 --- a/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_infra.yml +++ b/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_infra.yml @@ -115,4 +115,4 @@ state: present tags: owner: "{{ aws_vpc_name }}" - purpose: "{{ aws_purpose_tag }}" \ No newline at end of file + purpose: "{{ aws_purpose_tag }}" diff --git a/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_vm.yml b/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_vm.yml index 9c3a781..2fc236f 100644 --- a/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_vm.yml +++ b/collections/ansible_collections/demo/cloud/roles/aws/tasks/create_vm.yml @@ -44,4 +44,4 @@ wait: "{{ aws_ec2_wait }}" vpc_subnet_id: "{{ aws_subnet_id }}" user_data: "{{ lookup('template', aws_userdata_template+'.j2', template_vars=dict(aws_vm_name=vm_name)) }}" - register: aws_vm_output \ No newline at end of file + register: aws_vm_output diff --git a/collections/ansible_collections/demo/cloud/roles/azure/defaults/main.yml b/collections/ansible_collections/demo/cloud/roles/azure/defaults/main.yml deleted file mode 100644 index 085623d..0000000 --- a/collections/ansible_collections/demo/cloud/roles/azure/defaults/main.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -############## -# Azure Vars -############## -az_region: eastus -az_rg_name: ansible -az_rg_prefix: demo -az_vnet_cidr_block: 10.0.0.0/16 -az_subnet_cidr: 10.0.1.0/24 -az_vm_name: "{{ vm_name }}" -az_vm_owner: "{{ vm_owner }}" -az_blueprint: "{{ vm_blueprint }}" -az_vm_username: "{{ ansible_user }}" -az_vm_password: "{{ ansible_password }}" -az_env_tag: prod -az_purpose_tag: ansible_demo -az_ansiblegroup_tag: cloud diff --git a/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_infra.yml b/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_infra.yml deleted file mode 100644 index c7f5804..0000000 --- a/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_infra.yml +++ /dev/null @@ -1,76 +0,0 @@ ---- -- name: AZURE | CREATE INFRA | resource group - azure.azcollection.azure_rm_resourcegroup: - name: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - location: "{{ az_region }}" - -- name: AZURE | CREATE INFRA | virtual network - azure.azcollection.azure_rm_virtualnetwork: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ az_rg_name }}-{{ az_rg_prefix }}-vnet" - address_prefixes: "{{ az_vnet_cidr }}" - -- name: AZURE | CREATE INFRA | subnet - azure.azcollection.azure_rm_subnet: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ az_rg_name }}-{{ az_rg_prefix }}-subnet }}" - address_prefix: "{{ az_subnet_cidr }}" - virtual_network: "{{ az_rg_name }}-{{ az_rg_prefix }}-vnet" - -- name: AZURE | CREATE INFRA | security group - azure.azcollection.azure_rm_securitygroup: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ az_rg_name }}-{{ az_rg_prefix }}-sec-group" - rules: - - name: External - protocol: Tcp - destination_port_range: - - 80 # HTTP - - 443 # HTTPS - - 5986 # WinRM - - 3389 # RDP - access: Allow - priority: 1001 - direction: Inbound - - name: Ping - protocol: Icmp - access: Allow - priority: 1002 - direction: Inbound - - name: Internal TCP - protocol: Tcp - destination_port_range: - - 80 # HTTP - - 5986 # WinRM - - 3389 # RDP - - 53 # DNS - - 88 # Kerberos Authentication - - 135 # RPC - - 139 # Netlogon - - 389 # LDAP - - 445 # SMB - - 464 # Kerberos Authentication - - 5432 # PostgreSQL - - 636 # LDAPS (LDAP over TLS) - - 873 # Rsync - - 3268-3269 # Global Catalog - - 1024-65535 # Ephemeral RPC ports - access: Allow - priority: 1003 - direction: Inbound - source_address_prefix: "{{ az_vnet_cidr_block }}" - - name: Internal UDP - protocol: Udp - destination_port_range: - - 53 # DNS - - 88 # Kerberos Authentication - - 123 # NTP - - 137-138 # Netlogon - - 389 # LDAP - - 445 # SMB - - 464 # Kerberos Authentication - - 1024-65535 # Ephemeral RPC ports - access: Allow - priority: 1004 - direction: Inbound - source_address_prefix: "{{ az_vnet_cidr_block }}" \ No newline at end of file diff --git a/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_vm.yml b/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_vm.yml deleted file mode 100644 index 560bdc2..0000000 --- a/collections/ansible_collections/demo/cloud/roles/azure/tasks/create_vm.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -- name: AZURE | CREATE VM | vnet interface - azure.azcollection.azure_rm_networkinterface: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ az_vm_name }}_nic" - public_ip_name: "{{ az_vm_name }}_ip" - virtual_network: "{{ az_rg_name }}-{{ az_rg_prefix }}-vnet" - subnet: "{{ az_rg_name }}-{{ az_rg_prefix }}-subnet }}" - security_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-sec-group" - -- name: AZURE | CREATE VM | vm - azure.azcollection.azure_rm_virtualmachine: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ az_vm_name }}" - os_type: "{{ az_vm_os_type }}" - vm_size: "{{ az_vm_size }}" - admin_username: "{{ az_vm_username }}" - admin_password: "{{ az_vm_password }}" - network_interfaces: "{{ az_vm_name }}_nic" - image: "{{ az_vm_image }}" - tags: - blueprint: "{{ az_blueprint }}" - purpose: "{{ az_purpose_tag }}" - env: "{{ az_env_tag }}" - ansible_group: "{{ az_ansiblegroup_tag }}" - owner: "{{ az_vm_owner }}" - info: "This instance was built by Red Hat Product Demos" - Name: "{{ az_vm_name }}" diff --git a/collections/ansible_collections/demo/cloud/roles/azure/tasks/destroy_vm.yml b/collections/ansible_collections/demo/cloud/roles/azure/tasks/destroy_vm.yml deleted file mode 100644 index 9be4644..0000000 --- a/collections/ansible_collections/demo/cloud/roles/azure/tasks/destroy_vm.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- name: Destroy VM - azure.azcollection.azure_rm_virtualmachine: - resource_group: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg" - name: "{{ inventory_hostname }}" - state: absent - remove_on_absent: all_autocreated - delegate_to: localhost \ No newline at end of file diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/files/css/new.css b/collections/ansible_collections/demo/reporting/roles/report_server/files/css/new.css deleted file mode 100644 index 3266a46..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/files/css/new.css +++ /dev/null @@ -1,202 +0,0 @@ -p.hostname { - color: #000000; - font-weight: bolder; - font-size: large; - margin: auto; - width: 50%; - } - - #subtable { - background: #ebebeb; - margin: 0px; - width: 100%; - } - - #subtable tbody tr td { - padding: 5px 5px 5px 5px; - } - - #subtable thead th { - padding: 5px; - } - - * { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-family: "Open Sans", "Helvetica"; - - } - - a { - color: #000000; - } - - p { - color: #ffffff; - } - h1 { - text-align: center; - color: #ffffff; - } - - body { - background:#353a40; - padding: 0px; - margin: 0px; - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - } - - table { - border-collapse: separate; - background:#fff; - @include border-radius(5px); - @include box-shadow(0px 0px 5px rgba(0,0,0,0.3)); - } - - .main_net_table { - margin:50px auto; - } - - thead { - @include border-radius(5px); - } - - thead th { - font-size:16px; - font-weight:400; - color:#fff; - @include text-shadow(1px 1px 0px rgba(0,0,0,0.5)); - text-align:left; - padding:20px; - border-top:1px solid #858d99; - background: #353a40; - - &:first-child { - @include border-top-left-radius(5px); - } - - &:last-child { - @include border-top-right-radius(5px); - } - } - - tbody tr td { - font-weight:400; - color:#5f6062; - font-size:13px; - padding:20px 20px 20px 20px; - border-bottom:1px solid #e0e0e0; - } - - tbody tr:nth-child(2n) { - background:#f0f3f5; - } - - tbody tr:last-child td { - border-bottom:none; - &:first-child { - @include border-bottom-left-radius(5px); - } - &:last-child { - @include border-bottom-right-radius(5px); - } - } - - td { - vertical-align: top; - } - - span.highlight { - background-color: yellow; - } - - .expandclass { - color: #5f6062; - } - - .content{ - display:none; - margin: 10px; - } - - header { - width: 100%; - position: initial; - float: initial; - padding: 0; - margin: 0; - border-radius: 0; - height: 88px; - background-color: #171717; - } - - .header-container { - margin: 0 auto; - width: 100%; - height: 100%; - max-width: 1170px; - padding: 0; - float: initial; - display: flex; - align-items: center; - } - - .header-logo { - width: 137px; - border: 0; - margin: 0; - margin-left: 15px; - } - - .header-link { - margin-left: 40px; - text-decoration: none; - cursor: pointer; - text-transform: uppercase; - font-size: 15px; - font-family: 'Red Hat Text'; - font-weight: 500; - } - - .header-link:hover { - text-shadow: 0 0 0.02px white; - text-decoration: none; - } - - table.net_info td { - padding: 5px; -} - -p.expandclass:hover { - text-decoration: underline; - color: #EE0000; - cursor: pointer; -} - -.summary_info { -} - -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover { - border: 1px solid #5F0000; - background: #EE0000; -} - -div#net_content { - padding: 0px; - height: auto !important; -} - -img.router_image { - vertical-align: middle; - padding: 0px 10px 10px 10px; - width: 50px; -} - -table.net_info { - width: 100%; -} - -p.internal_label { - color: #000000; -} diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/files/redhat-ansible-logo.svg b/collections/ansible_collections/demo/reporting/roles/report_server/files/redhat-ansible-logo.svg deleted file mode 100644 index 2ecef98..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/files/redhat-ansible-logo.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - -Logo-Red_Hat-Ansible_Automation_Platform-A-Reverse-RGB - - - - - - - - - - - diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/files/report.png b/collections/ansible_collections/demo/reporting/roles/report_server/files/report.png deleted file mode 100644 index 3c38d52aa7bc061d1b59b509327669cf0e735627..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2098 zcmY*ad0bN48s#|TkQkUl4k=<@X=FAi zKFxkwX_iT(*`Sq0d9TBDsGKY9re)Rx^VxfQ|Mp&Me`kH`+u!-)oP0kYPq4C%G6)0$ z<8jyk39c-~brRNTkzFPMAT_|#4OG{yHz7IXkVEnNyuCqY60Qi62h>2aQi)`O03DG0 z3I~C91G;NG0NA#wkpY2nDImF3O}GRlL*}VulVq==EFbvg$d_4D2k>QoacN$a*#KPv zN-4OoR1he+MY;g-V1t&#EsPQr$_Vu)phz?-f*4ENOGdD$Dbg$unuU^3Dw#oqv8YMO zsVEi(zM?=$xHOD}!&W4WL<~IC+YjbWqmyBF2rGmY+({V*gQ4lM`%nQ`kJWU^2?LL3 zFj7!RB$LTRFt;OU^f;uogM$Oo$_8m;V<}Nsrm~Y6M3!Z8s?krA|N3CbsU$ijg+ZYu z!=%2%y|e=i3>+>kv^IX;lR??{t5S06YFm;9k%<;T;(?UdupG7s$*3MwvcZMj|n0X_6GpoWu)sS7Oe5!c0w???CvV+xwXv6cyWbIkn;v|8C6^ zSJdA@C@(JuUL86RN&In67(He7GU#`r_d~`w-PLo@Bg`1BhD2*MqADRhwe3dKr3t=4 zZ1PNLGJzV)^?EUBAT%7-7>*i_1G)wlDo@V}6y~lLIIHVx-q9Fw4Y{V;yz|QbQsIJJ zNxg=ORaRXDzOJc|i!tZFE)!yeG{ba{;djCyeS8~XSeG*;_vu@N%XD?&3sK1X$Hx~B z`>B#MHhi>K7sHUdmGYK$?bKIqvCYv{u=r-mnRwhGlTTaETz~WqCg_>04JYK!w^ix4 zp2>=-r7@)Td4v}1Nvg*cXyF%e%OCPYUGnRl_X-jRP zukz&_f!yz&X?uCqRiA5k)}022(|lq`Z0{pjbnlqc`NiHWdtJ1qwj--B*z8u3p_=f+ z9mgC}JK~aqerGt_>p_GnVVwTGwwILmDd_&a4}`pB|G$F^(dcIf)CYR9$F*=c7#cCu zb9RcX!o99-Ll_ejI3uhE`hIKG4^W_o`QDzGR>{9cLCSL*NyHkXe$_f&`5acav;db@ zVXvl-@0;(}GK{(zSP?%O0G;@(H)}z(OL1sauzYvp(;q6faQiJud;a+?Fl|qU!(7-o z_9T`SJRV+lvOMIiPn9o7PhioV+Jf8puKL)l6M(+BI4`ro^Fj9GN}IUiF+~3SWVSFh zv#DOg$vj5OUg>^pw?2i(YKd((+RBZDJ!b|&Hgy)Np%mcFUNVBJ#e=Ue;%2aJFkkLn zl+CRq^M8eG=Z>$-)Es#^86nuqGEkVB;+z0PU4rM^6ODPfBE_LG5v+$S5^$^Y$69Z6 z-y1<1jIegdg>y|ej7?v6se2&;&OIC(^ zhxRk|m|xCZU8Ir{WX0M&fk|SQ`s^t4FULkp_WSf-FDed5zBlvKGq?c=bMzl&Db@oJ z=O=FkDvy|kbdwxsi;MU=vw2$eJ*^bQ=;843zaHh!^KzT>MT&Qe4qZ-hySpt9p3Ek2 zjf6X7az_0j%yThp98~oUI(3YYpPPZy)39j74>rlfy?Dj(mERZj%3)7mZ{d5}A}xp}dv1IZ&&gk}L=)Gf+V>UVT6MA*^OW7}o)$lQ_`72p`8{rP>_UN>NA2Xj z#78xAr<{*xdW^YLey!O7U)rP-I+&-23yN;?h&6DReWc5k&7TyA^QKAhF>E6`%s>65 z4mVu|Y(c}SZmFpcPk=8oI*8Ff0!t$7bMXw^^3yEO5XBxy;_Vw9Y*uJeq{e1sb>64( zujwiUVubi*OYw7i4Q>>Cv7#(vBdoU1h#i+xly@My>U!%X7!Uf-iPpyw3Td)8C diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/files/webpage_logo.png b/collections/ansible_collections/demo/reporting/roles/report_server/files/webpage_logo.png deleted file mode 100644 index 65b583651477a4982270f263a8b4cf7a1d540d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45921 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 OChjR~-pRjh5%fP`|GmQi diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/linux_landing_page.yml b/collections/ansible_collections/demo/reporting/roles/report_server/tasks/linux_landing_page.yml deleted file mode 100644 index 30419e3..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/linux_landing_page.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- include_vars: "{{ ansible_system }}.yml" - -- name: get reports - ansible.builtin.find: - paths: "{{ doc_root }}/{{ reports_dir }}" - patterns: '*.html' - register: reports - check_mode: no - -- name: publish landing page - ansible.builtin.template: - src: linux_report.j2 - dest: "{{ doc_root }}/index.html" - check_mode: no - -- name: copy CSS over - ansible.builtin.copy: - src: "css" - dest: "{{ doc_root }}" - directory_mode: true - check_mode: no - -- name: copy logos over - ansible.builtin.copy: - src: "{{ item }}" - dest: "{{ doc_root }}" - directory_mode: true - loop: - - "webpage_logo.png" - - "redhat-ansible-logo.svg" - - "report.png" - check_mode: no - diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/main.yml b/collections/ansible_collections/demo/reporting/roles/report_server/tasks/main.yml deleted file mode 100644 index a275ceb..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- include_tasks: apache.yml - when: ansible_system == 'Linux' - -- include_tasks: iis.yml - when: ansible_system == 'Win32NT' diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/windows_landing_page.yml b/collections/ansible_collections/demo/reporting/roles/report_server/tasks/windows_landing_page.yml deleted file mode 100644 index 76574c9..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/tasks/windows_landing_page.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -- include_vars: "{{ ansible_system }}.yml" - -- name: get reports - ansible.windows.win_find: - paths: "{{ doc_root }}/{{ reports_dir }}" - patterns: '*.html' - register: reports - check_mode: no - -- name: publish landing page - ansible.builtin.win_template: - src: windows_report.j2 - dest: "{{ doc_root }}/index.html" - check_mode: no - -- name: copy CSS over - ansible.builtin.win_copy: - src: "css" - dest: "{{ doc_root }}" - directory_mode: true - check_mode: no - -- name: copy logos over - ansible.builtin.win_copy: - src: "{{ item }}" - dest: "{{ doc_root }}" - directory_mode: true - loop: - - "webpage_logo.png" - - "redhat-ansible-logo.svg" - - "report.png" - check_mode: no - diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/templates/header.j2 b/collections/ansible_collections/demo/reporting/roles/report_server/templates/header.j2 deleted file mode 100644 index 6d504d0..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/templates/header.j2 +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
- - - -
-
\ No newline at end of file diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/templates/linux_report.j2 b/collections/ansible_collections/demo/reporting/roles/report_server/templates/linux_report.j2 deleted file mode 100644 index 201d930..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/templates/linux_report.j2 +++ /dev/null @@ -1,42 +0,0 @@ - - - - Ansible Linux Automation Report - - - - - - - - - -
- {% include 'header.j2' %} -
-
-

Ansible Automation Reports

-

-

- - -{% for report in reports.files %} - {% set page = report.path.split('/')[-1] %} - - - -{% endfor %} - -
-
-

-
-
- {{ page }} -
-

Created with


-
-
-
- - diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/templates/windows_report.j2 b/collections/ansible_collections/demo/reporting/roles/report_server/templates/windows_report.j2 deleted file mode 100644 index 5690437..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/templates/windows_report.j2 +++ /dev/null @@ -1,42 +0,0 @@ - - - - Ansible Linux Automation Report - - - - - - - - - -
- {% include 'header.j2' %} -
-
-

Ansible Automation Reports

-

-

- - -{% for report in reports.files %} - {% set page = report.path.split('\\')[-1] %} - - - -{% endfor %} - -
-
-

-
-
- {{ page }} -
-

Created with


-
-
-
- - diff --git a/collections/ansible_collections/demo/reporting/roles/report_server/vars/Win32NT.yml b/collections/ansible_collections/demo/reporting/roles/report_server/vars/Win32NT.yml deleted file mode 100644 index ac4e675..0000000 --- a/collections/ansible_collections/demo/reporting/roles/report_server/vars/Win32NT.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -doc_root: C:\Inetpub\wwwroot -reports_dir: reports diff --git a/collections/ansible_collections/demo/satellite/roles/scap_client/tasks/main.yaml b/collections/ansible_collections/demo/satellite/roles/scap_client/tasks/main.yaml index 1f8d01a..8dc130f 100644 --- a/collections/ansible_collections/demo/satellite/roles/scap_client/tasks/main.yaml +++ b/collections/ansible_collections/demo/satellite/roles/scap_client/tasks/main.yaml @@ -70,7 +70,7 @@ template: src: openscap_client_config.yaml.j2 dest: /etc/foreman_scap_client/config.yaml - mode: 0644 + mode: "0644" owner: root group: root diff --git a/collections/requirements.yml b/collections/requirements.yml index 67801fa..a8d98a2 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -4,7 +4,7 @@ collections: version: 4.3.0 - name: redhat_cop.controller_configuration version: 2.2.5 - #linux + # linux - name: redhat.insights version: 1.0.7 - name: redhat.rhel_system_roles @@ -12,18 +12,18 @@ collections: - name: community.general version: 6.3.0 - name: containers.podman - #windows + # windows - name: chocolatey.chocolatey - name: community.windows version: 1.12.0 - name: ansible.windows version: 1.13.0 - #cloud + # cloud - name: azure.azcollection version: 1.14.0 - name: amazon.aws version: 5.2.0 - #satellite + # satellite - name: redhat.satellite version: 3.8.0 #network diff --git a/linux/compliance.yml b/linux/compliance.yml index 865dab3..3c4642c 100644 --- a/linux/compliance.yml +++ b/linux/compliance.yml @@ -1,14 +1,15 @@ --- -- hosts: "{{ HOSTS }}" +- name: Apply compliance profile + hosts: "{{ _hosts | default(omit) }}" become: true vars: compliance_profile: undef tasks: - - name: Check OS Type - assert: + - name: Check os type + ansible.builtin.assert: that: "ansible_os_family == 'RedHat'" - - name: Run Compliance Profile - include_role: - name: "redhatofficial.rhel{{ ansible_distribution_major_version }}_{{ compliance_profile }}" \ No newline at end of file + - name: Run compliance profile + ansible.builtin.include_role: + name: "redhatofficial.rhel{{ ansible_distribution_major_version }}_{{ compliance_profile }}" diff --git a/linux/deploy_application.yml b/linux/deploy_application.yml index 98598b7..eca3563 100644 --- a/linux/deploy_application.yml +++ b/linux/deploy_application.yml @@ -1,31 +1,31 @@ --- -- name: application deployment - hosts: "{{ HOSTS }}" +- name: Application deployment + hosts: "{{ _hosts | default('web') }}" gather_facts: false become: true - + tasks: - - name: make sure application is not empty - assert: + - name: Make sure application is not empty + ansible.builtin.assert: that: - "application != ''" - - name: printing to terminal application information - debug: - msg: "This Ansible Playbook will install {{application}}" + - name: Printing to terminal application information + ansible.builtin.debug: + msg: "This Ansible Playbook will install {{ application }}" - - name: install application - dnf: - name: "{{application}}" + - name: Install application + ansible.builtin.dnf: + name: "{{ application }}" allow_downgrade: true register: result - - name: printing to terminal application information - debug: - msg: "The application: {{application}} has been installed" - when: result.changed|bool + - name: Printing to terminal application information + ansible.builtin.debug: + msg: "The application: {{ application }} has been installed" + when: result.changed | bool - - name: printing to terminal application information - debug: - msg: "The application: {{application}} was already installed" - when: not result.changed|bool + - name: Printing to terminal application information + ansible.builtin.debug: + msg: "The application: {{ application }} was already installed" + when: not result.changed | bool diff --git a/linux/ec2_register.yml b/linux/ec2_register.yml index d48705c..789209d 100644 --- a/linux/ec2_register.yml +++ b/linux/ec2_register.yml @@ -1,72 +1,73 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Register ec2 instance with subscription mangler + hosts: "{{ _hosts | default(omit) }}" + become: true tasks: - - name: check for vars - assert: - that: - - org_id is defined - - activation_key is defined - - org_id != '' - - activation_key != '' - - org_id != 'undef' - - activation_key != 'undef' + - name: Check for vars + ansible.builtin.assert: + that: + - org_id is defined + - activation_key is defined + - org_id != '' + - activation_key != '' + - org_id != 'undef' + - activation_key != 'undef' - - name: set hostname - hostname: - name: "{{ inventory_hostname | regex_replace('_','-')}}" + - name: Set hostname + ansible.builtin.hostname: + name: "{{ inventory_hostname | regex_replace('_', '-') }}" # Install subscription-manager if it's not there - - name: Install subscription-manager - ansible.builtin.yum: - name: subscription-manager - state: present + - name: Install subscription-manager + ansible.builtin.yum: + name: subscription-manager + state: present - - name: remove rhui client packages - yum: - name: rh-amazon-rhui-client* - state: removed + - name: Remove rhui client packages + ansible.builtin.yum: + name: rh-amazon-rhui-client* + state: removed - - name: get current repos - command: - cmd: ls /etc/yum.repos.d/ - register: repos - changed_when: False + - name: Get current repos + ansible.builtin.command: + cmd: ls /etc/yum.repos.d/ + register: repos + changed_when: false - - name: remove existing rhui repos - file: - path: "/etc/yum.repos.d/{{ item }}" - state: absent - loop: "{{ repos.stdout_lines }}" - when: "'rhui' in item" + - name: Remove existing rhui repos + ansible.builtin.file: + path: "/etc/yum.repos.d/{{ item }}" + state: absent + loop: "{{ repos.stdout_lines }}" + when: "'rhui' in item" - - name: install katello package - yum: - name: "https://{{ sat_url }}/pub/katello-ca-consumer-latest.noarch.rpm" - state: present - validate_certs: no - disable_gpg_check: true - when: sat_url is defined + - name: Install katello package + ansible.builtin.yum: + name: "https://{{ sat_url }}/pub/katello-ca-consumer-latest.noarch.rpm" + state: present + validate_certs: false + disable_gpg_check: true + when: sat_url is defined - - name: manage repos with subscription mangler - ansible.builtin.lineinfile: - path: /etc/rhsm/rhsm.conf - regexp: '^manage_repos' - line: 'manage_repos = 1' + - name: Manage repos with subscription mangler + ansible.builtin.lineinfile: + path: /etc/rhsm/rhsm.conf + regexp: '^manage_repos' + line: 'manage_repos = 1' - - name: register subscription mangler - community.general.redhat_subscription: - state: present - activationkey: "{{ activation_key }}" - org_id: "{{ org_id }}" + - name: Register subscription mangler + community.general.redhat_subscription: + state: present + activationkey: "{{ activation_key }}" + org_id: "{{ org_id }}" - - name: configure Red Hat insights - import_role: - name: redhat.insights.insights_client - vars: - insights_display_name: "{{ inventory_hostname }}" - insights_tags: - env: "{{ env }}" - purpose: demo - group: "{{ insights_tag }}" + - name: Configure Red Hat insights + ansible.builtin.import_role: + name: redhat.insights.insights_client + vars: + insights_display_name: "{{ inventory_hostname }}" + insights_tags: + env: "{{ env }}" + purpose: demo + group: "{{ insights_tag }}" diff --git a/linux/fact_scan.yml b/linux/fact_scan.yml index 1c26ff0..94907f3 100644 --- a/linux/fact_scan.yml +++ b/linux/fact_scan.yml @@ -1,12 +1,11 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Scan host for facts + hosts: "{{ _hosts | default(omit) }}" + become: true tasks: - - name: get packages - ansible.builtin.package_facts: + - name: Get packages + ansible.builtin.package_facts: - - name: get services - ansible.builtin.service_facts: - - \ No newline at end of file + - name: Get services + ansible.builtin.service_facts: diff --git a/linux/hardening.yml b/linux/hardening.yml index 67f1392..750a120 100644 --- a/linux/hardening.yml +++ b/linux/hardening.yml @@ -1,6 +1,6 @@ --- -- name: harden linux systems - hosts: "{{ HOSTS | default('web') }}" +- name: Harden linux systems + hosts: "{{ _hosts | default('web') }}" become: true vars: - harden_firewall: false @@ -11,21 +11,21 @@ tasks: - name: Configure Firewall when: harden_firewall | bool - include_role: + ansible.builtin.include_role: name: linux-system-roles.firewall - name: Configure Timesync when: harden_time | bool - include_role: + ansible.builtin.include_role: name: redhat.rhel_system_roles.timesync - name: SSH Hardening when: harden_ssh | bool - include_role: + ansible.builtin.include_role: name: dev-sec.ssh-hardening # run with --skip-tags accounts_passwords_pam_faillock_deny - name: Apply PCI Baseline when: harden_pci | bool - include_role: + ansible.builtin.include_role: name: redhatofficial.rhel8_pci_dss diff --git a/linux/insights_compliance_scan.yml b/linux/insights_compliance_scan.yml index 6faa0d4..69a44f0 100644 --- a/linux/insights_compliance_scan.yml +++ b/linux/insights_compliance_scan.yml @@ -1,24 +1,25 @@ --- -- hosts: "{{ HOSTS }}" +- name: Run compliance scan with Red Hat Insights + hosts: "{{ _hosts | default(omit) }}" become: true vars: - #compliance_profile: undef + # compliance_profile: undef tasks: - name: Check OS Type - assert: + ansible.builtin.assert: that: "ansible_os_family == 'RedHat'" - name: Check variable values - debug: + ansible.builtin.debug: msg: "Value of compliance_profile_configured is {{ compliance_profile_configured }}" - name: Run Insights Compliance scan - import_role: + ansible.builtin.import_role: name: redhat.insights.compliance when: compliance_profile_configured == "Yes" - name: Notify user that Compliance scan is not being attempted - debug: + ansible.builtin.debug: msg: "User has not confirmed that all hosts are associated with an Insights Compliance profile. Scan aborted." when: compliance_profile_configured == "No" diff --git a/linux/inventory.insights.yml b/linux/inventory.insights.yml index e9a1ebd..c9e6f79 100644 --- a/linux/inventory.insights.yml +++ b/linux/inventory.insights.yml @@ -1,11 +1,11 @@ --- plugin: redhat.insights.insights -get_patches: yes +get_patches: true groups: patch_bugs: insights_patching.rhba_count > 0 patch_enhancements: insights_patching.rhea_count > 0 patch_security: insights_patching.rhsa_count > 0 -get_tags: yes +get_tags: true selection: none filter_tags: - insights-client/purpose=demo diff --git a/linux/patching.yml b/linux/patching.yml index 582f33e..a4d2e82 100644 --- a/linux/patching.yml +++ b/linux/patching.yml @@ -1,43 +1,47 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Linux server patching + hosts: "{{ _hosts | default(omit) }}" + become: true + strategy: linear vars: report_server: node1 - + tasks: -# Install yum-utils if it's not there - - name: Install yum-utils - ansible.builtin.yum: - name: yum-utils - state: latest + # Install yum-utils if it's not there + - name: Install yum-utils + ansible.builtin.yum: + name: yum-utils + state: installed - - include_role: - name: demo.patching.patch_linux + - name: Include patching role + ansible.builtin.include_role: + name: demo.patching.patch_linux - - name: Tell user when Insights Client is not configured - debug: - msg: "Insights client does not appear to be configured. Scan will be skipped" - when: - - ansible_local.insights.system_id is not defined + - name: Tell user when Insights Client is not configured + ansible.builtin.debug: + msg: "Insights client does not appear to be configured. Scan will be skipped" + when: + - ansible_local.insights.system_id is not defined - - name: Run the Insights Client Scan - command: insights-client - when: - - not ansible_check_mode - - ansible_local.insights.system_id is defined + - name: Run the Insights Client Scan + ansible.builtin.command: insights-client + when: + - not ansible_check_mode + - ansible_local.insights.system_id is defined - - block: + - name: Deploy report server + delegate_to: "{{ report_server }}" + run_once: true + block: + - name: Build report server + ansible.builtin.include_role: + name: "{{ item }}" + loop: + - demo.patching.report_server + - demo.patching.report_linux + - demo.patching.report_linux_patching - - include_role: - name: "{{ item }}" - loop: - - demo.patching.report_server - - demo.patching.report_linux - - demo.patching.report_linux_patching - - - include_role: - name: demo.patching.report_server - tasks_from: linux_landing_page - - delegate_to: "{{ report_server }}" - run_once: yes + - name: Publish landing page + ansible.builtin.include_role: + name: demo.patching.report_server + tasks_from: linux_landing_page diff --git a/linux/patching_report.yml b/linux/patching_report.yml deleted file mode 100644 index 3c83a8c..0000000 --- a/linux/patching_report.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- hosts: "{{ HOSTS }}" - become: yes - vars: - report_server: node1 - - tasks: - - include_role: - name: demo.patching.patch_linux - - - block: - - yum: - name: httpd - state: latest - check_mode: no - - - file: - path: /var/www/html/reports/ - state: directory - check_mode: no - - - copy: - dest: /var/www/html/reports/.htaccess - content: Options +Indexes - check_mode: no - - - service: - name: httpd - state: started - check_mode: no - - - include_role: - name: demo.patching.report_linux - - - include_role: - name: demo.patching.report_linux_patching - delegate_to: "{{ report_server }}" - run_once: yes \ No newline at end of file diff --git a/linux/podman.yml b/linux/podman.yml index fb295e5..fe8f673 100644 --- a/linux/podman.yml +++ b/linux/podman.yml @@ -1,54 +1,53 @@ --- - name: Podman - hosts: "{{ HOSTS }}" - + hosts: "{{ _hosts | default(omit) }}" vars: volume_path: podman message: undef tasks: - - name: Install Podman - ansible.builtin.dnf: - name: podman - state: latest - become: yes + - name: Install Podman + ansible.builtin.dnf: + name: podman + state: installed + become: true - - name: Create volume dir - ansible.builtin.file: - path: "{{ volume_path }}" - state: directory + - name: Create volume dir + ansible.builtin.file: + path: "{{ volume_path }}" + state: directory - - name: Create index.html - ansible.builtin.copy: - dest: "{{ volume_path }}/index.html" - content: "{{ message }}" + - name: Create index.html + ansible.builtin.copy: + dest: "{{ volume_path }}/index.html" + content: "{{ message }}" - - name: Run httpd container - containers.podman.podman_container: - name: apache - image: docker.io/httpd - state: started - volume: - - "./{{ volume_path }}/:/usr/local/apache2/htdocs:z" - ports: - - "8080:80" + - name: Run httpd container + containers.podman.podman_container: + name: apache + image: docker.io/httpd + state: started + volume: + - "./{{ volume_path }}/:/usr/local/apache2/htdocs:z" + ports: + - "8080:80" - - name: Check Web Page - ansible.builtin.uri: - url: http://127.0.0.1:8080 - return_content: yes - register: web_output - changed_when: false + - name: Check Web Page + ansible.builtin.uri: + url: http://127.0.0.1:8080 + return_content: true + register: web_output + changed_when: false - - name: podman ps - shell: podman ps - register: podman_output - changed_when: false + - name: Podman ps + ansible.builtin.command: podman ps + register: podman_output + changed_when: false - - name: Output - ansible.builtin.debug: - msg: - - "Output of podman ps command:" - - "{{ podman_output.stdout_lines }}" - - "Contents of web page:" - - "{{ web_output.content }}" + - name: Output + ansible.builtin.debug: + msg: + - "Output of podman ps command:" + - "{{ podman_output.stdout_lines }}" + - "Contents of web page:" + - "{{ web_output.content }}" diff --git a/linux/run_script.yml b/linux/run_script.yml index 8a9ae65..e4159f4 100644 --- a/linux/run_script.yml +++ b/linux/run_script.yml @@ -1,20 +1,22 @@ --- - name: Run Shell Script - hosts: "{{ HOSTS }}" - become: yes - gather_facts: no + hosts: "{{ _hosts | default(omit) }}" + become: true + gather_facts: false vars: shell_script: undef tasks: - name: Run Shell Script - shell: "{{ shell_script }}" + ansible.builtin.shell: "{{ shell_script }}" register: shell_output + tags: + - skip_ansible_lint # provided variable could require shell modele - name: Print script output - debug: + ansible.builtin.debug: var: shell_output.stdout_lines - - debug: + - name: Print message + ansible.builtin.debug: msg: You should really consider converting this script to a playbook! - run_once: yes diff --git a/linux/service_start.yml b/linux/service_start.yml index b8b650a..8e7a8d1 100644 --- a/linux/service_start.yml +++ b/linux/service_start.yml @@ -1,15 +1,16 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Start service + hosts: "{{ _hosts | default(omit) }}" + become: true vars: service_name: undef tasks: - - name: Check Service - service_facts: + - name: Check Service + ansible.builtin.service_facts: - - name: Start Service - service: - name: "{{ service_name }}" - state: started - when: service_name + '.service' in services + - name: Start Service + ansible.builtin.service: + name: "{{ service_name }}" + state: started + when: service_name + '.service' in services diff --git a/linux/service_stop.yml b/linux/service_stop.yml index 4cfb791..f8104fe 100644 --- a/linux/service_stop.yml +++ b/linux/service_stop.yml @@ -1,15 +1,16 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Stop service + hosts: "{{ _hosts | default(omit) }}" + become: true vars: service_name: undef tasks: - - name: Check Service - service_facts: + - name: Check Service + ansible.builtin.service_facts: - - name: Stop Service - service: - name: "{{ service_name }}" - state: stopped - when: service_name + '.service' in services + - name: Stop Service + ansible.builtin.service: + name: "{{ service_name }}" + state: stopped + when: service_name + '.service' in services diff --git a/linux/setup.yml b/linux/setup.yml index 6efc910..e2ea28c 100644 --- a/linux/setup.yml +++ b/linux/setup.yml @@ -1,6 +1,6 @@ --- user_message: - - Be sure to update the 'activation_key' and 'org_id' extra variables for 'LINUX / Register with Insights'. https://access.redhat.com/management/activation_keys + - Update the 'activation_key' and 'org_id' extra variables for 'LINUX / Register with Insights'. https://access.redhat.com/management/activation_keys - Update Credential for Insights Inventory with Red Hat account. - Add variables for system_roles. https://console.redhat.com/ansible/automation-hub/repo/published/redhat/rhel_system_roles controller_components: @@ -53,7 +53,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true extra_vars: activation_key: !unsafe "RHEL{{ ansible_distribution_major_version }}_{{ env }}" @@ -64,7 +64,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Choose Environment type: multiplechoice @@ -93,7 +93,7 @@ controller_templates: notification_templates_error: Telemetry use_fact_cache: true credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -101,7 +101,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - name: "LINUX / Temporary Sudo" @@ -113,7 +113,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -121,7 +121,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: User Name type: text @@ -143,9 +143,9 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry use_fact_cache: true - ask_job_type_on_launch: yes + ask_job_type_on_launch: true credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -153,7 +153,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - name: "LINUX / Start Service" @@ -166,7 +166,7 @@ controller_templates: notification_templates_error: Telemetry use_fact_cache: true credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -174,7 +174,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Service Name type: text @@ -191,7 +191,7 @@ controller_templates: notification_templates_error: Telemetry use_fact_cache: true credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -199,7 +199,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Service Name type: text @@ -215,7 +215,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -223,7 +223,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Shell Script type: textarea @@ -248,7 +248,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - name: "LINUX / Podman Webserver" @@ -260,7 +260,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -268,7 +268,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Web Page Message type: textarea @@ -284,15 +284,15 @@ controller_templates: notification_templates_started: Telemetry notification_templates_success: Telemetry notification_templates_error: Telemetry - diff_mode: yes - ask_job_type_on_launch: yes + diff_mode: true + ask_job_type_on_launch: true extra_vars: system_roles: - selinux selinux_policy: targeted selinux_state: enforcing credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -300,7 +300,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - name: "LINUX / Install Web Console (cockpit)" @@ -311,10 +311,10 @@ controller_templates: notification_templates_started: Telemetry notification_templates_success: Telemetry notification_templates_error: Telemetry - diff_mode: yes - ask_job_type_on_launch: yes + diff_mode: true + ask_job_type_on_launch: true extra_vars: - system_roles: + system_roles: - cockpit credentials: - "Workshop Credential" @@ -325,7 +325,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Cockpit package load type: multiplechoice @@ -346,7 +346,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" extra_vars: sudo_remove_nopasswd: false survey_enabled: true @@ -356,7 +356,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Compliance Profile type: multiplechoice @@ -371,7 +371,7 @@ controller_templates: project: "Ansible official demo project" playbook: "linux/insights_compliance_scan.yml" credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -379,7 +379,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Have you associated a compliance profile in the Insights Console for all hosts to be scanned? If not, then the scan will fail. type: multiplechoice @@ -400,7 +400,7 @@ controller_templates: notification_templates_error: Telemetry use_fact_cache: true credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -408,7 +408,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: true - question_name: Application Package Name type: text diff --git a/linux/system_roles.yml b/linux/system_roles.yml index 6ad1a8f..a6c8fcc 100644 --- a/linux/system_roles.yml +++ b/linux/system_roles.yml @@ -1,14 +1,14 @@ --- - name: Apply RHEL System Roles - hosts: "{{ HOSTS }}" + hosts: "{{ _hosts | default(omit) }}" become: true vars: system_roles: undef tasks: - name: Apply System Roles - include_role: + ansible.builtin.include_role: name: "redhat.rhel_system_roles.{{ item }}" loop: "{{ system_roles }}" when: - - system_roles | d("") | length > 0 \ No newline at end of file + - system_roles | d("") | length > 0 diff --git a/linux/temp_sudo.yml b/linux/temp_sudo.yml index b7b6460..87d2e5d 100644 --- a/linux/temp_sudo.yml +++ b/linux/temp_sudo.yml @@ -1,8 +1,8 @@ --- - name: Temporary Sudo - hosts: "{{ HOSTS }}" - become: yes - gather_facts: no + hosts: "{{ _hosts | default(omit) }}" + become: true + gather_facts: false vars: sudo_cleanup: true sudo_user: undef @@ -11,31 +11,31 @@ tasks: - name: Check if sudo user exists on system - getent: + ansible.builtin.getent: database: passwd key: "{{ sudo_user }}" - name: Check Cleanup package - yum: + ansible.builtin.yum: name: at state: present - name: Check Cleanup Service - service: + ansible.builtin.service: name: atd state: started - name: Create Sudo Rule - copy: + ansible.builtin.copy: dest: "/etc/sudoers.d/{{ sudo_user }}" owner: root group: root - mode: 0640 + mode: "0640" content: "{{ sudo_user }} ALL=(ALL) NOPASSWD:ALL" - name: Set Permission Cleanup - at: + ansible.posix.at: command: "rm /etc/sudoers.d/{{ sudo_user }}" count: "{{ sudo_time }}" units: "{{ sudo_units }}" - when: sudo_cleanup|bool + when: sudo_cleanup | bool diff --git a/linux/tshoot.yml b/linux/tshoot.yml index 51c3499..333e4d0 100644 --- a/linux/tshoot.yml +++ b/linux/tshoot.yml @@ -1,29 +1,29 @@ --- -- name: gather debug info - hosts: "{{ HOSTS }}" - become: yes +- name: Gather debug info + hosts: "{{ _hosts | default(omit) }}" + become: true tasks: - name: Gather recent vmstat info - command: /bin/vmstat 1 5 + ansible.builtin.command: /bin/vmstat 1 5 register: vmstat - + - name: Gather top CPU hogs - command: ps -eo user,pid,size,pcpu,cmd --sort=-pcpu + ansible.builtin.command: ps -eo user,pid,size,pcpu,cmd --sort=-pcpu register: pscpu - + - name: Gather top memory hogs - command: ps -eo user,pid,size,pcpu,cmd --sort=-size + ansible.builtin.command: ps -eo user,pid,size,pcpu,cmd --sort=-size register: pssize - + - name: Swap + wait states - debug: + ansible.builtin.debug: var: vmstat.stdout_lines - + - name: Top 3 CPU hogs - debug: + ansible.builtin.debug: var: pscpu.stdout_lines[:4] - + - name: Top 3 memory hogs - debug: - var: pssize.stdout_lines[:4] \ No newline at end of file + ansible.builtin.debug: + var: pssize.stdout_lines[:4] diff --git a/network/report.yml b/network/report.yml index a475195..4e4eeea 100644 --- a/network/report.yml +++ b/network/report.yml @@ -4,7 +4,7 @@ # https://github.com/network-automation/toolkit/blob/master/roles/build_report/tasks/main.yml - name: Collect facts - hosts: "{{ HOSTS }}" + hosts: "{{ _hosts | default(omit) }}" gather_facts: false tasks: @@ -32,7 +32,7 @@ # ansible_host: "{{ lookup('community.general.dig', inventory_hostname)}}" - hosts: node1 - become: yes + become: true vars: report_server: node1 web_path: /var/www/html/reports/ @@ -50,7 +50,7 @@ loop: - demo.patching.report_server - demo.patching.build_report_network - + - ansible.builtin.include_role: name: demo.patching.report_server tasks_from: linux_landing_page diff --git a/network/setup.yml b/network/setup.yml index 100bc02..37409d6 100644 --- a/network/setup.yml +++ b/network/setup.yml @@ -14,8 +14,8 @@ controller_projects: organization: Default scm_type: git scm_url: https://github.com/nleiva/ansible-net-modules - update_project: yes - wait: yes + update_project: true + wait: true controller_inventories: - name: Network Inventory @@ -47,7 +47,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry ask_limit_on_launch: true - use_fact_cache: yes + use_fact_cache: true survey: name: '' description: '' @@ -79,7 +79,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry use_fact_cache: true - ask_job_type_on_launch: yes + ask_job_type_on_launch: true credentials: - "Workshop Credential" survey_enabled: true @@ -89,7 +89,7 @@ controller_templates: spec: - question_name: What devices do you want to include in the report? type: multiplechoice - variable: HOSTS + variable: _hosts default: routers required: true choices: diff --git a/satellite/server_openscap.yml b/satellite/server_openscap.yml index ac5129b..0caa1da 100644 --- a/satellite/server_openscap.yml +++ b/satellite/server_openscap.yml @@ -1,16 +1,17 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Run openSCAP scan + hosts: "{{ _hosts | default(omit) }}" + become: true vars: policy_name: all roles: - demo.satellite.scap_client tasks: - - name: Randomized startup delay... - pause: seconds="{{ 5 | random }}" + - name: Randomized startup delay... + ansible.builtin.pause: seconds="{{ 5 | random }}" - - name: "Run SCAP Scan" - shell: "/usr/bin/foreman_scap_client {{ item.id }}" - loop: "{{ policy }}" - when: policy_scan == 'all' or item.name in policy_scan + - name: Run SCAP Scan + ansible.builtin.shell: "/usr/bin/foreman_scap_client {{ item.id }}" + loop: "{{ policy }}" + when: policy_scan == 'all' or item.name in policy_scan diff --git a/satellite/server_register.yml b/satellite/server_register.yml index 0ee988a..c08a0ad 100644 --- a/satellite/server_register.yml +++ b/satellite/server_register.yml @@ -1,8 +1,9 @@ --- -- hosts: "{{ HOSTS }}" - become: yes +- name: Register host to Satellite + hosts: "{{ _hosts | default(omit) }}" + become: true vars: # env: undef satellite_url: "{{ lookup('ansible.builtin.env', 'SATELLITE_SERVER') }}" roles: - - demo.satellite.register_host \ No newline at end of file + - demo.satellite.register_host diff --git a/satellite/setup.yml b/satellite/setup.yml index b8fa354..3beeae3 100644 --- a/satellite/setup.yml +++ b/satellite/setup.yml @@ -205,7 +205,7 @@ controller_launch_jobs: ####################### ### Satellite Vars ### ###################### -satellite_components: +satellite_components: - content_views #- content_view_publish - lifecycle_environments @@ -229,12 +229,12 @@ satellite_content_views: - name: RHEL8 content_view: RHEL8 repositories: - - name: Red Hat Enterprise Linux 8 for x86_64 - BaseOS RPMs 8 - product: Red Hat Enterprise Linux for x86_64 - - name: Red Hat Enterprise Linux 8 for x86_64 - AppStream RPMs 8 - product: Red Hat Enterprise Linux for x86_64 - - name: Red Hat Satellite Client 6 for RHEL 8 x86_64 RPMs - product: Red Hat Enterprise Linux for x86_64 + - name: Red Hat Enterprise Linux 8 for x86_64 - BaseOS RPMs 8 + product: Red Hat Enterprise Linux for x86_64 + - name: Red Hat Enterprise Linux 8 for x86_64 - AppStream RPMs 8 + product: Red Hat Enterprise Linux for x86_64 + - name: Red Hat Satellite Client 6 for RHEL 8 x86_64 RPMs + product: Red Hat Enterprise Linux for x86_64 satellite_lifecycle_environments: # Red Hat Enterprise Linux 7 diff --git a/satellite/setup_satellite.yml b/satellite/setup_satellite.yml index c70fa47..1a298e4 100644 --- a/satellite/setup_satellite.yml +++ b/satellite/setup_satellite.yml @@ -49,6 +49,6 @@ name: RHEL7_STIG organizations: "{{ satellite_organization }}" scap_file: "{{ item }}" - loop: + loop: - files/ssg-rhel7-ds-tailoring.xml - files/ssg-rhel8-ds-tailoring-stig-gui.xml diff --git a/setup_demo.yml b/setup_demo.yml index 0850b63..7c62b7a 100644 --- a/setup_demo.yml +++ b/setup_demo.yml @@ -54,7 +54,7 @@ - name: "SESSION_COOKIE_AGE" value: 180000 - - name: "include configuration for {{ demo }}" + - name: "Include configuration for {{ demo }}" ansible.builtin.include_vars: "{{ demo }}/setup.yml" - name: Demo Components diff --git a/windows/backup.yml b/windows/backup.yml index 86081b9..661630a 100644 --- a/windows/backup.yml +++ b/windows/backup.yml @@ -3,5 +3,5 @@ name: Rollback playbook tasks: - name: "Rollback this step" - debug: + ansible.builtin.debug: msg: "Rolling back this step" diff --git a/windows/create_ad_domain.yml b/windows/create_ad_domain.yml index bddbed6..d17459f 100644 --- a/windows/create_ad_domain.yml +++ b/windows/create_ad_domain.yml @@ -1,50 +1,50 @@ --- - name: Create Active Directory domain - hosts: "{{ HOSTS | default('os_windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false tasks: - - name: Set Local Admin Password - ansible.windows.win_user: - name: Administrator - password: "{{ ansible_password }}" + - name: Set Local Admin Password + ansible.windows.win_user: + name: Administrator + password: "{{ ansible_password }}" - - name: Create new domain in a new forest on the target host - ansible.windows.win_domain: - dns_domain_name: ansible.local - safe_mode_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" - register: new_forest + - name: Create new domain in a new forest on the target host + ansible.windows.win_domain: + dns_domain_name: ansible.local + safe_mode_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" + register: new_forest - - name: Reboot the target host - ansible.windows.win_reboot: - reboot_timeout: 3600 - when: new_forest.reboot_required + - name: Reboot the target host + ansible.windows.win_reboot: + reboot_timeout: 3600 + when: new_forest.reboot_required - - name: Wait up to 10min for AD web services to start - community.windows.win_wait_for_process: - process_name_exact: Microsoft.ActiveDirectory.WebServices - pre_wait_delay: 60 - state: present - timeout: 600 - sleep: 10 - remote_user: Administrator + - name: Wait up to 10min for AD web services to start + community.windows.win_wait_for_process: + process_name_exact: Microsoft.ActiveDirectory.WebServices + pre_wait_delay: 60 + state: present + timeout: 600 + sleep: 10 + remote_user: Administrator - - name: Create some groups - community.windows.win_domain_group: - name: "{{ item.name }}" - scope: global - loop: - - { name: "GroupA" } - - { name: "GroupB" } - - { name: "GroupC" } + - name: Create some groups + community.windows.win_domain_group: + name: "{{ item.name }}" + scope: global + loop: + - { name: "GroupA" } + - { name: "GroupB" } + - { name: "GroupC" } - - name: Create some users - community.windows.win_domain_user: - name: "{{ item.name }}" - groups: "{{ item.groups }}" - password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" - update_password: on_create - loop: - - { name: "UserA", groups: "GroupA" } - - { name: "UserB", groups: "GroupB" } - - { name: "UserC", groups: "GroupC" } + - name: Create some users + community.windows.win_domain_user: + name: "{{ item.name }}" + groups: "{{ item.groups }}" + password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" + update_password: on_create + loop: + - { name: "UserA", groups: "GroupA" } + - { name: "UserB", groups: "GroupB" } + - { name: "UserC", groups: "GroupC" } diff --git a/windows/helpdesk_new_user_portal.yml b/windows/helpdesk_new_user_portal.yml index a9d61ba..a5dc320 100644 --- a/windows/helpdesk_new_user_portal.yml +++ b/windows/helpdesk_new_user_portal.yml @@ -1,39 +1,39 @@ --- - name: Helpdesk new user portal - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('windows') }}" gather_facts: false tasks: - - name: Setting host facts using complex arguments - set_fact: - temp_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" - # Example result: ['&Qw2|E[-'] + - name: Setting host facts using complex arguments + ansible.builtin.set_fact: + temp_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" + # Example result: ['&Qw2|E[-'] - - name: Create new user - community.windows.win_domain_user: - name: "{{ firstname }} {{ surname }}" - firstname: "{{ firstname }}" - surname: "{{ surname }}" - sam_account_name: "{{ firstname[0] }}{{ surname }}" - company: BobCo - password: "{{ temp_password }}" - state: present - groups: - - "GroupA" - - "GroupB" - street: "{{ street }}" - city: "{{ city }}" - state_province: IN - postal_code: "{{ postal_code }}" - country: US - attributes: - telephoneNumber: "{{ telephone_number }}" - register: new_user + - name: Create new user + community.windows.win_domain_user: + name: "{{ firstname }} {{ surname }}" + firstname: "{{ firstname }}" + surname: "{{ surname }}" + sam_account_name: "{{ firstname[0] }}{{ surname }}" + company: BobCo + password: "{{ temp_password }}" + state: present + groups: + - "GroupA" + - "GroupB" + street: "{{ street }}" + city: "{{ city }}" + state_province: IN + postal_code: "{{ postal_code }}" + country: US + attributes: + telephoneNumber: "{{ telephone_number }}" + register: new_user - - name: Display User - debug: - var: new_user + - name: Display User + ansible.builtin.debug: + var: new_user - - name: Show temp password - debug: - var: temp_password + - name: Show temp password + ansible.builtin.debug: + var: temp_password diff --git a/windows/install_iis.yml b/windows/install_iis.yml index 2b84612..eb15c8c 100644 --- a/windows/install_iis.yml +++ b/windows/install_iis.yml @@ -1,25 +1,25 @@ --- - name: Install IIS - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('windows') }}" vars: iis_message: undef tasks: - name: Install IIS - win_feature: + ansible.windows.win_feature: name: Web-Server state: present - name: Start IIS service - win_service: + ansible.windows.win_service: name: W3Svc state: started - name: Create website index.html - win_copy: + ansible.windows.win_copy: content: "{{ iis_message }}" dest: C:\Inetpub\wwwroot\index.html - name: Show website address - debug: + ansible.builtin.debug: msg: http://{{ ansible_host }} diff --git a/windows/patching.yml b/windows/patching.yml index ab7f3c0..d6a8ec0 100644 --- a/windows/patching.yml +++ b/windows/patching.yml @@ -1,25 +1,28 @@ --- - name: Windows updates - hosts: "{{ HOSTS | default('os_windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" + strategy: linear vars: report_server: win1 - + tasks: - - include_role: - name: demo.patching.patch_windows + - name: Patch windows server + ansible.builtin.include_role: + name: demo.patching.patch_windows - - block: + - name: Build report server + delegate_to: "{{ report_server }}" + run_once: true + block: + - name: Install report server + ansible.builtin.include_role: + name: "{{ item }}" + loop: + - demo.patching.report_server + - demo.patching.report_windows + - demo.patching.report_windows_patching - - include_role: - name: "{{ item }}" - loop: - - demo.patching.report_server - - demo.patching.report_windows - - demo.patching.report_windows_patching - - - include_role: - name: demo.patching.report_server - tasks_from: windows_landing_page - - delegate_to: "{{ report_server }}" - run_once: yes + - name: Update landing page + ansible.builtin.include_role: + name: demo.patching.report_server + tasks_from: windows_landing_page diff --git a/windows/powershell.yml b/windows/powershell.yml index ccba36f..ed9d348 100644 --- a/windows/powershell.yml +++ b/windows/powershell.yml @@ -1,16 +1,17 @@ --- - name: Run PowerShell - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false vars: ps_script: undef tasks: - - name: Run PowerShell - ansible.windows.win_powershell: - script: | - {{ ps_script }} - register: ps_output + - name: Run PowerShell + ansible.windows.win_powershell: + script: | + {{ ps_script }} + register: ps_output - - debug: - msg: "{{ ps_output.output }}" + - name: Print output + ansible.builtin.debug: + msg: "{{ ps_output.output }}" diff --git a/windows/powershell_dsc.yml b/windows/powershell_dsc.yml index f283041..dc91e42 100644 --- a/windows/powershell_dsc.yml +++ b/windows/powershell_dsc.yml @@ -1,42 +1,42 @@ --- - name: PowerShell DSC - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false tasks: - - name: Setup the SecurityPolicyDSC module - community.windows.win_psmodule: - name: SecurityPolicyDSC - module_version: 2.10.0.0 - state: present - accept_license: yes - - - name: Set password history - ansible.windows.win_dsc: - resource_name: AccountPolicy - Name: Enforce_password_history - Enforce_password_history: 24 + - name: Setup the SecurityPolicyDSC module + community.windows.win_psmodule: + name: SecurityPolicyDSC + module_version: 2.10.0.0 + state: present + accept_license: true - - name: Set maximum password age - ansible.windows.win_dsc: - resource_name: AccountPolicy - Name: Maximum_Password_Age - Maximum_Password_Age: 60 + - name: Set password history + ansible.windows.win_dsc: + resource_name: AccountPolicy + Name: Enforce_password_history + Enforce_password_history: 24 - - name: Set minimum password age - ansible.windows.win_dsc: - resource_name: AccountPolicy - Name: Minimum_Password_Age - Maximum_Password_Age: 20 + - name: Set maximum password age + ansible.windows.win_dsc: + resource_name: AccountPolicy + Name: Maximum_Password_Age + Maximum_Password_Age: 60 - - name: Set minimum password length - ansible.windows.win_dsc: - resource_name: AccountPolicy - Name: Minimum_Password_Length - Maximum_Password_Age: 8 + - name: Set minimum password age + ansible.windows.win_dsc: + resource_name: AccountPolicy + Name: Minimum_Password_Age + Maximum_Password_Age: 20 - - name: Set password complexity requirements - ansible.windows.win_dsc: - resource_name: AccountPolicy - Name: Password_must_meet_complexity_requirements - Password_must_meet_complexity_requirements: Enabled + - name: Set minimum password length + ansible.windows.win_dsc: + resource_name: AccountPolicy + Name: Minimum_Password_Length + Maximum_Password_Age: 8 + + - name: Set password complexity requirements + ansible.windows.win_dsc: + resource_name: AccountPolicy + Name: Password_must_meet_complexity_requirements + Password_must_meet_complexity_requirements: Enabled diff --git a/windows/powershell_script.yml b/windows/powershell_script.yml index 48ca142..c887f81 100644 --- a/windows/powershell_script.yml +++ b/windows/powershell_script.yml @@ -1,20 +1,22 @@ --- - name: PowerShell Script - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false vars: remote_dest: "C:\\query_services.ps1" - tasks: - - name: Copy script to remote - ansible.windows.win_copy: - src: "{{playbook_dir}}/query_services.ps1" - dest: "{{ remote_dest }}" - - - name: Run Script - ansible.windows.win_powershell: - script: | - {{ remote_dest }} -ServiceState {{ service_state }} - register: ps_output - - debug: - var: ps_output + tasks: + - name: Copy script to remote + ansible.windows.win_copy: + src: "{{ playbook_dir }}/query_services.ps1" + dest: "{{ remote_dest }}" + + - name: Run Script + ansible.windows.win_powershell: + script: | + {{ remote_dest }} -ServiceState {{ service_state }} + register: ps_output + + - name: Print output + ansible.builtin.debug: + var: ps_output diff --git a/windows/setup.yml b/windows/setup.yml index 967a848..d979461 100644 --- a/windows/setup.yml +++ b/windows/setup.yml @@ -22,7 +22,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -30,7 +30,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - question_name: web content type: text @@ -40,7 +40,7 @@ controller_templates: - name: "WINDOWS / Patching" use_fact_cache: true job_type: check - ask_job_type_on_launch: yes + ask_job_type_on_launch: true inventory: "Workshop Inventory" project: "Ansible official demo project" playbook: "windows/patching.yml" @@ -49,7 +49,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -57,7 +57,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - question_name: Update categories type: multiselect @@ -94,7 +94,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -102,7 +102,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - name: "WINDOWS / Chocolatey install specific" @@ -114,7 +114,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -122,7 +122,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - question_name: Package name type: text @@ -138,7 +138,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -146,9 +146,9 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - - question_name: PowerShell Script + - question_name: PowerShell Script type: textarea variable: ps_script default: "Get-Service | Where-Object -FilterScript {$_.Status -eq 'running'} | Select-Object -Property 'Name'" @@ -163,7 +163,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -171,7 +171,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - question_name: Service state to query? type: multiplechoice @@ -191,7 +191,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -199,7 +199,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - name: "WINDOWS / AD /Create Domain" @@ -211,7 +211,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' @@ -219,7 +219,7 @@ controller_templates: spec: - question_name: Server Name or Pattern type: text - variable: HOSTS + variable: _hosts required: false - name: "WINDOWS / AD / New User" @@ -231,7 +231,7 @@ controller_templates: notification_templates_success: Telemetry notification_templates_error: Telemetry credentials: - - "Workshop Credential" + - "Workshop Credential" survey_enabled: true survey: name: '' diff --git a/windows/snow.yml b/windows/snow.yml deleted file mode 100644 index 4b1aa1b..0000000 --- a/windows/snow.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -- name: open a change request - hosts: student1-ansible-1 - vars: - change_request: - severity: 2 - priority: 2 - description: Automated Provisioning - justification: Ansible Triggered - implementation_plan: Updated by Red Hat AAP - risk_impact_analysis: Changes are made automatically based on approved changes - test_plan: Run synthetic validation tests post-deployment - short_description: Automated Provisioning - tasks: - - name: Create a change request - servicenow.itsm.change_request: - instance: - host: "https://{{ snow_instance }}.service-now.com" - username: "{{ snow_username }}" - password: "{{ snow_password }}" - type: standard - state: new - requested_by: admin - short_description: "{{ change_request.short_description }}" - description: "{{ change_request.description }}" - priority: moderate - risk: low - impact: low - register: new_incident - - - debug: - var: new_incident.record.number diff --git a/windows/windows_choco_multiple.yml b/windows/windows_choco_multiple.yml index d9c226d..dfeca17 100644 --- a/windows/windows_choco_multiple.yml +++ b/windows/windows_choco_multiple.yml @@ -1,27 +1,28 @@ --- - name: Chocolatey install multiple - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false vars: choco_packages: - name: nodejs - name: python tasks: - - name: Install specific versions of packages sequentially - win_chocolatey: - name: "{{ item.name }}" - state: latest - loop: "{{ choco_packages }}" + - name: Install specific versions of packages sequentially + chocolatey.chocolatey.win_chocolatey: + name: "{{ item.name }}" + state: installed + loop: "{{ choco_packages }}" - - name: Check python version - win_command: python --version - register: check_python_version - changed_when: false + - name: Check python version + ansible.windows.win_command: python --version + register: check_python_version + changed_when: false - - name: Check nodejs version - win_command: node --version - register: check_node_version - changed_when: false + - name: Check nodejs version + ansible.windows.win_command: node --version + register: check_node_version + changed_when: false - - debug: - msg: Python Version is {{ check_python_version.stdout_lines[0] }} and NodeJS version is {{ check_node_version.stdout_lines[0] }} + - name: Print message + ansible.builtin.debug: + msg: Python Version is {{ check_python_version.stdout_lines[0] }} and NodeJS version is {{ check_node_version.stdout_lines[0] }} diff --git a/windows/windows_choco_specific.yml b/windows/windows_choco_specific.yml index 5f034ec..7f86851 100644 --- a/windows/windows_choco_specific.yml +++ b/windows/windows_choco_specific.yml @@ -1,9 +1,9 @@ --- - name: Chocolatey install specific - hosts: "{{ HOSTS | default('windows') }}" + hosts: "{{ _hosts | default('os_windows') }}" gather_facts: false tasks: - - name: Install choco package with specific version - win_chocolatey: - name: "{{ package_name }}" + - name: Install choco package with specific version + chocolatey.chocolatey.win_chocolatey: + name: "{{ package_name }}"