Category: windows

TightVNC Security Hole

Virtual Network Computing (VNC) is a graphical desktop-sharing system that uses the Remote Frame Buffer protocol (RFB) to remotely control another computer. It transmits the keyboard and mouse input from one computer to another, relaying the graphical-screen updates, over a network.[1]

VNC servers work on a variety of platforms, allowing you to share screens and keyboards between Windows, Mac, Linux, and Raspberry Pi devices. RDP server is proprietary and only works with one operating system. VNC vs RDP performance. RDP provides a better and faster remote connection.

There are a number of reasons why people use it.

 RDP requires licenses and VNC does not.
 You can also have multiple sessions on a user
 You can set it so it will connect to an existing session (which is what a lot folks use it for)
 It can be used on multiple OS’s including linux; while RDP is just for windows

There are a few VNC tools out there.

RealVNC

 They have enterprise version
 Requires Licenses
 Has no AD authentication
 Has decent Encryption

UltraVNC – Best one to use.

 Has AD authentication
 Has good Encryption
 AD authentication
 File transfer inside the VNC connection
 Multiuser connections and Existing
 Loads of features the others don’t have
 Is considered the most secure
 Free for personal and commercial use
 Available through chocolatey package manager

Tight-VNC – Security Hole

 Free
 Has encryption but its DES with an 8 character limit
 Available through chocolatey package manager

.

Tight-VNC has their encryption algorithm hardcoded into its software and appears they have NOT updated its encryption standards in years.

.

.

DES Encryption used

# This is hardcoded in VNC applications like TightVNC.

    $magicKey = [byte[]]@(0xE8, 0x4A, 0xD6, 0x60, 0xC4, 0x72, 0x1A, 0xE0)

    $ansi = [System.Text.Encoding]::GetEncoding(

        [System.Globalization.CultureInfo]::CurrentCulture.TextInfo.ANSICodePage)

.

    $pass = [System.Net.NetworkCredential]::new(, $Password).Password    

    $byteCount = $ansi.GetByteCount($pass)

    if ($byteCount gt 8) {

        $err = [System.Management.Automation.ErrorRecord]::new(

            [ArgumentException]‘Password must not exceed 8 characters’,

            PasswordTooLong,

            [System.Management.Automation.ErrorCategory]::InvalidArgument,

            $null)

        $PSCmdlet.WriteError($err)

        return

    }

.

    $toEncrypt = [byte[]]::new(8)

    $null = $ansi.GetBytes($pass, 0, $pass.Length, $toEncrypt, 0)

    

    $des = $encryptor = $null

    try {

        $des = [System.Security.Cryptography.DES]::Create()

        $des.Padding = ‘None’

        $encryptor = $des.CreateEncryptor($magicKey, [byte[]]::new(8))

.

        $data = [byte[]]::new(8)

        $null = $encryptor.TransformBlock($toEncrypt, 0, $toEncrypt.Length, $data, 0)

.

        , $data

    }

    finally {

        if ($encryptor) { $encryptor.Dispose() }

        if ($des) { $des.Dispose() }

    }

}

.

What this means is…IF you are using admin credentials on your machine while using Tight-VNC a hacker that is way better than I… Could gain access to your infrastructure by simply glimpsing the windows registry. Im sure there ways to exploit it.

I will demonstrate:

Now you can install Tight-vnc manually or via chocolatey. I used chocolatey and this from a public available repo.

.

.

Now lets set the password by right clicking tightvnc icon in the bottom corner and setting the password to an 8 character password, by clicking on change primary password and typing in whatever you like

‘Suck3r00’

.

A screenshot of a computer

Description automatically generated

.

.

Now lets open powershell without administrator privileges. Lets say I got in remotely and chocolatey is there and I want to check to see if tight-vnc is there.

.

A screenshot of a computer

Description automatically generated

.

As you can see I find this without administrator privilege.

.

Now lets say I was able to view the registry and get the encrypted value for tight-vnc; all I need to do is see for a few seconds.

.

.

Now there are tools online where you can convert that hexadecimal to binary decimal values long before AI was around. But since I love GPT im going to ask it to convert that for me

.

.

I have script that didn’t take long to put together from digging around for about an hour online. Which im obviously not going to share, BUT if I can do it……someone with skills could do pretty easy. A professional hacker NO SWEAT.

A computer screen shot of a blue screen

Description automatically generated

.

.As you can see if you have rolled this out how dangerous it is.

Having said that I have also written an Ansible Role which will purge tightvnc from your infrastructure and deploy ultravnc which will use encryption and AD authentication. Which the other two currently do NOT do.

.

Hope you enjoyed getting P0WNed.

.

.

.

.

How to Deploy VM’s in Hyper-V with Ansible

Thought it would be fun to do…..

If you can find another public repo that has it working online. Please send me a message so I can kick myself.

 This role will allow you to use a vhdx image to deploy vm’s in hyperv
 It will use the vm name to create a sub-folder to place the new vm image in
 It will configure the network switch
 It will setup the vlan tag/id and enable it
 It will also set the smart-paging file location to the destination path of the vm
 It will configure the OS network configuration
 It will power on the machine and wait for response successfully
 It can also remove vms
 You can also call the role with tags if you want…

.

How to use this role:

1.You must first download the git repository into your roles directory usually ansible/role/
2.Now you want edit the hosts.client file name file or create it if it doesn’t exist under your “ansible/inventory/dev:staging:prod” directory. This is a good way to separate environments with ansible, inside each environment you should have a hosts.file like indicated below.

Example file: hosts.dev, hosts.staging, hosts.prod

