Win patch (#11)

Add patching report for windows, cloud destroy VM, and Windows Full blueprint
This commit is contained in:
willtome
2022-03-30 11:03:08 -05:00
committed by GitHub
parent 8e56c5bbf6
commit 0ed4737985
48 changed files with 182 additions and 377 deletions

View File

@@ -0,0 +1,6 @@
---
vm_blueprint_providers:
- aws
aws_image_filter: 'Windows_Server-2019-English-Full-Base*'
aws_instance_size: t3.medium
aws_userdata_template: aws_windows_userdata

View File

@@ -1,24 +0,0 @@
---
#######
# AWS VARS
#######
aws_vpc_name: ansible
aws_vpc_prefix: demo
aws_vpc_cidr_block: 10.0.0.0/16
aws_subnet_cidr: 10.0.1.0/24
aws_region: us-east-1
aws_vm_name: "{{ vm_name }}"
aws_vm_owner: "{{ vm_owner }}"
aws_blueprint: "{{ vm_blueprint }}"
aws_image_filter: "{{ omit }}"
aws_image_size: "{{ omit }}"
aws_image_architecture: "{{ omit }}"
aws_image_owners: "{{ omit }} "
aws_userdata_template: default
aws_keypair_name: "{{ aws_vpc_name }}-{{ aws_vpc_prefix }}-demo-key"
aws_securitygroup_name: "{{ aws_vpc_name }}-{{ aws_vpc_prefix }}-sec-group"
aws_env_tag: prod
aws_purpose_tag: ansible_demo
aws_ansiblegroup_tag: cloud
aws_ec2_wait: true

View File

@@ -1,118 +0,0 @@
---
- name: AWS | CREATE INFRA | vpc
amazon.aws.ec2_vpc_net:
state: present
name: "{{ aws_vpc_name }}-{{ aws_vpc_prefix }}-vpc"
cidr_block: "{{ aws_vpc_cidr_block }}"
tenancy: default
region: "{{ aws_region }}"
tags:
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"
register: aws_vpc
- name: AWS | CREATE INFRA | internet gateway
amazon.aws.ec2_vpc_igw:
state: present
vpc_id: "{{ aws_vpc.vpc.id }}"
region: "{{ aws_region }}"
tags:
Name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-vpc-igw"
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"
register: aws_gateway
- name: Create security group internal
amazon.aws.ec2_group:
state: present
name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-sec-group"
region: "{{ aws_region }}"
description: Inbound WinRM and RDP, http for demo servers and internal AD ports
rules:
- proto: tcp
ports:
- 80 # HTTP
- 443 # HTTPS
- 22 # SSH
- 5986 # WinRM
- 3389 # RDP
cidr_ip: 0.0.0.0/0
- proto: icmp
to_port: -1
from_port: -1
cidr_ip: 0.0.0.0/0
- proto: tcp
ports:
- 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
cidr_ip: 10.0.0.0/16
- proto: udp
ports:
- 53 # DNS
- 88 # Kerberos Authentication
- 123 # NTP
- 137-138 # Netlogon
- 389 # LDAP
- 445 # SMB
- 464 # Kerberos Authentication
- 1024-65535 # Ephemeral RPC ports
cidr_ip: 10.0.0.0/16
rules_egress:
- proto: -1
cidr_ip: 0.0.0.0/0
vpc_id: "{{ aws_vpc.vpc.id }}"
tags:
Name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-sec-group"
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"
- name: Create a subnet on the VPC
amazon.aws.ec2_vpc_subnet:
state: present
vpc_id: "{{ aws_vpc.vpc.id }}"
cidr: "{{ aws_subnet_cidr }}"
region: "{{ aws_region }}"
map_public: yes
tags:
Name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-subnet"
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"
register: aws_subnet
- name: Create a subnet route table
amazon.aws.ec2_vpc_route_table:
state: present
vpc_id: "{{ aws_vpc.vpc.id }}"
region: "{{ aws_region }}"
subnets:
- "{{ aws_subnet.subnet.id }}"
routes:
- dest: 0.0.0.0/0
gateway_id: "{{ aws_gateway.gateway_id }}"
tags:
Name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-vpc-rtbl"
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"
- name: Create AWS keypair
amazon.aws.ec2_key:
name: "{{ aws_vpc_name }}-{{aws_vpc_prefix }}-demo-key"
region: "{{ aws_region }}"
key_material: "{{ aws_public_key }}"
state: present
tags:
owner: "{{ aws_vpc_name }}"
purpose: "{{ aws_purpose_tag }}"

View File

@@ -1,47 +0,0 @@
---
- name: AWS | CREATE VM | get subnet info
amazon.aws.ec2_vpc_subnet_info:
region: "{{ aws_region }}"
filters:
"tag:Name": "{{ aws_vpc_name }}-{{ aws_vpc_prefix }}-subnet"
register: aws_subnet
- name: AWS | CREATE VM | save subnet id
set_fact:
aws_subnet_id: "{{ aws_subnet.subnets|map(attribute='id')| list | last }}"
- name: AWS| CREATE VM | find ami
amazon.aws.ec2_ami_info:
region: "{{ aws_region }}"
owners: "{{ aws_image_owners }}"
filters:
name: "{{ aws_image_filter }}"
architecture: "{{ aws_image_architecture }}"
register: amis
- name: AWS| CREATE VM | save ami
set_fact:
aws_instance_ami: >
{{ amis.images | selectattr('name', 'defined') | sort(attribute='creation_date') | last }}
- name: AWS| CREATE VM | create instance
amazon.aws.ec2_instance:
network:
assign_public_ip: yes
key_name: "{{ aws_keypair_name }}"
instance_type: "{{ aws_instance_size }}"
image_id: "{{ aws_instance_ami.image_id }}"
region: "{{ aws_region }}"
security_group: "{{ aws_securitygroup_name }}"
tags:
blueprint: "{{ aws_blueprint }}"
purpose: "{{ aws_purpose_tag }}"
env: "{{ aws_env_tag }}"
ansible_group: "{{ aws_ansiblegroup_tag }}"
owner: "{{ aws_vm_owner }}"
info: "This instance was built by Red Hat Product Demos"
Name: "{{ aws_vm_name }}"
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

View File

@@ -1,29 +0,0 @@
<powershell>
# Disable .Net Optimization Service
Get-ScheduledTask *ngen* | Disable-ScheduledTask
# Disable Windows Auto Updates
# https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/troubleshooting-windows-instances.html#high-cpu-issue
reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" /v AUOptions /t REG_DWORD /d 1 /f
net stop wuauserv
net start wuauserv
# Remove policies stopping us from enabling WinRM
reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" /v AllowBasic /f
reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" /v AllowUnencryptedTraffic /f
reg delete "HKLM\SOFTWARE\Policies\Microsoft\Windows\WinRM\Service" /v DisableRunAs /f
# Disable Windows Defender Monitoring
Set-MpPreference -DisableRealtimeMonitoring $true
# Enable WinRM
Invoke-WebRequest -Uri https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 -OutFile C:\ConfigureRemotingForAnsible.ps1
C:\ConfigureRemotingForAnsible.ps1 -ForceNewSSLCert -EnableCredSSP
# add ec2-user
$Password = ConvertTo-SecureString {{ ansible_password }} -AsPlainText -Force
New-LocalUser -Name "ec2-user" -Description "Ansible Service Account" -Password $Password
Add-LocalGroupMember -Group "Administrators" -Member "ec2-user"
Rename-Computer -NewName {{ aws_vm_name }} -Force -Restart
</powershell>

View File

@@ -1,9 +0,0 @@
---
##############
# Azure Vars
##############
az_region:
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

View File

@@ -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 }}"

