@@ -1,11 +1,42 @@
|
||||
# Ansible Cloud Demos
|
||||
# Cloud Demos
|
||||
|
||||
## Table of Contents
|
||||
- [Cloud Demos](#cloud-demos)
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [About These Demos](#about-these-demos)
|
||||
- [Jobs](#jobs)
|
||||
- [Inventory](#inventory)
|
||||
- [Post Setup Setup](#post-setup-setup)
|
||||
- [Configure Credentials](#configure-credentials)
|
||||
- [Add Workshop Credential Password](#add-workshop-credential-password)
|
||||
- [Remove Inventory Variables](#remove-inventory-variables)
|
||||
- [Getting your Puiblic Key for Create Infra Job](#getting-your-puiblic-key-for-create-infra-job)
|
||||
- [Suggested Usage](#suggested-usage)
|
||||
- [Known Issues](#known-issues)
|
||||
|
||||
## About These Demos
|
||||
This category of demos shows examples of multi-cloud provisioning and management with Ansible Automation Platform. The list of demos can be found below. These demos are particularly helpful in building additional infrastructure for other demo categories such as Linux and Windows. See the [Suggested Usage](#suggested-usage) section of this document for recommendations on how to best use these demos.
|
||||
|
||||
### Jobs
|
||||
|
||||
- [**Cloud / Create Infra**](create_infra.yml) - Creates a VPC with required routing and firewall rules for provisioning VMs
|
||||
- [**Cloud / Create VM**](create_vm.yml) - Create a VM based on a [blueprint](blueprints/) in the selected cloud provider
|
||||
- [**Cloud / Destroy VM**](destroy_vm.yml) - Destroy a VM that has been created in a cloud provider. VM must be imported into dynamic inventory to be deleted.
|
||||
|
||||
### Inventory
|
||||
|
||||
A dynamic inventory is created to pull inventory hosts from cloud providers. The VM will be added by name therefore provisioning VMs with the same name will cause conflict in the inventory.
|
||||
|
||||
Groups will be created based on the operating system (platform) of the VM provisioned as well as a group called `cloud_<cloud provider>`.
|
||||
|
||||
## Post Setup Setup
|
||||
After running the setup job template, there are a few steps required to make the demos fully functional. See post setup actions below.
|
||||
|
||||
## Setup
|
||||
> These steps may differ if you in your environment
|
||||
|
||||
### Add AWS Credentials
|
||||
### Configure Credentials
|
||||
|
||||
1) Add AWS Access and Secret key to the AWS Credential created by the setup job
|
||||
- Add AWS Access and Secret key to the `AWS` Credential created by the setup job.
|
||||
|
||||
### Add Workshop Credential Password
|
||||
|
||||
@@ -23,12 +54,11 @@
|
||||
4) `cat .ssh/authorized_keys` and copy the key listed including the `ssh-rsa` prefix
|
||||
|
||||
|
||||
## Demos
|
||||
## Suggested Usage
|
||||
|
||||
### Cloud / Create Infra
|
||||
**Cloud / Create Infra** -The Create Infra job builds cloud infrastructure based on the provider definition in the included `demo.cloud` collection.
|
||||
|
||||
The Create Infra job builds cloud infrastructure based on the provider definition in the included `demo.cloud` collection.
|
||||
**Cloud / Create VM** - The Create VM job builds a VM in the given provider based on the included `demo.cloud` collection. VM [blueprints](blueprints/) define variables for each provider that override the defaults in the collection. When creating VMs it is recommended to follow naming conventions that can be used as host patterns. (eg. VM names: `win1`, `win2`, `win3`. Host Pattern: `win*` )
|
||||
|
||||
### Cloud / Create VM
|
||||
|
||||
The Create VM job builds a VM in the given provider based on the included `demo.cloud` collection. VM blueprints define variables for each provider that override the collection roles.
|
||||
## Known Issues
|
||||
Azure does not work without a custom execution environment that includes the Azure dependencies.
|
||||
14
cloud/blueprints/windows.yml
Normal file
14
cloud/blueprints/windows.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
vm_blueprint_providers:
|
||||
- aws
|
||||
- azure
|
||||
aws_image_filter: 'Windows_Server-2019-English-Core-Base*'
|
||||
aws_instance_size: t3.medium
|
||||
aws_userdata_template: aws_windows_userdata
|
||||
az_vm_os_type: Windows
|
||||
az_vm_size: Standard_DS1_v2
|
||||
az_vm_image:
|
||||
offer: WindowsServer
|
||||
publisher: MicrosoftWindowsServer
|
||||
sku: 2022-Datacenter
|
||||
version: latest
|
||||
@@ -16,4 +16,4 @@
|
||||
include_role:
|
||||
name: "demo.cloud.aws"
|
||||
tasks_from: destroy_vm
|
||||
when: "'cloud_aws' in group_names"
|
||||
when: "'cloud_aws' in group_names or 'cloud_azure' in group_names"
|
||||
|
||||
@@ -17,6 +17,13 @@ controller_credentials:
|
||||
username: REPLACEME
|
||||
password: REPLACEME
|
||||
|
||||
#- name: Azure
|
||||
# credential_type: Microsoft Azure Resource Manager
|
||||
# organization: Default
|
||||
# update_secrets: false
|
||||
# inputs:
|
||||
# subscription: REPLACEME
|
||||
|
||||
controller_inventory_sources:
|
||||
- name: AWS Inventory
|
||||
organization: Default
|
||||
@@ -35,12 +42,30 @@ controller_inventory_sources:
|
||||
- key: platform
|
||||
prefix: os
|
||||
|
||||
#- name: Azure Inventory
|
||||
# organization: Default
|
||||
# source: azure_rm
|
||||
# inventory: Workshop Inventory
|
||||
# credential: Azure
|
||||
# execution_environment: Ansible Engine 2.9 execution environment
|
||||
# overwrite: true
|
||||
# source_vars:
|
||||
# hostnames:
|
||||
# - tags.Name
|
||||
# - default
|
||||
# keyed_groups:
|
||||
# - key: os_profile.system
|
||||
# prefix: os
|
||||
# conditional_groups:
|
||||
# cloud_azure: true
|
||||
|
||||
controller_templates:
|
||||
- name: Cloud / Create Infra
|
||||
job_type: run
|
||||
organization: Default
|
||||
credentials:
|
||||
credentials:
|
||||
- AWS
|
||||
#- Azure
|
||||
project: Ansible official demo project
|
||||
playbook: cloud/create_infra.yml
|
||||
inventory: Workshop Inventory
|
||||
@@ -58,6 +83,7 @@ controller_templates:
|
||||
required: true
|
||||
choices:
|
||||
- aws
|
||||
#- azure
|
||||
- question_name: AWS Public Key (only required for aws provider)
|
||||
type: textarea
|
||||
required: false
|
||||
@@ -67,6 +93,7 @@ controller_templates:
|
||||
organization: Default
|
||||
credentials:
|
||||
- AWS
|
||||
#- Azure
|
||||
- Workshop Credential
|
||||
project: Ansible official demo project
|
||||
playbook: cloud/create_vm.yml
|
||||
@@ -93,6 +120,7 @@ controller_templates:
|
||||
required: true
|
||||
choices:
|
||||
- aws
|
||||
#- azure
|
||||
- question_name: Blueprint
|
||||
type: multiplechoice
|
||||
variable: vm_blueprint
|
||||
@@ -107,6 +135,7 @@ controller_templates:
|
||||
organization: Default
|
||||
credentials:
|
||||
- AWS
|
||||
#- Azure
|
||||
- Workshop Credential
|
||||
project: Ansible official demo project
|
||||
playbook: cloud/destroy_vm.yml
|
||||
@@ -123,3 +152,4 @@ controller_templates:
|
||||
type: text
|
||||
variable: HOSTS
|
||||
required: true
|
||||
|
||||
|
||||
@@ -2,8 +2,16 @@
|
||||
##############
|
||||
# Azure Vars
|
||||
##############
|
||||
az_region:
|
||||
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_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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
- name: AZURE | CREATE INFRA | resource group
|
||||
azure.azcollection.azure_rm_resourcegroup:
|
||||
name: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg"
|
||||
location: "{{ az_region }}"
|
||||
name: "{{ az_rg_name }}-{{ az_rg_prefix }}-rg"
|
||||
location: "{{ az_region }}"
|
||||
|
||||
- name: AZURE | CREATE INFRA | virtual network
|
||||
azure.azcollection.azure_rm_virtualnetwork:
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- 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 }}"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
- 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
|
||||
@@ -0,0 +1,36 @@
|
||||
build_report_windows
|
||||
========
|
||||
|
||||
Installs Apache and creates a report based on facts from Windows services and packages modules
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Must run on Apache server
|
||||
|
||||
Role Variables / Configuration
|
||||
--------------
|
||||
|
||||
N/A
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
N/A
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
The role can be used to create an html report on any number of Linux hosts using any number of Windows servers about their services and packages installed
|
||||
|
||||
|
||||
```
|
||||
---
|
||||
- hosts: all
|
||||
|
||||
tasks:
|
||||
- name: Run Windows Report
|
||||
import_role:
|
||||
name: shadowman.reports.build_report_windows
|
||||
|
||||
```
|
||||
@@ -0,0 +1,2 @@
|
||||
---
|
||||
detailedreport: True
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,202 @@
|
||||
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: #ffffff;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Logos" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="930.2px" height="350px" viewBox="0 0 930.2 350" style="enable-background:new 0 0 930.2 350;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#EE0000;}
|
||||
</style>
|
||||
<title>Logo-Red_Hat-Ansible_Automation_Platform-A-Reverse-RGB</title>
|
||||
<path class="st0" d="M383.3,228.5h18.8L446,335.7h-17.5l-12.4-31.4h-48l-12.6,31.4h-16.7L383.3,228.5z M410.9,291l-18.7-47l-18.7,47
|
||||
H410.9z"/>
|
||||
<path class="st0" d="M455.2,257.7h15.3v7.8c6.2-6.2,14.7-9.6,23.5-9.3c17.9,0,30.5,12.4,30.5,30.5v49h-15.3v-46.5
|
||||
c0-12.3-7.5-19.8-19.3-19.8c-7.8-0.3-15.1,3.6-19.3,10.1v56.1h-15.3V257.7z"/>
|
||||
<path class="st0" d="M543,315.5c8.1,6.4,16.7,9.8,25.4,9.8c11,0,18.7-4.8,18.7-11.7c0-5.5-4-8.7-12.6-10l-14.1-2
|
||||
c-15.5-2.3-23.3-9.5-23.3-21.6c0-14.1,12.3-23.6,30.5-23.6c11.3-0.1,22.3,3.4,31.5,9.9l-7.8,10.1c-8.6-5.7-16.4-8.1-24.7-8.1
|
||||
c-9.3,0-15.6,4.3-15.6,10.6c0,5.7,3.7,8.4,12.9,9.8l14.1,2c15.5,2.3,23.6,9.7,23.6,21.7c0,14-14.1,24.5-32.6,24.5
|
||||
c-13.5,0-25.6-4-34.2-11.5L543,315.5z"/>
|
||||
<path class="st0" d="M611.6,235.6c0-5.2,4.1-9.4,9.3-9.5c0,0,0,0,0,0c5.2-0.2,9.7,3.9,9.9,9.1c0.2,5.2-3.9,9.7-9.1,9.9
|
||||
c-0.2,0-0.5,0-0.7,0C615.8,245.1,611.6,240.9,611.6,235.6C611.6,235.7,611.6,235.7,611.6,235.6z M628.6,335.7h-15.3v-78h15.3V335.7z
|
||||
"/>
|
||||
<path class="st0" d="M685.5,336.9c-8.5,0-16.8-2.7-23.6-7.8v6.6h-15.2V228.5l15.3-3.4v40c6.6-5.6,15.1-8.7,23.7-8.6
|
||||
c22.1,0,39.4,17.7,39.4,40.1C725.2,319.1,707.9,336.9,685.5,336.9z M662,279.2v35.2c4.9,5.7,13,9.2,21.8,9.2
|
||||
c15,0,26.4-11.5,26.4-26.8c0-15.3-11.5-27-26.4-27C674.9,269.8,667.1,273.2,662,279.2z"/>
|
||||
<path class="st0" d="M755,335.7h-15.3V228.5l15.3-3.4V335.7z"/>
|
||||
<path class="st0" d="M810.5,337.1c-23,0-40.9-17.7-40.9-40.4c0-22.5,17.2-40.1,39.1-40.1c21.5,0,37.7,17.8,37.7,40.8v4.4h-61.6
|
||||
c2,13,13.2,22.5,26.4,22.4c7.2,0.2,14.2-2.3,19.8-6.8l9.8,9.7C832.1,333.7,821.5,337.4,810.5,337.1z M784.9,290.2h46.3
|
||||
c-2.3-11.9-11.5-20.8-22.8-20.8C796.5,269.4,787.2,277.8,784.9,290.2z"/>
|
||||
<path class="st1" d="M202.8,137.5c18.4,0,45.1-3.8,45.1-25.7c0.1-1.7-0.1-3.4-0.5-5l-11-47.7c-2.5-10.5-4.8-15.2-23.2-24.5
|
||||
c-14.3-7.3-45.5-19.4-54.7-19.4c-8.6,0-11.1,11.1-21.3,11.1c-9.8,0-17.1-8.3-26.4-8.3c-8.8,0-14.6,6-19,18.4c0,0-12.4,34.9-14,40
|
||||
c-0.3,0.9-0.4,1.9-0.4,2.9C77.6,92.9,131.1,137.5,202.8,137.5 M250.8,120.7c2.5,12.1,2.5,13.3,2.5,14.9c0,20.6-23.2,32.1-53.7,32.1
|
||||
c-69,0-129.3-40.3-129.3-67c0-3.7,0.8-7.4,2.2-10.8c-24.8,1.3-56.9,5.7-56.9,34c0,46.4,109.9,103.5,196.9,103.5
|
||||
c66.7,0,83.5-30.2,83.5-54C296.1,154.6,279.9,133.4,250.8,120.7"/>
|
||||
<path d="M250.7,120.7c2.5,12.1,2.5,13.3,2.5,14.9c0,20.6-23.2,32.1-53.7,32.1c-69,0-129.3-40.3-129.3-67c0-3.7,0.8-7.4,2.2-10.8
|
||||
l5.4-13.3c-0.3,0.9-0.4,1.9-0.4,2.8c0,13.6,53.5,58.1,125.2,58.1c18.4,0,45.1-3.8,45.1-25.7c0.1-1.7-0.1-3.4-0.5-5L250.7,120.7z"/>
|
||||
<path class="st0" d="M869.1,151.2c0,17.5,10.5,26,29.7,26c5.9-0.1,11.8-1,17.5-2.5v-20.3c-3.7,1.2-7.5,1.7-11.3,1.7
|
||||
c-7.9,0-10.8-2.5-10.8-9.9v-31.1h22.9V94.2h-22.9V67.7l-25,5.4v21.1h-16.6v20.9h16.6L869.1,151.2z M791,151.7
|
||||
c0-5.4,5.4-8.1,13.6-8.1c5,0,10,0.7,14.9,1.9V156c-4.8,2.6-10.2,3.9-15.6,3.9C795.9,159.9,791.1,156.8,791,151.7 M798.7,177.5
|
||||
c8.8,0,16-1.9,22.6-6.3v5h24.8v-52.5c0-20-13.5-30.9-35.9-30.9c-12.6,0-25,2.9-38.3,9l9,18.4c9.6-4,17.7-6.5,24.8-6.5
|
||||
c10.3,0,15.6,4,15.6,12.2v4c-6.1-1.6-12.3-2.4-18.6-2.3c-21.1,0-33.8,8.8-33.8,24.6C768.9,166.6,780.4,177.6,798.7,177.5
|
||||
M662.5,176.2h26.7v-42.5h44.6v42.5h26.7V67.7h-26.6v41.7h-44.6V67.7h-26.7L662.5,176.2z M561,135.1c0-11.8,9.3-20.8,21.5-20.8
|
||||
c6.4-0.1,12.6,2.1,17.4,6.4v28.6c-4.7,4.4-10.9,6.7-17.4,6.5C570.5,155.8,561,146.8,561,135.1 M600.2,176.1H625V62.3l-25,5.4v30.8
|
||||
c-6.4-3.6-13.6-5.5-20.9-5.4c-23.9,0-42.6,18.4-42.6,42c-0.3,23,18.1,41.9,41.1,42.2c0.2,0,0.5,0,0.7,0c7.9,0,15.6-2.5,22-7.1V176.1
|
||||
z M486.5,113.2c7.9,0,14.6,5.1,17.2,13h-34.2C471.9,118,478.2,113.2,486.5,113.2 M444.2,135.2c0,23.9,19.5,42.5,44.6,42.5
|
||||
c13.8,0,23.9-3.7,34.3-12.4l-16.6-14.7c-3.9,4-9.6,6.2-16.4,6.2c-8.8,0.2-16.8-4.9-20.2-13h58.4v-6.2c0-26-17.5-44.8-41.4-44.8
|
||||
c-23.2-0.4-42.4,18.2-42.7,41.5C444.2,134.6,444.2,134.9,444.2,135.2 M400.9,90.5c8.8,0,13.8,5.6,13.8,12.2s-5,12.2-13.8,12.2h-26.3
|
||||
V90.5H400.9z M347.9,176.2h26.7v-39.5h20.3l20.5,39.5h29.7l-23.9-43.4c12.4-5,20.5-17.1,20.4-30.5c0-19.5-15.3-34.5-38.3-34.5H348
|
||||
L347.9,176.2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -0,0 +1,24 @@
|
||||
- name: create HTML report
|
||||
ansible.builtin.template:
|
||||
src: report.j2
|
||||
dest: "{{ file_path }}/windows.html"
|
||||
|
||||
- name: copy CSS over
|
||||
ansible.builtin.copy:
|
||||
src: "css"
|
||||
dest: "{{ file_path }}"
|
||||
directory_mode: true
|
||||
|
||||
- name: copy logos over
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ file_path }}"
|
||||
directory_mode: true
|
||||
loop:
|
||||
- "webpage_logo.png"
|
||||
- "redhat-ansible-logo.svg"
|
||||
- "server.png"
|
||||
|
||||
- name: display link to inventory report
|
||||
ansible.builtin.debug:
|
||||
msg: "Please go to http://{{ ansible_host }}/windows.html"
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
<header>
|
||||
<div class="header-container">
|
||||
<a href="https://ansible.com">
|
||||
<img
|
||||
class="header-logo"
|
||||
src="redhat-ansible-logo.svg"
|
||||
title="Red Hat Ansible"
|
||||
alt="Red Hat Ansible"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,29 @@
|
||||
<!–– INTERNAL TABLE FOR PACKAGES --!>
|
||||
<div id="accordion">
|
||||
<div class="ui-accordion ui-widget ui-helper-reset" role="tablist">
|
||||
<h3 class="ui-accordion-header ui-corner-top ui-state-default ui-accordion-icons ui-accordion-header-collapsed ui-corner-all" role="tab" id="ui-id-3" aria-controls="ui-id-4" aria-selected="false" aria-expanded="false" tabindex="0">Package Facts</h3>
|
||||
<div class="net_content ui-accordion-content ui-corner-bottom ui-helper-reset ui-widget-content" id="ui-id-4" aria-labelledby="ui-id-3" role="tabpanel" aria-hidden="true" style="display: none; height: 194px;">
|
||||
<table id="subtable" class="sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Package Name</th>
|
||||
<th>Version</th>
|
||||
<th>Publisher</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if hostvars[windows_host]['packages'] is defined %}
|
||||
{% for package in hostvars[windows_host]['packages'] %}
|
||||
<tr>
|
||||
<td>{{package['name']}}</td>
|
||||
<td>{{package['version']}}</td>
|
||||
<td>{{package['publisher']}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!–– END INTERNAL TABLE FOR PACKAGES --!>
|
||||
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> Ansible Windows Automation Report </title>
|
||||
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
|
||||
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
|
||||
<link rel="stylesheet" href="css/new.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
|
||||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
|
||||
<script src="https://www.kryogenix.org/code/browser/sorttable/sorttable.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
$( "#accordion > div" ).accordion({
|
||||
header: "h3",
|
||||
active: false,
|
||||
collapsible: true
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
(function(document) {
|
||||
'use strict';
|
||||
|
||||
var TableFilter = (function(myArray) {
|
||||
var search_input;
|
||||
|
||||
function _onInputSearch(e) {
|
||||
search_input = e.target;
|
||||
var tables = document.getElementsByClassName(search_input.getAttribute('data-table'));
|
||||
myArray.forEach.call(tables, function(table) {
|
||||
myArray.forEach.call(table.tBodies, function(tbody) {
|
||||
myArray.forEach.call(tbody.rows, function(row) {
|
||||
var text_content = row.textContent.toLowerCase();
|
||||
var search_val = search_input.value.toLowerCase();
|
||||
row.style.display = text_content.indexOf(search_val) > -1 ? '' : 'none';
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
var inputs = document.getElementsByClassName('search-input');
|
||||
myArray.forEach.call(inputs, function(input) {
|
||||
input.oninput = _onInputSearch;
|
||||
});
|
||||
}
|
||||
};
|
||||
})(Array.prototype);
|
||||
|
||||
document.addEventListener('readystatechange', function() {
|
||||
if (document.readyState === 'complete') {
|
||||
TableFilter.init();
|
||||
}
|
||||
});
|
||||
|
||||
})(document);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
{% include 'header.j2' %}
|
||||
<section>
|
||||
<center>
|
||||
<h1>Ansible Windows Automation Report</h1>
|
||||
<h3><input type="search" placeholder="Search..." class="form-control search-input" data-table="main_net_table"/>
|
||||
</center>
|
||||
<table class="table table-striped mt32 main_net_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Windows Device</th>
|
||||
<th>Operating System</th>
|
||||
<th>Operating System Kernel Version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for windows_host in groups['tag_Windows']|sort %}
|
||||
<tr>
|
||||
<td class="summary_info">
|
||||
<div id="hostname">
|
||||
<p class="hostname">
|
||||
<img class="router_image" src="server.png"> {{ hostvars[windows_host]['inventory_hostname'].split('.')[0] }}</p>
|
||||
</div>
|
||||
{% if detailedreport == 'True' %}
|
||||
{% include 'packages.j2' %}
|
||||
{% include 'services.j2' %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{hostvars[windows_host]['ansible_os_family']|default("none")}}</td>
|
||||
<td>{{hostvars[windows_host]['ansible_distribution']|default("none")}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<center><p>Created with</p><br><img src="webpage_logo.png" width="300">
|
||||
</center>
|
||||
</section>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<!–– INTERNAL TABLE FOR SERVICES --!>
|
||||
<div id="accordion">
|
||||
<div class="ui-accordion ui-widget ui-helper-reset" role="tablist">
|
||||
<h3 class="ui-accordion-header ui-corner-top ui-state-default ui-accordion-icons ui-accordion-header-collapsed ui-corner-all" role="tab" id="ui-id-3" aria-controls="ui-id-4" aria-selected="false" aria-expanded="false" tabindex="0">Services Facts</h3>
|
||||
<div class="net_content ui-accordion-content ui-corner-bottom ui-helper-reset ui-widget-content" id="ui-id-4" aria-labelledby="ui-id-3" role="tabpanel" aria-hidden="true" style="display: none; height: 194px;">
|
||||
<table id="subtable" class="sortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Display Name</th>
|
||||
<th>Windows Services Name</th>
|
||||
<th>State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% if hostvars[windows_host]['services'] is defined %}
|
||||
{% for service in hostvars[windows_host]['services'] %}
|
||||
<tr>
|
||||
<td>{{service['name']}}</td>
|
||||
<td>{{service['win_svc_name']}}</td>
|
||||
<td>{{service['state']}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!–– END INTERNAL TABLE FOR SERVICES --!>
|
||||
@@ -0,0 +1 @@
|
||||
file_path: /var/www/html
|
||||
@@ -0,0 +1,36 @@
|
||||
build_report_windows_patch
|
||||
========
|
||||
|
||||
Installs Apache and creates a report based on facts from Windows update job
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Must run on Apache server
|
||||
|
||||
Role Variables / Configuration
|
||||
--------------
|
||||
|
||||
N/A
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
N/A
|
||||
|
||||
Example Playbook
|
||||
----------------
|
||||
|
||||
The role can be used to create an html patching report on any number of Linux hosts using any number of Windows servers
|
||||
|
||||
|
||||
```
|
||||
---
|
||||
- hosts: all
|
||||
|
||||
tasks:
|
||||
- name: Run Windows Patch Report
|
||||
import_role:
|
||||
name: shadowman.reports.build_report_windows_patch
|
||||
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
EMAIL_FROM: tower@shadowman.dev
|
||||
to_emails: alex@shadowman.dev,tower@shadowman.dev
|
||||
EMAIL_TO: "{{ to_emails.split(',') }}"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
@@ -0,0 +1,111 @@
|
||||
p.hostname {
|
||||
color: #000000;
|
||||
font-weight: bolder;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
#subtable {
|
||||
background: #ebebeb;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#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: #ffffff;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #ffffff;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
background:#353a40;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
background:#fff;
|
||||
@include border-radius(5px);
|
||||
margin:50px auto;
|
||||
@include box-shadow(0px 0px 5px rgba(0,0,0,0.3));
|
||||
}
|
||||
|
||||
thead {
|
||||
@include border-radius(5px);
|
||||
}
|
||||
|
||||
thead th {
|
||||
font-family: 'Patua One', monospace;
|
||||
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-family: 'Open Sans', sans-serif;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
span.highlight {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
.expandclass {
|
||||
color: #5f6062;
|
||||
}
|
||||
|
||||
.content{
|
||||
display:none;
|
||||
margin: 10px;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
@@ -0,0 +1,38 @@
|
||||
- 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
|
||||
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title> Windows Patch Report </title>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1>Ansible Windows Patching Report</h1>
|
||||
<style>
|
||||
@media print {
|
||||
.noprint {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="noprint">
|
||||
<button type="button" onclick="tableToCSV()">Download CSV</button>
|
||||
<input type="button" value="Print" onClick="window.print()">
|
||||
</div>
|
||||
</center>
|
||||
<table border = "1" cellpadding = "5" cellspacing = "5">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Hostname</th>
|
||||
<th>Operating System</th>
|
||||
<th>Required Updates</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for windows_host in groups['tag_Windows']|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] %}
|
||||
<li>{{updatenum.title}}</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li>Compliant</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% for host in ansible_play_hosts %}
|
||||
<center><p>Created with Ansible on {{hostvars[host].ansible_date_time.iso8601}}</p></center>
|
||||
{% endfor %}
|
||||
<script type="text/javascript">
|
||||
function tableToCSV() {
|
||||
|
||||
// Variable to store the final csv data
|
||||
var csv_data = [];
|
||||
|
||||
// Get each row data
|
||||
var rows = document.getElementsByTagName('tr');
|
||||
for (var i = 0; i < rows.length; i++) {
|
||||
|
||||
// Get each column data
|
||||
var cols = rows[i].querySelectorAll('td,th');
|
||||
|
||||
// Stores each csv row data
|
||||
var csvrow = [];
|
||||
for (var j = 0; j < (cols.length); j++) {
|
||||
|
||||
// Get the text data of each cell of
|
||||
// a row and push it to csvrow
|
||||
if ( j == cols.length-1 && i==0){}
|
||||
else{
|
||||
csvrow.push(cols[j].textContent.replace(/,/g, " "));
|
||||
}
|
||||
|
||||
}
|
||||
csv_data.push(csvrow.join(","));
|
||||
}
|
||||
|
||||
// combine each row data with new line character
|
||||
csv_data = csv_data.join('\n');
|
||||
|
||||
// Call this function to download csv file
|
||||
downloadCSVFile(csv_data);
|
||||
}
|
||||
function downloadCSVFile(csv_data) {
|
||||
|
||||
// Create CSV file object and feed our
|
||||
// csv_data into it
|
||||
CSVFile = new Blob([csv_data], { type: "text/csv" });
|
||||
|
||||
// Create to temporary link to initiate
|
||||
// download process
|
||||
var temp_link = document.createElement('a');
|
||||
var todayDate = new Date().toISOString().slice(0, 10);
|
||||
|
||||
// Download csv file
|
||||
temp_link.download = "windowspatching-" + todayDate + ".csv";
|
||||
var url = window.URL.createObjectURL(CSVFile);
|
||||
temp_link.href = url;
|
||||
|
||||
// This link should not be displayed
|
||||
temp_link.style.display = "none";
|
||||
document.body.appendChild(temp_link);
|
||||
|
||||
// Automatically click the link to trigger download
|
||||
temp_link.click();
|
||||
document.body.removeChild(temp_link);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
file_path: /var/www/html
|
||||
@@ -24,4 +24,4 @@
|
||||
|
||||
- name: display link to inventory report
|
||||
ansible.builtin.debug:
|
||||
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/linux.html"
|
||||
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/linux.html"
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
ansible.builtin.debug:
|
||||
msg: "Please go to http://{{ hostvars[report_server]['ansible_host'] }}/reports/linuxpatch.html"
|
||||
|
||||
|
||||
#- name: Send Report via E-mail
|
||||
# community.general.mail:
|
||||
# host: "{{ EMAIL_HOST }}"
|
||||
|
||||
@@ -16,6 +16,6 @@ collections:
|
||||
version: 1.9.0
|
||||
#cloud
|
||||
- name: azure.azcollection
|
||||
version: 1.11.0
|
||||
version: 1.13.0
|
||||
- name: amazon.aws
|
||||
version: 3.1.1
|
||||
|
||||
Reference in New Issue
Block a user