b.Put your server under the appropriate group inside the file and save
i.testmachine1.nicktailor.com ansible_host=192.168.1.101 (the ip is pointed to the hypervisor)

Note: If there is no group simply list the server outside grouping, the –limit flag will pick it

up.

3.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

c.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
d.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
e.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

4.Move inside host_var
f.cd host_var
g.create a file called {{ servername }} and save it for us its testmachine1.nicktailor.com

.

5.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

h.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
i.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
j.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

6.Move inside host_var
k.cd host_var
l.create a file called {{ servername }} and save it for us its testmachine1.nicktailor.com
m.add the following parameters to your inventory file and save.

passed parameters: example: inventory/host_vars/testmachine.nicktailor.com

vms:

  – type: testserver

    name: nicktest

.

    cpu: 2   

    memory: 4096MB

.

    network:

      ip: 192.168.23.26

      netmask: 255.255.255.0

      gateway: 192.168.23.254

      dns: 192.168.0.17,192.168.0.18

      

#    network_switch: ‘External Virtual Switch’

    network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’

    vlanid: 1113

.

#   source-image

    src_vhd: ‘Z:\volumes\devops\devopssysprep\devopssysprep.vhdx

.

#   destination will be created in Z:\\volumes\servername\servername.vhdx by default

#   to change the paths you need to update the prov_vm.yml’s first three task paths

.

Running your playbook:

1.You must run your play book from inside parent directory always “ansible
2.Now there is a playbook called createvm.yml in the ansible directory which simply calls the ansible-hyperv role inside the roles directory.

Example: of ansible/createvm.yml

name: Provision VM

  hosts: hypervdev.nicktailor.com

  gather_facts: no

.

  tasks:

    – import_tasks: roles/ansible-hyperv/tasks/prov_vm.yml

.

Command:

ansible-playbook –i inventory/dev/hosts createvm.ymllimit=’testmachine1.nicktailor.com

 -i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by environment like hosts.dev or hosts.staging
 -u : this is the ssh_user you will be connecting to the servers with
 -Kkb : this tells ansible that you will be using sudo su – for the ssh_user when running all role/tasks
 -ask-beocme : is saying become root
 -limit=’server’ : this allows you to segement which server you want to run the playbook against.

.

Successful example run of the book:

.

[ntailor@ansible-home ~]$ ansible-playbook –i inventory/hosts createvm.yml –limit=’testmachine1.nicktailor.com

.

PLAY [Provision VM] ****************************************************************************************************************************************************************

.

TASK [Create directory structure] **************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Check whether vhdx already exists] *******************************************************************************************************************************************

ok: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Clone vhdx] ******************************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘changed’: False, ‘invocation’: {module_args: {‘path’: ‘Z:\\\\volumes\\\\devops\\nicktest\\nicktest.vhdx, checksum_algorithm: ‘sha1’, get_checksum: False, ‘follow’: False, ‘get_md5’: False}}, ‘stat’: {‘exists’: False}, ‘failed’: False, ‘item’: {‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx}, ansible_loop_var: ‘item’})

.

TASK [set_fact] ********************************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com]

.

TASK [debug] ***********************************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com] => {

    path_folder: “Z:\\\\volumes\\\\devops\\nicktest\\nicktest.vhdx”

}

.

TASK [set_fact] ********************************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com]

.

TASK [debug] ***********************************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com] => {

    page_folder: “Z:\\\\volumes\\\\devops\\nicktest”

}

.

TASK [Create VMs] ******************************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Set SmartPaging File Location for new Virtual Machine to use destination image path] *****************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Set Network VlanID] **********************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Configure VMs IP] ************************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [add_host] ********************************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘changed’: True, ‘failed’: False, ‘item’: {‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx}, ansible_loop_var: ‘item’})

.

TASK [Poweron VMs] *****************************************************************************************************************************************************************

changed: [testmachine1.nicktailor.com] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [Wait for VM to be running] ***************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com -> localhost] => (item={‘type’: testservers, ‘name’: nicktest, cpu: 2, ‘memory’: ‘4096MB’, ‘network’: {ip: ‘192.168.23.36’, ‘netmask’: ‘255.255.255.0’, ‘gateway’: ‘192.168.23.254’, dns: 192.168.0.17,192.168.0.18}, network_switch: ‘Cisco VIC Ethernet Interface #6 – Virtual Switch’, vlanid: 1113, ‘src_vhd: ‘C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx})

.

TASK [debug] ***********************************************************************************************************************************************************************

ok: [testmachine1.nicktailor.com] => {

    “wait”: {

        “changed”: false,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “elapsed”: 82,

                “failed”: false,

                “invocation”: {

                    module_args: {

                        active_connection_states: [

                            “ESTABLISHED”,

                            “FIN_WAIT1”,

                            “FIN_WAIT2”,

                            “SYN_RECV”,

                            “SYN_SENT”,

                            “TIME_WAIT”

                        ],

                        connect_timeout: 5,

                        “delay”: 0,

                        exclude_hosts: null,

                        “host”: “192.168.23.36”,

                        msg: null,

                        “path”: null,

                        “port”: 5986,

                        search_regex: null,

                        “sleep”: 1,

                        “state”: “started”,

                        “timeout”: 100

                    }

                },

                “item”: {

                    cpu: 2,

                    “memory”: “4096MB”,

                    “name”: nicktest,

                    “network”: {

                        dns: 192.168.0.17,192.168.0.18,

                        “gateway”: “192.168.23.254”,

                        ip: “192.168.23.36”,

                        “netmask”: “255.255.255.0”

                    },

                    network_switch: “Cisco VIC Ethernet Interface #6 – Virtual Switch”,

                    src_vhd: “C:\\volumes\\devops\\devopssysprep\\devopssysprep.vhdx”,

                    “type”: testservers,

                    vlanid: 1113

                },

                match_groupdict: {},

                match_groups: [],

                “path”: null,

                “port”: 5986,

                search_regex: null,

                “state”: “started”

            }

        ]

    }

}