View File

@@ -4,9 +4,13 @@
tasks:
- name: list systems to be destroyed
debug:
msg: "{{ inventory_hostname }}"
- name: pause for review...
pause:
seconds: 30
prompt: "{{ inventory_hostname }} will be DESTROYED in 30 seconds. Cancel the job to Abort."
prompt: "Systems listed above will be DESTROYED in 30 seconds. Cancel the job to Abort."
- name: destroy vm
include_role:

View File

@@ -98,6 +98,28 @@ controller_templates:
variable: vm_blueprint
required: true
choices: #"{{ lookup('fileglob', 'blueprints/*.yml') | regex_replace(',','\n') | regex_findall('.*/(.*)(?=.yml)') | list }}"
- windows
- windows_core
- windows_full
- rhel8
- rhel7
- name: Cloud / Destroy VM
job_type: run
organization: Default
credentials:
- AWS
- Workshop Credential
project: Ansible official demo project
playbook: cloud/destroy_vm.yml
inventory: Workshop Inventory
execution_environment: Default execution environment
survey_enabled: true
extra_vars:
aws_region: us-east-2
survey:
name: ''
description: ''
spec:
- question_name: Name or Pattern
type: text
variable: HOSTS
required: true

View File

@@ -22,7 +22,7 @@
- name: AWS| CREATE VM | save ami
set_fact:
aws_instance_ami: >
{{ amis.images | selectattr('name', 'defined') | sort(attribute='creation_date') | last }}
{{ (amis.images | selectattr('name', 'defined') | sort(attribute='creation_date'))[-2] }}
- name: AWS| CREATE VM | create instance
amazon.aws.ec2_instance:

View File

@@ -1,38 +0,0 @@
- name: Create HTML report
ansible.builtin.template:
src: report.j2
dest: "{{ file_path }}/windowspatch.html"
check_mode: no
- name: Copy CSS over
ansible.builtin.copy:
src: "css"
dest: "{{ file_path }}"
directory_mode: true
check_mode: no
- name: Copy logo over
ansible.builtin.copy:
src: "webpage_logo.png"
dest: "{{ file_path }}"
directory_mode: true
check_mode: no
- name: Display link to Patch report
ansible.builtin.debug:
msg: "Please go to http://{{ ansible_host }}/windowspatch.html"
- name: Send Report via E-mail
community.general.mail:
host: "{{ EMAIL_HOST }}"
username: "{{ EMAIL_USERNAME }}"
password: "{{ EMAIL_PASSWORD }}"
port: "{{ EMAIL_PORT }}"
subject: "Windows Patching Report"
body: "{{ lookup('template', 'report.j2') }}"
from: "{{ EMAIL_FROM }}"
to: "{{ EMAIL_TO }}"
subtype: html
delegate_to: localhost
become: false
check_mode: no

View File

@@ -0,0 +1,14 @@
---
win_update_categories:
- Application
- Connectors
- CriticalUpdates
- DefinitionUpdates
- DeveloperKits
- FeaturePacks Guidance
- SecurityUpdates
- ServicePacks
- Tools
- UpdateRollups
- Updates
allow_reboot: true

View File

@@ -0,0 +1,15 @@
---
- name: Scan packages
demo.patching.win_scan_packages:
check_mode: no
- name: Scan Services
demo.patching.win_scan_services:
check_mode: no
- name: Install Windows Updates
ansible.windows.win_updates:
category_names: "{{ win_update_categories | default(omit) }}"
reboot: "{{ allow_reboot }}"
state: installed
register: patchingresult

View File

@@ -24,4 +24,4 @@
- name: display link to inventory report
ansible.builtin.debug:
msg: "Please go to http://{{ ansible_host }}/reports/linux.html"
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/linux.html"

View File

@@ -20,7 +20,7 @@
- name: Display link to Linux patch report
ansible.builtin.debug:
msg: "Please go to http://{{ ansible_host }}/reports/linuxpatch.html"
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/linuxpatch.html"
#- name: Send Report via E-mail
# community.general.mail:

View File

@@ -0,0 +1,20 @@
---
- 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

View File

@@ -0,0 +1,23 @@
---
- name: Install IIS
ansible.windows.win_feature:
name: Web-Server
state: present
check_mode: no
- name: Start IIS service
ansible.windows.win_service:
name: W3Svc
state: started
check_mode: no
- name: Create Directory
ansible.windows.win_file:
path: C:\Inetpub\wwwroot\reports
state: directory
check_mode: no
- name: Enable Directory Browsing
ansible.windows.win_powershell:
script: |
"Set-WebConfigurationProperty -filter /system.webServer/directoryBrowse -name enabled -value true -PSPath 'IIS:\Sites\Default Web Site\reports'"

View File

@@ -1,16 +1,19 @@
---
- name: create HTML report
ansible.builtin.template:
ansible.windows.win_template:
src: report.j2
dest: "{{ file_path }}/windows.html"
check_mode: no
- name: copy CSS over
ansible.builtin.copy:
ansible.windows.win_copy:
src: "css"
dest: "{{ file_path }}"
directory_mode: true
check_mode: no
- name: copy logos over
ansible.builtin.copy:
ansible.windows.win_copy:
src: "{{ item }}"
dest: "{{ file_path }}"
directory_mode: true
@@ -18,7 +21,8 @@
- "webpage_logo.png"
- "redhat-ansible-logo.svg"
- "server.png"
check_mode: no
- name: display link to inventory report
ansible.builtin.debug:
msg: "Please go to http://{{ ansible_host }}/windows.html"
#- name: display link to inventory report
# ansible.builtin.debug:
# msg: "Please go to http://{{ host_vars[report_server]['ansible_host'] }}/reports/windows.html"

View File