.

PLAY RECAP *************************************************************************************************************************************************************************

testmachine1.nicktailor.com      : ok=15   changed=7    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

.

.

.

How to Join Windows Servers to your DC with Ansible

 This role will simply join a new windows server to the domain
 You simply need to define the passed parameters in defaults/main.yml indicated below
 This role will ask you for the domain admin password at runtime so you will need to know it. Don’t need to worry about vaulting the admin AD password in the code
 This role assume your windows host is already configured to use winrm

How to use this role:

1.You must first download the git repository into your roles directory usually ansible/role/
2.Now you want edit the hosts.client file name file or create it if it doesn’t exist under your “ansible/inventory/dev:staging:prod” directory. This is a good way to separate environments with ansible, inside each environment you should have a hosts.file like indicated below.

Example file: hosts.dev, hosts.staging, hosts.prod

c.Put your server under the appropriate group inside the file and save
i.Testmachine1.nicktailor.coml ansible_host=192.168.1.101

Note: If there is no group simply list the server outside grouping, the –limit flag will pick it

up.

3.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

d.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
e.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
f.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

4.Move inside host_var
g.cd host_var
h.create a file called {{ servername }} and save it for us its testmachine1.nicktailor.com

.

5.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

i.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
j.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
k.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

6.Move inside host_var
l.cd host_var
m.create a file called {{ servername }} and save it for us its testmachine1.nicktailor.com
n.add the following parameters to your inventory file and save.

passed parameters: example: roles/add-server-to-dc/default/main.yml

dns_domain_name: ad.nicktailor.com

computer_name: testmachine1

domain_ou_path: “OU=Admin,DC=nicktailor,DC=local”

domain_admin_user: adminuser@nicktailor.com

state: domain

.

Running your playbook:

1.You must run your play book from inside parent directory always “ansible
2.Now there is a playbook called joinservertodomain.yml in the ansible directory which simply calls the add-servers-to-dc role inside the roles directory.

Example: of ansible/joinservertodomain.yml

hosts: all

  gather_facts: no

  vars_prompt:

  – name: domain_pass

    prompt: Enter Admin Domain Password

  roles:

    – role: addservers-todc

.

Command:

ansible-playbook –i inventory/dev/hosts joinservertodomain.ymllimit=’testmachine1.nicktailor.com

 -i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by environment like hosts.dev or hosts.staging
 -u : this is the ssh_user you will be connecting to the servers with
 -Kkb : this tells ansible that you will be using sudo su – for the ssh_user when running all role/tasks
 -ask-beocme : is saying become root
 -limit=’server’ : this allows you to segement which server you want to run the playbook against.

.

Successful example run of the book:

.

[alfred@ansible.nicktailor.com ~]$ ansible-playbook –i inventory/hosts joinservertodomain.yml –limit=’testmachine1.nicktailor.com

ansible-playbook 2.9.27

  config file = /etc/ansible/ansible.cfg

  configured module search path = [‘/home/alfred/.ansible/plugins/modules’, ‘/usr/share/ansible/plugins/modules’]

  ansible python module location = /usr/lib/python3.6/site-packages/ansible

  executable location = /usr/bin/ansible-playbook

  python version = 3.6.8 (default, Nov 10 2021, 06:50:23) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3.0.2)]

.

PLAYBOOK: joinservertodomain.yml *****************************************************************************************************************************************************

Positional arguments: joinservertodomain.yml

verbosity: 4

connection: smart

timeout: 10

become_method: sudo

tags: (‘all’,)

inventory: (‘/home/alfred/inventory/hosts’,)

subset: testmachine1.nicktailor.com

forks: 5

1 plays in joinservertodomain.yml

Enter Domain Password:

.

PLAY [all] ***********************************************************************************************************************************************************************

META: ran handlers

.

TASK [addservertodc : Join windows host to Domain Controller] ********************************************************************************************************************

task path: /home/alfred/roles/addservertodc/tasks/main.yml:1

Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/win_domain_membership.ps1

Pipelining is enabled.

<testmachine1.nicktailor.com> ESTABLISH WINRM CONNECTION FOR USER: ansibleuser on PORT 5986 TO testmachine1.nicktailor.com

EXEC (via pipeline wrapper)

changed: [testmachine1.nicktailor.com] => {

    “changed”: true,

    reboot_required: true

}

.

TASK [addservertodc : win_reboot] ************************************************************************************************************************************************

win_reboot: system successfully rebooted

changed: [testmachine1.nicktailor.com] => {

    “changed”: true,

    “elapsed”: 23,

    “rebooted”: true

}

META: ran handlers

META: ran handlers

.

PLAY RECAP ***********************************************************************************************************************************************************************

testmachine1.nicktailor.com       : ok=2    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

.

.

.

.

How to deploy windows firewall rules with Ansible

 This role enable the windows firewall for all 3 profiles (Domain, Private, Public)
 You can deploy rules via profile or globally using defaults, group_vars and host_vars
 You also can set outbound rules for windows programs

How to use this role:

1.You must first download the git repository into your roles directory usually ansible/role/
2.Now you want edit the hosts.client file name file or create it if it doesn’t exist under your “ansible/inventory/dev:staging:prod” directory. This is a good way to separate environments with ansible, inside each environment you should have a hosts.file like indicated below.

Example file: hosts.dev, hosts.staging, hosts.prod

b.Put your server under the appropriate group inside the file and save
i.devops.nicktailor.win ansible_host=192.168.90.10

Note: If there is no group simply list the server outside grouping, the –limit flag will pick it

up.

3.Now inside this directory you should see hosts & host_vars, group_vars

Note: If you do not create a group_var/groupfile or host_var/server file. Then the default/main.yml rules are implemented by this role, you can update this file to have whichever defaults you like and they can be overridden at the group_var and host_var level, should you need to.

Descriptions:

c.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
d.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
e.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

4.Move inside host_var
f.cd host_var
g.create a file called {{ servername }} and save it for us its devops.nicktailor.win

.

5.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

h.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
i.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
j.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

6.Move inside host_var
k.cd host_var
l.create a file called {{ servername }} and save it for us its devops.nicktailor.win

Okay now here is where VSC is handy. You want to connect your visual studio code to the management server under your user. I have provided a link which shows you how to setup your keys and get VSC working with it.

.

Note: You don’t have to use VSC you can use good old nano or vim, but it’s a pain. Up to you.

.

defaults/main.yml – this file is the default rules it will apply if you do not add any other rules currently

# defaults file for windows_firewall

win_fw_prefix: “Ansible-Created-Rule”

.

win_fw_ports_allow_in:

  – localport: 53,

    profile: public

.

  – localport: 123,

    profile: public

.

win_fw_web_ports:

  – localport: 80,

    profile: public

.

  – localport: 443,

    profile: public

.

  – localport: 8080,

    profile: public

    

win_fw_program_allowed_web_out_public:

  – ‘microsoftupdate.exe’

..

Running your playbook:

1.You must run your play book from inside parent directory always “ansible
2.Now there is a playbook called nickfirewall.yml in the ansible directory which simply calls the windows-firewall role inside the roles directory.

Example: of ansible/ nickfirewall.yml

hosts: all

  gather_facts: yes

  any_errors_fatal: true

  roles:

    – role: ansible-windows-firewall

.

Command:

ansible-playbook –i inventory/dev/hosts nickfirewall.yml limit=’devops.nicktailor.win

 -i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by environment like hosts.dev or hosts.staging
 -u : this is the ssh_user you will be connecting to the servers with
 -Kkb : this tells ansible that you will be using sudo su – for the ssh_user when running all role/tasks
 -ask-beocme : is saying become root
 -limit=’server’ : this allows you to segement which server you want to run the playbook against.

.

Successful example run of the book:

.

[aflred@batcave.ansible]$ ansible-playbook –i hosts/dev nickfirewall.yml –limit=’devops.nicktailor.win

.

PLAY [all] ***************************************************************************************************************************************************************************

.

TASK [Gathering Facts] ***************************************************************************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [windows_firewall : Enable firewall for Domain, Public and Private profiles] ****************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [windows_firewall : Firewall | WebServer System Any Profile] ********************************************************************************************************************

ok: [devops.nicktailor.win] => (item={‘description’: ‘IGMP messages are sent and received by nodes to create, join and depart multicast groups.’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: ‘Any’, ‘name’: ‘CoreNet-IGMP-In’, ‘protocol’: ‘2’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘IGMP messages are sent and received by nodes to create, join and depart multicast groups.’, ‘direction’: ‘out’, icmp_type_code: ‘Any’, localport: ‘Any’, ‘name’: ‘CoreNet-IGMP-Out’, ‘protocol’: ‘2’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘Inbound rule required to permit IPv6 traffic for ISATAP (Intra-Site Automatic Tunnel Addressing Protocol) and 6to4 tunneling services.’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: ‘Any’, ‘name’: ‘CoreNet-IPv6-In’, ‘protocol’: ’41’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘Outbound rule required to permit IPv6 traffic for ISATAP (Intra-Site Automatic Tunnel Addressing Protocol) and 6to4 tunneling services.’, ‘direction’: ‘out’, icmp_type_code: ‘Any’, localport: ‘Any’, ‘name’: ‘CoreNet-IPv6-Out’, ‘protocol’: ’41’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘An inbound rule to allow HTTPS traffic for Internet Information Services (IIS) [TCP 443]’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: ‘443’, ‘name’: ‘IIS-WebServerRole-HTTPS-In-TCP’, ‘protocol’: ‘TCP’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘Inbound rule to allow SMB traffic to manage the File Services role.’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: ‘445’, ‘name’: FileServerServerManager-SMB-TCP-In’, ‘protocol’: ‘TCP’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘An inbound rule to allow HTTP traffic for Internet Information Services (IIS) [TCP 80]’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: ’80’, ‘name’: ‘IIS-WebServerRole-HTTP-In-TCP’, ‘protocol’: ‘TCP’, remoteip: ‘Any’})

ok: [devops.nicktailor.win] => (item={‘description’: ‘Inbound TCP rule to allow IPHTTPS tunneling technology to provide connectivity across HTTP proxies and firewalls.’, ‘direction’: ‘in’, icmp_type_code: ‘Any’, localport: IPHTTPSIn, ‘name’: ‘CoreNet-IPHTTPS-In’, ‘protocol’: ‘TCP’, remoteip: ‘Any’})

.

TASK [windows_firewall : Firewall | allow incoming ports] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => (item={localport: 53, ‘profile’: ‘public’})

ok: [devops.nicktailor.win] => (item={localport: 123, ‘profile’: ‘public’})

ok: [devops.nicktailor.win] => (item={localport: 80, ‘profile’: ‘public’})