@@ -75,7 +75,7 @@ collapsible: true
</tr>
</thead>
<tbody>
{% for windows_host in groups['tag_Windows']|sort %}
{% for windows_host in ansible_play_hosts |sort %}
<tr>
<td class="summary_info">
<div id="hostname">

View File

@@ -0,0 +1 @@
file_path: C:\Inetpub\wwwroot\reports

View File

@@ -0,0 +1,23 @@
- name: Create HTML report
ansible.windows.win_template:
src: report.j2
dest: "{{ file_path }}/windowspatch.html"
check_mode: no
- name: Copy CSS over
ansible.windows.win_copy:
src: "css"
dest: "{{ file_path }}"
directory_mode: true
check_mode: no
- name: Copy logo over
ansible.windows.win_copy:
src: "webpage_logo.png"
dest: "{{ file_path }}"
directory_mode: true
check_mode: no
- name: Display link to Patch report
ansible.builtin.debug:
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/windowspatch.html"

View File

@@ -27,16 +27,16 @@
</tr>
</thead>
<tbody>
{% for windows_host in groups['tag_Windows']|sort %}
{% for windows_host in ansible_play_hosts |sort %}
<tr>
<td>{{hostvars[windows_host]['inventory_hostname']}}</td>
<td>{{hostvars[windows_host]['ansible_distribution']|default("none")}}</td>
<td>
<ul>
{% if hostvars[windows_host].patchresult.updates is defined and hostvars[windows_host].patchresult.found_update_count|int > 0 %}
{% for update in hostvars[windows_host].patchresult.updates %}
{% set updatenum = hostvars[windows_host].patchresult.updates[update] %}
{% if hostvars[windows_host].patchingresult.updates is defined and hostvars[windows_host].patchingresult.found_update_count|int > 0 %}
{% for update in hostvars[windows_host].patchingresult.updates %}
{% set updatenum = hostvars[windows_host].patchingresult.updates[update] %}
<li>{{updatenum.title}}</li>
{% endfor %}
{% else %}
@@ -49,9 +49,7 @@
{% endfor %}
</tbody>
</table>
{% for host in ansible_play_hosts %}
<center><p>Created with Ansible on {{hostvars[host].ansible_date_time.iso8601}}</p></center>
{% endfor %}
<center><p>Created with Ansible on {{hostvars[inventory_hostname].ansible_date_time.iso8601}}</p></center>
<script type="text/javascript">
function tableToCSV() {

View File

@@ -0,0 +1 @@
file_path: C:\Inetpub\wwwroot\reports

View File

@@ -12,6 +12,8 @@ collections:
#windows
- chocolatey.chocolatey
- community.windows
- name: ansible.windows
version: 1.9.0
#cloud
- name: azure.azcollection
version: 1.11.0

22
windows/patching.yml Normal file
View File

@@ -0,0 +1,22 @@
---
- name: Windows updates
hosts: "{{ HOSTS | default('os_windows') }}"
vars:
report_server: win1
tasks:
- include_role:
name: demo.patching.patch_windows
- block:
- include_role:
name: demo.patching.report_server
tasks_from: iis
- include_role:
name: demo.patching.report_windows
- include_role:
name: demo.patching.report_windows_patching
delegate_to: "{{ report_server }}"
run_once: yes

View File

@@ -74,11 +74,13 @@ controller_templates:
variable: iis_message
required: true
- name: "WINDOWS / Windows updates"
job_type: run
- name: "WINDOWS / Patching"
use_fact_cache: true
job_type: check
ask_job_type_on_launch: yes
inventory: "Workshop Inventory"
project: "Ansible official demo project"
playbook: "windows/windows_updates.yml"
playbook: "windows/patching.yml"
execution_environment: Default execution environment
credentials:
- "Workshop Credential"
@@ -92,8 +94,8 @@ controller_templates:
variable: HOSTS
required: false
- question_name: Update categories
type: multiplechoice
variable: categories
type: multiselect
variable: win_update_categories
required: false
default: SecurityUpdates
choices:
@@ -110,7 +112,7 @@ controller_templates:
- Updates
- question_name: Reboot after install?
type: multiplechoice
variable: reboot_server
variable: allow_reboot
required: false
default: 'Yes'
choices:

View File

@@ -1,9 +0,0 @@
---
- name: Windows updates
hosts: "{{ HOSTS | default('windows') }}"
tasks:
- name: Install Windows Updates
win_updates:
category_names: "{{ categories | default(omit) }}"
reboot: '{{ reboot_server | default(yes) }}'