ok: [devops.nicktailor.win] => (item={localport: 443, ‘profile’: ‘public’})

ok: [devops.nicktailor.win] => (item={localport: 8080, ‘profile’: ‘public’})

.

TASK [windows_firewall : Firewall | allow outgoing program] **************************************************************************************************************************

ok: [devops.nicktailor.win] => (item=microsoftupdate.exe)

.

PLAY RECAP ***************************************************************************************************************************************************************************

devops.nicktailor.win       : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

.

.

.

.

.

How to deploy windows shares with Ansible

 This will role will setup a network share on windows
 It will also update the user permission on the folder
 You can also adjust the folder missions

How to use this role:

1.You must first download the git repository into your roles directory usually ansible/role/
a.git clone git@github.com:Perfect10NickTailor/ansible-windows-shares.git

.

2.Now you want edit the hosts.client file name file or create it if it doesn’t exist under your “ansible/inventory/dev:staging:prod” directory. This is a good way to separate environments with ansible, inside each environment you should have a hosts.file like indicated below.

Example file: hosts.dev, hosts.staging, hosts.prod

b.Put your server under the appropriate group inside the file and save
devops.nicktailor.win ansible_host=192.168.90.10

Note: If there is no group simply list the server outside grouping, the –limit flag will pick it

up.

3.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

c.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
d.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
e.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

4.Move inside host_var
f.cd host_var
g.create a file called {{ servername }} and save it for us its devops.nicktailor.win

.

5.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

h.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
i.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
j.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

6.Move inside host_var
k.cd host_var
l.create a file called {{ servername }} and save it for us its devops.nicktailor.win

Okay now here is where VSC is handy. You want to connect your visual studio code to the management server under your user. I have provided a link which shows you how to setup your keys and get VSC working with it.

.

Note: You don’t have to use VSC you can use good old nano or vim, but it’s a pain. Up to you.

.

Running your playbook:

1.You must run your play book from inside parent directory always “ansible
2.Now there is a playbook called nickcreateshare.yml in the ansible directory which simply calls the ansible-role-win-iis role inside the roles directory.

Example: of ansible/ nickcreateshare.yml

hosts: all

  gather_facts: yes

  any_errors_fatal: true

  roles:

    – role: ansible-windows-share

.

Command:

ansible-playbook –i inventory/dev/hosts nickcreateshare.yml limit=’devops.nicktailor.win

 -i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by environment like hosts.dev or hosts.staging
 -u : this is the ssh_user you will be connecting to the servers with
 -Kkb : this tells ansible that you will be using sudo su – for the ssh_user when running all role/tasks
 -ask-beocme : is saying become root
 -limit=’server’ : this allows you to segement which server you want to run the playbook against.

.

Successful example run of the book:

.

[BruceWayne@batcave.ansible ~]$ ansible-playbook –i inventory/hosts nickcreateshare.yml –limit=devops.nicktailor.win

.

PLAY [all] ***************************************************************************************************************************************************************************

.

TASK [Gathering Facts] ***************************************************************************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [create-windows-share : Create share path] **************************************************************************************************************************************

changed: [devops.nicktailor.win] => (item={share_name: ‘test3’, description_share: ‘default share for testing’, share_path: ‘C:\\inetpub\\wwwroot3′, ‘change’: ansibleuser, ‘list’: True, ‘allowed_users: ansibleuser, user_permissions: ansibleuser})

.

TASK [create-windows-share : debug] **************************************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “path”: {

        “changed”: true,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: true,

                “failed”: false,

                “item”: {

                    allowed_users: ansibleuser,

                    “change”: ansibleuser,

                    description_share: “default share for testing”,

                    “list”: true,

                    share_name: “test3”,

                    share_path: “C:\\inetpub\\wwwroot3″,

                    user_permissions: ansibleuser

                }

            }

        ]

    }

}

.

TASK [create-windows-share : Add public company share] *******************************************************************************************************************************

changed: [devops.nicktailor.win] => (item={share_name: ‘test3’, description_share: ‘default share for testing’, share_path: ‘C:\\inetpub\\wwwroot3′, ‘change’: ansibleuser, ‘list’: True, ‘allowed_users: ansibleuser, user_permissions: ansibleuser})

.

TASK [create-windows-share : debug] **************************************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “share”: {

        “changed”: true,

        msg: “All items completed”,

        “results”: [

            {

                “actions”: [

                    “New-SmbShare -Name test3 -Path C:\\inetpub\\wwwroot3″,

                    “Set-SmbShare -Force -Name test3 -Description default share for testing”,

                    “Revoke-SmbShareAccess -Force -Name test3 –AccountName Everyone”,

                    “Grant-SmbShareAccess -Force -Name test3 –AccountName DEVOPS01\\ansibleuserAccessRight Full”

                ],

                ansible_loop_var: “item”,

                “changed”: true,

                “failed”: false,

                “item”: {

                    allowed_users: ansibleuser,

                    “change”: ansibleuser,

                    description_share: “default share for testing”,

                    “list”: true,

                    share_name: “test3”,

                    share_path: “C:\\inetpub\\wwwroot3″,

                    user_permissions: ansibleuser

                }

            }

        ]

    }

}

.

TASK [create-windows-share : Give full control on share folder] **********************************************************************************************************************

changed: [devops.nicktailor.win] => (item={share_name: ‘test3’, description_share: ‘default share for testing’, share_path: ‘C:\\inetpub\\wwwroot3′, ‘change’: ansibleuser, ‘list’: True, ‘allowed_users: ansibleuser, user_permissions: ansibleuser})

.

TASK [create-windows-share : debug] **************************************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “permission”: {

        “changed”: true,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: true,

                “failed”: false,

                “item”: {

                    allowed_users: ansibleuser,

                    “change”: ansibleuser,

                    description_share: “default share for testing”,

                    “list”: true,

                    share_name: “test3”,

                    share_path: “C:\\inetpub\\wwwroot3″,

                    user_permissions: ansibleuser

                }

            }

        ]

    }

}

.

PLAY RECAP ***************************************************************************************************************************************************************************

devops.nicktailor.win       : ok=7    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

.

.

.

.

How to deploy multiple sites in IIS with Ansible

This was fun and interesting little project. Looks like nobody ever really got it working properly, so I decided to do it.

 This role will install IIS if its not already installed
      It will also configure all the user permissions needed for IIS
 It will configure a default application pool
 This role will allow you to call the ansible role once and create multiple sites in IIS and attach the sites to the default application pool
 It will also configure the bindings
You can also remove, start, and stop sites

You can also upload your own custom web.config

Additions that are not in any public repo online currently. If you require these additions for your organisation, you may hire or pay for the additions:
  • Ability to create multiple application pools per site.
  • Set application pool identities
  • Update IIS site paths to use a NAS location vs physical paths only

Note: You will likely have to add the firewall rules depending on how your network setup. I have written a windows playbook to handle the firewall stuff, but that will be in another post. You will also need to ensure winrm is configured properly on the windows machine for ansible to talk to it.

Ansible Operational Documentation:

1.You must first download the git repository into your roles directory usually ansible/role/
2.Now you want to edit the hosts.client file name file or create it if it doesn’t exist under your “ansible/inventory/dev:staging:prod” directory. This is a good way to separate environments with ansible, inside each environment you should have a hosts.file like indicated below.

Example file: hosts.dev, hosts.staging, hosts.prod

b.Put your server under the appropriate group inside the file and save
i.devops.nicktailor.win ansible_host=192.168.90.10

Note: If there is no group simply list the server outside grouping, the –limit flag will pick it

up.

3.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

c.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
d.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
e.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

4.Move inside host_var
f.cd host_var
g.create a file called {{ servername }} and save it for us its devops.nicktailor.win

.

5.Now inside this directory you should see hosts & host_vars, group_vars

Descriptions:

h.Hosts. – is where you will list your servers under specific groups which tell the playbook (what the server is, if it the server should have a specific task run on it, and how to find it)
i.Host_vars – Inside this directory is where you list the server by name which is you will list under hosts. Inside these files you pass variable parameters to the specific roles when running your playbook. Without these the playbook cant do the tasks you want it to.
j.Group_varsAre how a way to group variables for sets of servers and this keeps code cleaners and easier to manage.

Operational Use:

6.Move inside host_var
k.cd host_var
l.create a file called {{ servername }} and save it for us its devops.nicktailor.win

Okay now here is where VSC is handy. You want to connect your visual studio code to the management server under your user. 

.

Note: You don’t have to use VSC you can use good old nano or vim, but it’s a pain. Up to you.

.

Example files:

ansible/inventory/dev/host_vars/devops.nicktailor.win

Example Yaml Block :

.

domains:

  – name: “First website”

    host_header:

    ip: ‘*’

    iis_binding_port: ‘8082’

    protocol: ‘http’

    state: ‘absent’

    certificate_hash:

    certificate_store_name: ‘My’

    iis_site_name: ‘Default Web Site’

    iis_site_path: ‘C:\inetpub\wwwroot1′

    iis_acl_path:  ‘C:\inetpub\wwwroot1′

    iis_site_state: absent

    iis_site_port: ’80’

    iis_site_id:

    iis_site_ip: ‘*’

    iis_site_ssl: false

    iis_site_hostname: ‘*’

    iis_site_parameters:

    iis_site_state_start: stopped

    iis_site_web_config:

    iis_site_web_config_force: true

.

  – name: “Second website”

    host_header:

    ip: ‘*’

    iis_binding_port: ‘8081’

    protocol: ‘http’

    state: ‘present’

    certificate_hash:

    certificate_store_name: ‘My’

    iis_site_name: ‘site2’

    iis_acl_path: ‘C:\inetpub\wwwroot2′

    iis_site_path: ‘C:\inetpub\wwwroot2′

    iis_site_state: present

    iis_site_port: ’80’

    iis_site_id:

    iis_site_ip: ‘*’

    iis_site_ssl: false

    iis_site_hostname: ‘*’

    iis_site_parameters:

    iis_site_state_start: started

    iis_site_web_config:

    iis_site_web_config_force: true

.

Running your playbook:

1.You must run your play book from inside parent directory always “ansible
2.Now there is a playbook called nickwiniis.yml in the ansible directory which simply calls the ansible-role-win-iis role inside the roles directory.

Example: of ansible/nickwiniis.yml

hosts: all

  gather_facts: yes

  any_errors_fatal: true

  roles:

    – role: ansible-role-win-iis

.

Command:

ansible-playbook –i inventory/dev/hosts nickwiniis.yml -u nick –Kkb –limit=’devops.nicktailor.win

 -i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by environment like hosts.dev or hosts.staging
 -u : this is the ssh_user you will be connecting to the servers with
 -Kkb : this tells ansible that you will be using sudo su – for the ssh_user when running all role/tasks
 -ask-beocme : is saying become root
 -limit=’server’ : this allows you to segement which server you want to run the playbook against.

.

Successful example run of the book:

.

[ntailor@ansible.nicktailor.com]$ ansibleplaybooki hosts/dev nickwiniis.ymllimit=devops.nicktailor.win

.

PLAY [all] *****************************************************************************************************************************************************

.

TASK [Gathering Facts] *****************************************************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [ansiblerolewiniis : ensure iis is installed] **********************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [ansiblerolewiniis : configure app pool] ***************************************************************************************************************

ok: [devops.nicktailor.win]

.

TASK [ansiblerolewiniis : ensure path for site exists] ******************************************************************************************************

ok: [devops.nicktailor.win] => (item={‘name’: ‘First website’, host_header: , ip: ‘*’, iis_binding_port: ‘8082’, ‘protocol’: ‘http’, ‘state’: ‘absent’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘Default Web Site’, iis_site_path: ‘C:\\inetpub\\wwwroot1′, iis_acl_path: ‘C:\\inetpub\\wwwroot1′, iis_site_state: ‘absent’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘stopped’, iis_site_web_config: , iis_site_web_config_force: True})

ok: [devops.nicktailor.win] => (item={‘name’: ‘Second website’, host_header: , ip: ‘*’, iis_binding_port: ‘8081’, ‘protocol’: ‘http’, ‘state’: ‘present’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘site2’, iis_acl_path: ‘C:\\inetpub\\wwwroot2′, iis_site_path: ‘C:\\inetpub\\wwwroot2′, iis_site_state: ‘present’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘started’, iis_site_web_config: , iis_site_web_config_force: True})

.

TASK [ansiblerolewiniis : debug] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “path”: {

        “changed”: false,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot1″,

                    iis_binding_port: “8082”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “Default Web Site”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot1″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “absent”,

                    iis_site_state_start: “stopped”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “First website”,

                    “protocol”: “http”,

                    “state”: “absent”

                }

            },

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot2″,

                    iis_binding_port: “8081”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “site2”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot2″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “present”,

                    iis_site_state_start: “started”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “Second website”,

                    “protocol”: “http”,

                    “state”: “present”

                }

            }

        ]

    }

}

.

TASK [ansiblerolewiniis : allow iis group access to site path] **********************************************************************************************

ok: [devops.nicktailor.win] => (item={‘name’: ‘First website’, host_header: , ip: ‘*’, iis_binding_port: ‘8082’, ‘protocol’: ‘http’, ‘state’: ‘absent’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘Default Web Site’, iis_site_path: ‘C:\\inetpub\\wwwroot1′, iis_acl_path: ‘C:\\inetpub\\wwwroot1′, iis_site_state: ‘absent’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘stopped’, iis_site_web_config: , iis_site_web_config_force: True})

ok: [devops.nicktailor.win] => (item={‘name’: ‘Second website’, host_header: , ip: ‘*’, iis_binding_port: ‘8081’, ‘protocol’: ‘http’, ‘state’: ‘present’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘site2’, iis_acl_path: ‘C:\\inetpub\\wwwroot2′, iis_site_path: ‘C:\\inetpub\\wwwroot2′, iis_site_state: ‘present’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘started’, iis_site_web_config: , iis_site_web_config_force: True})

.

TASK [ansiblerolewiniis : debug] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “access”: {

        “changed”: false,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot1″,

                    iis_binding_port: “8082”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “Default Web Site”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot1″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “absent”,

                    iis_site_state_start: “stopped”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “First website”,

                    “protocol”: “http”,

                    “state”: “absent”

                }

            },

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot2″,

                    iis_binding_port: “8081”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “site2”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot2″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “present”,

                    iis_site_state_start: “started”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “Second website”,

                    “protocol”: “http”,

                    “state”: “present”

                }

            }

        ]

    }

}

.

TASK [ansiblerolewiniis : upload custom web.config from template] *******************************************************************************************

skipping: [devops.nicktailor.win] => (item={‘name’: ‘First website’, host_header: , ip: ‘*’, iis_binding_port: ‘8082’, ‘protocol’: ‘http’, ‘state’: ‘absent’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘Default Web Site’, iis_site_path: ‘C:\\inetpub\\wwwroot1′, iis_acl_path: ‘C:\\inetpub\\wwwroot1′, iis_site_state: ‘absent’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘stopped’, iis_site_web_config: , iis_site_web_config_force: True})

skipping: [devops.nicktailor.win] => (item={‘name’: ‘Second website’, host_header: , ip: ‘*’, iis_binding_port: ‘8081’, ‘protocol’: ‘http’, ‘state’: ‘present’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘site2’, iis_acl_path: ‘C:\\inetpub\\wwwroot2′, iis_site_path: ‘C:\\inetpub\\wwwroot2′, iis_site_state: ‘present’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘started’, iis_site_web_config: , iis_site_web_config_force: True})

.

TASK [ansiblerolewiniis : debug] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    startiis: {

        “changed”: false,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot1″,

                    iis_binding_port: “8082”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “Default Web Site”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot1″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “absent”,

                    iis_site_state_start: “stopped”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “First website”,

                    “protocol”: “http”,

                    “state”: “absent”

                },

                skip_reason: “Conditional result was False”,

                “skipped”: true

            },

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot2″,

                    iis_binding_port: “8081”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “site2”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot2″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “present”,

                    iis_site_state_start: “started”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “Second website”,

                    “protocol”: “http”,

                    “state”: “present”

                },

                skip_reason: “Conditional result was False”,

                “skipped”: true

            }

        ]

    }

}

.

TASK [ansiblerolewiniis : configure site] *******************************************************************************************************************

changed: [devops.nicktailor.win] => (item={‘name’: ‘First website’, host_header: , ip: ‘*’, iis_binding_port: ‘8082’, ‘protocol’: ‘http’, ‘state’: ‘absent’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘Default Web Site’, iis_site_path: ‘C:\\inetpub\\wwwroot1′, iis_acl_path: ‘C:\\inetpub\\wwwroot1′, iis_site_state: ‘absent’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘stopped’, iis_site_web_config: , iis_site_web_config_force: True})

changed: [devops.nicktailor.win] => (item={‘name’: ‘Second website’, host_header: , ip: ‘*’, iis_binding_port: ‘8081’, ‘protocol’: ‘http’, ‘state’: ‘present’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘site2’, iis_acl_path: ‘C:\\inetpub\\wwwroot2′, iis_site_path: ‘C:\\inetpub\\wwwroot2′, iis_site_state: ‘present’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘started’, iis_site_web_config: , iis_site_web_config_force: True})

.

TASK [ansiblerolewiniis : debug] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    iis_site: {

        “changed”: true,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: true,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot1″,

                    iis_binding_port: “8082”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “Default Web Site”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot1″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “absent”,

                    iis_site_state_start: “stopped”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “First website”,

                    “protocol”: “http”,

                    “state”: “absent”

                },

                “site”: {

                    ApplicationPool: DefaultAppPool,

                    “Bindings”: [

                        “*:80:*

                    ],

                    “ID”: 1,

                    “Name”: “Default Web Site”,

                    PhysicalPath: “C:\\inetpub\\wwwroot1″,

                    “State”: “Stopped”

                }

            },

            {

                ansible_loop_var: “item”,

                “changed”: true,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot2″,

                    iis_binding_port: “8081”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “site2”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot2″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “present”,

                    iis_site_state_start: “started”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “Second website”,

                    “protocol”: “http”,

                    “state”: “present”

                },

                “site”: {

                    ApplicationPool: DefaultAppPool,

                    “Bindings”: [

                        “*:80:*

                    ],

                    “ID”: 2,

                    “Name”: “site2”,

                    PhysicalPath: “C:\\inetpub\\wwwroot2″,

                    “State”: “Started”

                }

            }

        ]

    }

}

.

TASK [ansiblerolewiniis : configure site bindings] **********************************************************************************************************

ok: [devops.nicktailor.win] => (item={‘name’: ‘First website’, host_header: , ip: ‘*’, iis_binding_port: ‘8082’, ‘protocol’: ‘http’, ‘state’: ‘absent’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘Default Web Site’, iis_site_path: ‘C:\\inetpub\\wwwroot1′, iis_acl_path: ‘C:\\inetpub\\wwwroot1′, iis_site_state: ‘absent’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘stopped’, iis_site_web_config: , iis_site_web_config_force: True})

changed: [devops.nicktailor.win] => (item={‘name’: ‘Second website’, host_header: , ip: ‘*’, iis_binding_port: ‘8081’, ‘protocol’: ‘http’, ‘state’: ‘present’, certificate_hash: , certificate_store_name: ‘My’, iis_site_name: ‘site2’, iis_acl_path: ‘C:\\inetpub\\wwwroot2′, iis_site_path: ‘C:\\inetpub\\wwwroot2′, iis_site_state: ‘present’, iis_site_port: ’80’, iis_site_id: , iis_site_ip: ‘*’, iis_site_ssl: False, iis_site_hostname: ‘*’, iis_site_parameters: , iis_site_state_start: ‘started’, iis_site_web_config: , iis_site_web_config_force: True})

.

TASK [ansiblerolewiniis : debug] ****************************************************************************************************************************

ok: [devops.nicktailor.win] => {

    “startiis2”: {

        “changed”: true,

        msg: “All items completed”,

        “results”: [

            {

                ansible_loop_var: “item”,

                “changed”: false,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot1″,

                    iis_binding_port: “8082”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “Default Web Site”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot1″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “absent”,

                    iis_site_state_start: “stopped”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “First website”,

                    “protocol”: “http”,

                    “state”: “absent”

                }

            },

            {

                ansible_loop_var: “item”,

                binding_info: {

                    bindingInformation: “*:8081:”,

                    certificateHash: “”,

                    certificateStoreName: “”,

                    hostheader: “”,

                    ip: “*”,

                    “port”: 8081,

                    “protocol”: “http”,

                    sslFlags: 0

                },

                “changed”: true,

                “failed”: false,

                “item”: {

                    certificate_hash: “”,

                    certificate_store_name: “My”,

                    host_header: “”,

                    iis_acl_path: “C:\\inetpub\\wwwroot2″,

                    iis_binding_port: “8081”,

                    iis_site_hostname: “*”,

                    iis_site_id: “”,

                    iis_site_ip: “*”,

                    iis_site_name: “site2”,

                    iis_site_parameters: “”,

                    iis_site_path: “C:\\inetpub\\wwwroot2″,

                    iis_site_port: “80”,

                    iis_site_ssl: false,

                    iis_site_state: “present”,

                    iis_site_state_start: “started”,

                    iis_site_web_config: “”,

                    iis_site_web_config_force: true,

                    ip: “*”,

                    “name”: “Second website”,

                    “protocol”: “http”,

                    “state”: “present”

                },

                operation_type: “added”,

                website_state: “Started”

            }

        ]

    }

}

.

RUNNING HANDLER [ansiblerolewiniis : restart iis] ***********************************************************************************************************

changed: [devops.nicktailor.win]

.

PLAY RECAP *****************************************************************************************************************************************************

devops.nicktailor.win       : ok=13   changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

.

.

Now you could write in to copy an test index.html file, but just to show it works. I manually created the index.html

.

Test:

[ansible.nicktailor.com]$ curl -k http://devops.nicktailor.win

YAY THis works!

.

.

0