Author: admin

How to deploy OpenNebula Frontends via Ansible

Frontend: This role deploys the OpenNebula Cloud platform frontends via Ansible

Ansible Operational Documentation – OpenNebula Frontend Deployments

https://opennebula.io/ – OpenNebula is basically a opensource inhouse cloud platform that you can deploy and manage virtual machines using a kvm backend on the host which is scalable. OpenNebula support give you a document to run manual commands, and would not provide the opensource playbook they use to deploy frontends.

So I reverse engineered one for others to use and edit as needed. As nobody runs commands manually anymore. If you are not automating then you are basically a dinosaur

Note: You will still need to buy your own enterprise license to get access to the apt source. You can find that below and you can plug those into defaults/main.yml before you run the book.

This role handles the following when deploying OpenNebula Frontends in standalone or HA using groups to distinguish how to deploy in scale using apache.

 Apache.yml – separate task that independently deploys apache and the configutation. This is so if you simply if wanted to run rerun the apache configuration with a new domain, you don’t need to rerun the whole book.
 Mysql.yml – this task uses a custom python library that is not apart of native ansible, located in side the library folder and handles the following
It deploys mysql
It changes the root password
Removes_anonymous_user
Disables_root_login_remotely
Removes the testdb
It will create the database, user, and grantpermission for new the new database
 Main.yml – This is the primary task that deploys the ON frontend
Install depenancies for ON
Imports the keys for Ubuntu, phusionpassenger, ON
Install and configures mysql (using custom python library)
Install and configures apache for ON
Configures sunstone.conf
Configures oned.conf
Is able to distinguish between standalone and HA setup
Copies ssh keys for ON to secondary FE’s
Copies rafthook scripts to secondary FE’s
Adds primary server to ON zone
Updates zone endpoint
Backups up primary mysql db and copies to secondary nodes in HA
Setups up federation configuration if defined
Stop and starts services at specific times during the installation for everything to work correctly. (super important) do not change the order without reviewing

How to use this role:

1.You must first download the git repository
b.git clone git@github.com:Perfect10NickTailor/opennebula-frontends.git
2.Under your user you will see a directory called opennebula-frontends cd into this directory
c.cd opennebula-frontends
3.Move inside the inventory directory to the appropriate client directory
a.Create a file called hosts.opennebula
4.Now you want edit the {{ hosts.opennebula }} file name file or create it if it doesn’t exist

Example file: hosts.opennebula

d.Put your server under the appropriate group inside the file and save

Example: This is how you would list out 3 frontend hosts

[all:children]

frontend_server_primary # this is where you list ON server number 1

mysql_servers – you list any server that will require mysql install for ON

apache_servers – you list any server that will be running ON apache

frontend_HA – you list any additional front ends that will be used in HA here for OpenNebula

.

[frontend_server_primary]

Testmachine1 ansible_host=192.168.86.61

.

[mysql_servers]

Testmachine1 ansible_host=192.168.86.61

Testmachine2 ansible_host=192.168.86.62

#Testmachine3 ansibel_host=192.168.86.63

[apache_servers]

Testmachine1 ansible_host=192.168.86.61

Testmachine2 ansible_host=192.168.86.62

#Testmachine3 ansibel_host=192.168.86.63

.

[frontend_HA]

Testmachine2 ansible_host=192.168.86.62

#Testmachine3 ansible_host=192.168.86.63

.

Note: For a standalone setup you simply list the same host under the following 3 groups listed below and then in your command under –limt=”testmachine1” instead of ‘testmachine1,testmachine2′. The playbook is smart enough to know what to do from there.

[frontend_server_primary]

Testmachine1 ansible_host=192.168.86.63

[mysql_servers]

Testmachine1 ansible_host=192.168.86.63

[apache_servers]

Testmachine1 ansible_host=192.168.86.63

Special Notes: This playbook is designed so you can choose deploy ON in standalone, in classic centralised mysql(HA), or OpenNebula HA(with mysql deploy individually with rafthook configuration.

We will be deploying the OpenNebula officially supported way.
Although no senior architect would usually choose this approach over classic mysql HA(active/passive), we followed it anyway.

Important things to know:

Group variables for this role that are passed and need to be defined below. If you want to change certificates and configure mysql it has to be done in these group vars for this role to work. You will need to create opennebula ssl keys for the vnc console stuff to work, they are not provided by this playbook.

Dev/group_vars:

Frontend_server_primary

session_memcache: memcache

vnc_proxy_support_wss: true

vnc_proxy_cert_path: /etc/ssl/certs/opennebula.pem

vnc_proxy_key_path: /etc/ssl/private/opennebula.key

vnc_proxy_ipv6: false

vnc_request_password: false

driver: qcow2

.

Frontend_HA

#If these are defined HA setup is pushed.

#It Adds VIP hooks for floating IP and federation server ID:

#these variables can be overidden at at the host_var level.

#If host is listed under frontend_HA group in your host

#then these defaults will be used

.

leader_interface_name: enp0s8

leader_ip: 192.168.50.132/24

follower_ip: 192.168.50.132/24

follower_interface_name: enp0s8

.

Mysql_servers

OpenNebula Mysql Installation

mysqlrootuser: root

mysqlnewinstallpassword: Swordfish123

mysql_admin_user: admin    

mysql_admin_password: admin

database_to_create: opennebula

.

Running your playbook:

1.You must run your play book from inside parent directory of ansible”
2.There is a file called commands.txt with references to help you format your command quickly.
3.Now there is a playbook called ON-frontenddeploly.yml in the ansible directory which simply calls the opennebula-frontends role inside the roles directory.

Example: of opennebula-frontend/ON-frontenddeploy.yml

hosts: all

  become: True

  become_user: root

  gather_facts: no

  roles:

    – role: opennebula-frontend

.

Command: Running – playbook to deploy OpenNebula in HA

ansible-playbook -i inventory/dev/hosts ON-frontenddeploy.yml -u brucewayne -Kkb –ask-become –limit=’testmachine1,testmachine2′

Command: Running – playbook to deploy OpenNebula in Standalone

ansible-playbook -i inventory/dev/hosts ON-frontenddeploy.yml -u brucewayne -Kkb –ask-become –limit=’testmachine1′

.

-i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by customer like hosts.opennebla2  
-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 run:

.

brucewayne@KVMtestbox:~/ansible/opennebula-frontend$ ansibleplaybooki inventory/dev/hosts.opennebula2 ONfrontenddeploy.ymlu brucewayneKkbaskbecomelimit=‘testmachine1,testmachine2’

SSH password:

BECOME password[defaults to SSH password]:

.

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

.

TASK [frontend : install debian packages] ********************************************************************************************************************************************************************************

ok: [testmachine2] => (item=curl)

ok: [testmachine1] => (item=curl)

ok: [testmachine1] => (item=gnupg)

ok: [testmachine2] => (item=gnupg)

changed: [testmachine1] => (item=buildessential)

ok: [testmachine1] => (item=dirmngr)

ok: [testmachine1] => (item=cacertificates)

ok: [testmachine1] => (item=memcached)

changed: [testmachine2] => (item=buildessential)

ok: [testmachine2] => (item=dirmngr)

ok: [testmachine2] => (item=cacertificates)

ok: [testmachine2] => (item=memcached)

.

TASK [frontend : import the opennebula apt key] **************************************************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : Show Key list] ******************************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “keylist.stdout_lines”: [

        “/etc/apt/trusted.gpg”,

        “——————–“,

        “pub   rsa2048 2013-06-13 [SC]”,

        ”      92B7 7188 854C F23E 1634  DA89 592F 7F05 85E1 6EBF”,

        “uid           [ unknown] OpenNebula Repository <contact@opennebula.org>”,

        “sub   rsa2048 2013-06-13 [E]”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32″,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092″,

        “uid           [ unknown] Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2018-09-17 [SC]”,

        ”      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C”,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>”

    ]

}

ok: [testmachine2] => {

    “keylist.stdout_lines”: [

        “/etc/apt/trusted.gpg”,

        “——————–“,

        “pub   rsa2048 2013-06-13 [SC]”,

        ”      92B7 7188 854C F23E 1634  DA89 592F 7F05 85E1 6EBF”,

        “uid           [ unknown] OpenNebula Repository <contact@opennebula.org>”,

        “sub   rsa2048 2013-06-13 [E]”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32″,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092″,

        “uid           [ unknown] Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2018-09-17 [SC]”,

        ”      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C”,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>”

    ]

}

.

TASK [frontend : import the phusionpassenger apt key] ********************************************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : Show Key list] ******************************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “keylist2.stdout_lines”: [

        “/etc/apt/trusted.gpg”,

        “——————–“,

        “pub   rsa2048 2013-06-13 [SC]”,

        ”      92B7 7188 854C F23E 1634  DA89 592F 7F05 85E1 6EBF”,

        “uid           [ unknown] OpenNebula Repository <contact@opennebula.org>”,

        “sub   rsa2048 2013-06-13 [E]”,

        “”,

        “pub   rsa4096 2013-06-30 [SC]”,

        ”      1637 8A33 A6EF 1676 2922  526E 561F 9B9C AC40 B2F7″,

        “uid           [ unknown] Phusion Automated Software Signing (Used by automated tools to sign software packages) <auto-software-signing@phusion.nl>”,

        “sub   rsa4096 2013-06-30 [E]”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32″,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092″,

        “uid           [ unknown] Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2018-09-17 [SC]”,

        ”      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C”,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>”

    ]

}

ok: [testmachine2] => {

    “keylist2.stdout_lines”: [

        “/etc/apt/trusted.gpg”,

        “——————–“,

        “pub   rsa2048 2013-06-13 [SC]”,

        ”      92B7 7188 854C F23E 1634  DA89 592F 7F05 85E1 6EBF”,

        “uid           [ unknown] OpenNebula Repository <contact@opennebula.org>”,

        “sub   rsa2048 2013-06-13 [E]”,

        “”,

        “pub   rsa4096 2013-06-30 [SC]”,

        ”      1637 8A33 A6EF 1676 2922  526E 561F 9B9C AC40 B2F7″,

        “uid           [ unknown] Phusion Automated Software Signing (Used by automated tools to sign software packages) <auto-software-signing@phusion.nl>”,

        “sub   rsa4096 2013-06-30 [E]”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      790B C727 7767 219C 42C8  6F93 3B4F E6AC C0B2 1F32″,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2012) <ftpmaster@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2012-cdimage.gpg”,

        “——————————————————“,

        “pub   rsa4096 2012-05-11 [SC]”,

        ”      8439 38DF 228D 22F7 B374  2BC0 D94A A3F0 EFE2 1092″,

        “uid           [ unknown] Ubuntu CD Image Automatic Signing Key (2012) <cdimage@ubuntu.com>”,

        “”,

        “/etc/apt/trusted.gpg.d/ubuntu-keyring-2018-archive.gpg”,

        “——————————————————“,

        “pub   rsa4096 2018-09-17 [SC]”,

        ”      F6EC B376 2474 EDA9 D21B  7022 8719 20D1 991B C93C”,

        “uid           [ unknown] Ubuntu Archive Automatic Signing Key (2018) <ftpmaster@ubuntu.com>”

    ]

}

.

TASK [frontend : add opennebula apt repository] **************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : add bionic phusionpassenger apt repository] *************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : wget apttransporthttps cacertificates] ***************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “install2”: {

        “changed”: true,

        “cmd”: “apt-get -y install wget apt-transport-https ca-certificates”,

        “delta”: “0:00:02.087119”,

        “end”: “2022-04-06 03:13:42.512860”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:13:40.425741”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “Reading package lists…\nBuilding dependency tree…\nReading state information…\nca-certificates is already the newest version (20210119~20.04.2).\nwget is already the newest version (1.20.3-1ubuntu2).\nwget set to manually installed.\nThe following NEW packages will be installed\n  apt-transport-https\n0 to upgrade, 1 to newly install, 0 to remove and 1 not to upgrade.\nNeed to get 4,680 B of archives.\nAfter this operation, 162 kB of additional disk space will be used.\nGet:1 http://gb.archive.ubuntu.com/ubuntu focal-updates/universe amd64 apt-transport-https all 2.0.6 [4,680 B]\nFetched 4,680 B in 0s (15.1 kB/s)\nSelecting previously unselected package apt-transport-https.\r\n(Reading database … \r(Reading database … 5%\r(Reading database … 10%\r(Reading database … 15%\r(Reading database … 20%\r(Reading database … 25%\r(Reading database … 30%\r(Reading database … 35%\r(Reading database … 40%\r(Reading database … 45%\r(Reading database … 50%\r(Reading database … 55%\r(Reading database … 60%\r(Reading database … 65%\r(Reading database … 70%\r(Reading database … 75%\r(Reading database … 80%\r(Reading database … 85%\r(Reading database … 90%\r(Reading database … 95%\r(Reading database … 100%\r(Reading database … 199304 files and directories currently installed.)\r\nPreparing to unpack …/apt-transport-https_2.0.6_all.deb …\r\nUnpacking apt-transport-https (2.0.6) …\r\nSetting up apt-transport-https (2.0.6) …”,

        “stdout_lines”: [

            “Reading package lists…”,

            “Building dependency tree…”,

            “Reading state information…”,

            “ca-certificates is already the newest version (20210119~20.04.2).”,

            “wget is already the newest version (1.20.3-1ubuntu2).”,

            “wget set to manually installed.”,

            “The following NEW packages will be installed”,

            ”  apt-transport-https”,

            “0 to upgrade, 1 to newly install, 0 to remove and 1 not to upgrade.”,

            “Need to get 4,680 B of archives.”,

            “After this operation, 162 kB of additional disk space will be used.”,

            “Get:1 http://gb.archive.ubuntu.com/ubuntu focal-updates/universe amd64 apt-transport-https all 2.0.6 [4,680 B]”,

            “Fetched 4,680 B in 0s (15.1 kB/s)”,

            “Selecting previously unselected package apt-transport-https.”,

            “(Reading database … “,

            “(Reading database … 5%”,

            “(Reading database … 10%”,

            “(Reading database … 15%”,

            “(Reading database … 20%”,

            “(Reading database … 25%”,

            “(Reading database … 30%”,

            “(Reading database … 35%”,

            “(Reading database … 40%”,

            “(Reading database … 45%”,

            “(Reading database … 50%”,

            “(Reading database … 55%”,

            “(Reading database … 60%”,

            “(Reading database … 65%”,

            “(Reading database … 70%”,

            “(Reading database … 75%”,

            “(Reading database … 80%”,

            “(Reading database … 85%”,

            “(Reading database … 90%”,

            “(Reading database … 95%”,

            “(Reading database … 100%”,

            “(Reading database … 199304 files and directories currently installed.)”,

            “Preparing to unpack …/apt-transport-https_2.0.6_all.deb …”,

            “Unpacking apt-transport-https (2.0.6) …”,

            “Setting up apt-transport-https (2.0.6) …”

        ]

    }

}

ok: [testmachine2] => {

    “install2”: {

        “changed”: true,

        “cmd”: “apt-get -y install wget apt-transport-https ca-certificates”,

        “delta”: “0:00:02.710741”,

        “end”: “2022-04-06 03:13:43.155299”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:13:40.444558”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “Reading package lists…\nBuilding dependency tree…\nReading state information…\nca-certificates is already the newest version (20210119~20.04.2).\nwget is already the newest version (1.20.3-1ubuntu2).\nwget set to manually installed.\nThe following packages were automatically installed and are no longer required:\n  linux-headers-5.11.0-27-generic linux-hwe-5.11-headers-5.11.0-27\n  linux-image-5.11.0-27-generic linux-modules-5.11.0-27-generic\n  linux-modules-extra-5.11.0-27-generic\nUse ‘sudo apt autoremove’ to remove them.\nThe following NEW packages will be installed\n  apt-transport-https\n0 to upgrade, 1 to newly install, 0 to remove and 37 not to upgrade.\nNeed to get 4,680 B of archives.\nAfter this operation, 162 kB of additional disk space will be used.\nGet:1 http://gb.archive.ubuntu.com/ubuntu focal-updates/universe amd64 apt-transport-https all 2.0.6 [4,680 B]\nFetched 4,680 B in 0s (13.2 kB/s)\nSelecting previously unselected package apt-transport-https.\r\n(Reading database … \r(Reading database … 5%\r(Reading database … 10%\r(Reading database … 15%\r(Reading database … 20%\r(Reading database … 25%\r(Reading database … 30%\r(Reading database … 35%\r(Reading database … 40%\r(Reading database … 45%\r(Reading database … 50%\r(Reading database … 55%\r(Reading database … 60%\r(Reading database … 65%\r(Reading database … 70%\r(Reading database … 75%\r(Reading database … 80%\r(Reading database … 85%\r(Reading database … 90%\r(Reading database … 95%\r(Reading database … 100%\r(Reading database … 202372 files and directories currently installed.)\r\nPreparing to unpack …/apt-transport-https_2.0.6_all.deb …\r\nUnpacking apt-transport-https (2.0.6) …\r\nSetting up apt-transport-https (2.0.6) …”,

        “stdout_lines”: [

            “Reading package lists…”,

            “Building dependency tree…”,

            “Reading state information…”,

            “ca-certificates is already the newest version (20210119~20.04.2).”,

            “wget is already the newest version (1.20.3-1ubuntu2).”,

            “wget set to manually installed.”,

            “The following packages were automatically installed and are no longer required:”,

            ”  linux-headers-5.11.0-27-generic linux-hwe-5.11-headers-5.11.0-27″,

            ”  linux-image-5.11.0-27-generic linux-modules-5.11.0-27-generic”,

            ”  linux-modules-extra-5.11.0-27-generic”,

            “Use ‘sudo apt autoremove’ to remove them.”,

            “The following NEW packages will be installed”,

            ”  apt-transport-https”,

            “0 to upgrade, 1 to newly install, 0 to remove and 37 not to upgrade.”,

            “Need to get 4,680 B of archives.”,

            “After this operation, 162 kB of additional disk space will be used.”,

            “Get:1 http://gb.archive.ubuntu.com/ubuntu focal-updates/universe amd64 apt-transport-https all 2.0.6 [4,680 B]”,

            “Fetched 4,680 B in 0s (13.2 kB/s)”,

            “Selecting previously unselected package apt-transport-https.”,

            “(Reading database … “,

            “(Reading database … 5%”,

            “(Reading database … 10%”,

            “(Reading database … 15%”,

            “(Reading database … 20%”,

            “(Reading database … 25%”,

            “(Reading database … 30%”,

            “(Reading database … 35%”,

            “(Reading database … 40%”,

            “(Reading database … 45%”,

            “(Reading database … 50%”,

            “(Reading database … 55%”,

            “(Reading database … 60%”,

            “(Reading database … 65%”,

            “(Reading database … 70%”,

            “(Reading database … 75%”,

            “(Reading database … 80%”,

            “(Reading database … 85%”,

            “(Reading database … 90%”,

            “(Reading database … 95%”,

            “(Reading database … 100%”,

            “(Reading database … 202372 files and directories currently installed.)”,

            “Preparing to unpack …/apt-transport-https_2.0.6_all.deb …”,

            “Unpacking apt-transport-https (2.0.6) …”,

            “Setting up apt-transport-https (2.0.6) …”

        ]

    }

}

.

TASK [frontend : aptget update] *****************************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : Include mysql task when groupvar mysqlservers is defined] ***********************************************************************************************************************************************

included: /home/brucewayne/ansible/opennebula-frontend/roles/frontend/tasks/mysql.yml for testmachine1, testmachine2

.

TASK [frontend : install debian packages] ********************************************************************************************************************************************************************************

changed: [testmachine1] => (item=mariadbserver)

changed: [testmachine1] => (item=python3pymysql)

changed: [testmachine2] => (item=mariadbserver)

changed: [testmachine2] => (item=python3pymysql)

.

TASK [frontend : Secure mysql installation] ******************************************************************************************************************************************************************************

[WARNING]: Module did not set no_log for change_root_password

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “mysql_secure”: {

        “changed”: true,

        “failed”: false,

        “meta”: {

            “change_root_pwd”: “True  — But not for all of the hosts”,

            “connected_with_socket?”: true,

            “disallow_root_remotely”: “False — meets the desired state”,

            “hosts_failed”: [

                “127.0.0.1”,

                “::1”

            ],

            “hosts_success”: [

                “localhost”

            ],

            “mysql_version_above_10_3?”: false,

            “new_password_correct?”: false,

            “remove_anonymous_user”: “False — meets the desired state”,

            “remove_test_db”: “False — meets the desired state”,

            “stdout”: “Password for user: root @ Hosts: [‘localhost’] changed to the desired state”

        },

        “warnings”: [

            “Module did not set no_log for change_root_password”

        ]

    }

}

ok: [testmachine2] => {

    “mysql_secure”: {

        “changed”: true,

        “failed”: false,

        “meta”: {

            “change_root_pwd”: “True  — But not for all of the hosts”,

            “connected_with_socket?”: true,

            “disallow_root_remotely”: “False — meets the desired state”,

            “hosts_failed”: [

                “::1”,

                “127.0.0.1”

            ],

            “hosts_success”: [

                “localhost”

            ],

            “mysql_version_above_10_3?”: false,

            “new_password_correct?”: false,

            “remove_anonymous_user”: “False — meets the desired state”,

            “remove_test_db”: “False — meets the desired state”,

            “stdout”: “Password for user: root @ Hosts: [‘localhost’] changed to the desired state”

        },

        “warnings”: [

            “Module did not set no_log for change_root_password”

        ]

    }

}

.

TASK [frontend : Create opennebula database] *****************************************************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “database”: {

        “changed”: true,

        “db”: “opennebula”,

        “db_list”: [

            “opennebula”

        ],

        “executed_commands”: [

            “CREATE DATABASE `opennebula`”

        ],

        “failed”: false

    }

}

ok: [testmachine2] => {

    “database”: {

        “changed”: true,

        “db”: “opennebula”,

        “db_list”: [

            “opennebula”

        ],

        “executed_commands”: [

            “CREATE DATABASE `opennebula`”

        ],

        “failed”: false

    }

}

.

TASK [frontend : create user ‘admin’ with password ‘admin’ for ‘{{opennebula_db}}’ and grant all priveleges] *******************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : install opennebula packages] ****************************************************************************************************************************************************************************

changed: [testmachine1] => (item=opennebula)

changed: [testmachine1] => (item=opennebulasunstone)

changed: [testmachine1] => (item=opennebulagate)

changed: [testmachine1] => (item=opennebulaflow)

ok: [testmachine1] => (item=opennebularubygems)

changed: [testmachine1] => (item=opennebulafireedge)

ok: [testmachine1] => (item=gnupg)

changed: [testmachine2] => (item=opennebula)

changed: [testmachine2] => (item=opennebulasunstone)

changed: [testmachine2] => (item=opennebulagate)

changed: [testmachine2] => (item=opennebulaflow)

ok: [testmachine2] => (item=opennebularubygems)

changed: [testmachine2] => (item=opennebulafireedge)

ok: [testmachine2] => (item=gnupg)

.

TASK [frontend : Copy oned.conf to server with updated DB(host,user,pass)] ***********************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : Copy sunstoneserver.conf to server configs] ************************************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : Add credentials to Admin] ****************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “authfile.stdout_lines”: [

        “admin:IgDeMozOups8”

    ]

}

ok: [testmachine2] => {

    “authfile.stdout_lines”: [

        “admin:Tafwaytofen2”

    ]

}

.

TASK [frontend : Set fact for authfile] **********************************************************************************************************************************************************************************

ok: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : update permissions opennebula permissions] **************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : Include apache configuration] ***************************************************************************************************************************************************************************

included: /home/brucewayne/ansible/opennebula-frontend/roles/frontend/tasks/apache.yml for testmachine1, testmachine2

.

TASK [frontend : restart systemdtimesyncd] ******************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : install debian packages] ********************************************************************************************************************************************************************************

changed: [testmachine1] => (item=apache2utils)

changed: [testmachine2] => (item=apache2utils)

changed: [testmachine1] => (item=apache2)

changed: [testmachine1] => (item=libapache2modproxymsrpc)

changed: [testmachine2] => (item=apache2)

changed: [testmachine2] => (item=libapache2modproxymsrpc)

changed: [testmachine1] => (item=libapache2modpassenger)

changed: [testmachine2] => (item=libapache2modpassenger)

.

TASK [frontend : copy opennebula apache ssl virtualhost config to server] ************************************************************************************************************************************************

changed: [testmachine1] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/apache_confs/opennebula.conf)

changed: [testmachine2] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/apache_confs/opennebula.conf)

.

TASK [frontend : copy opennebul ssl certificate to servers] **************************************************************************************************************************************************************

changed: [testmachine1] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/certs/opennebula.pem)

changed: [testmachine2] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/certs/opennebula.pem)

.

TASK [frontend : copy opennebula ssl private key to server] **************************************************************************************************************************************************************

changed: [testmachine1] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/private/opennebula.key)

changed: [testmachine2] => (item=/home/brucewayne/ansible/opennebula-frontend/roles/frontend/templates/private/opennebula.key)

.

TASK [frontend : Enable SSL virtual host for openebula] ******************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : enable opennebula virtualhost] **************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : Restart service httpd, in all cases] ********************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : Enable service httpd and ensure it is not masked] *******************************************************************************************************************************************************

ok: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : get service facts] **************************************************************************************************************************************************************************************

ok: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : Check to see if httpd is running] ***********************************************************************************************************************************************************************

ok: [testmachine1] => {

    “ansible_facts.services[\”apache2.service\”]”: {

        “name”: “apache2.service”,

        “source”: “systemd”,

        “state”: “running”,

        “status”: “enabled”

    }

}

ok: [testmachine2] => {

    “ansible_facts.services[\”apache2.service\”]”: {

        “name”: “apache2.service”,

        “source”: “systemd”,

        “state”: “running”,

        “status”: “enabled”

    }

}

.

TASK [frontend : start opennebula] ***************************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “openebula.state”: “started”

}

ok: [testmachine2] => {

    “openebula.state”: “started”

}

.

TASK [frontend : start opennebulagate] **********************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “gate.state”: “started”

}

ok: [testmachine2] => {

    “gate.state”: “started”

}

.

TASK [frontend : start opennebulaflow] **********************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “flow.state”: “started”

}

ok: [testmachine2] => {

    “flow.state”: “started”

}

.

TASK [frontend : start opennebulanovc] **********************************************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “novnc.state”: “started”

}

ok: [testmachine2] => {

    “novnc.state”: “started”

}

.

TASK [frontend : start systemdtimesyncd] ********************************************************************************************************************************************************************************

ok: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “timesyncd.state”: “started”

}

ok: [testmachine2] => {

    “timesyncd.state”: “started”

}

.

TASK [frontend : Check if server is listed under frontend_HA] ************************************************************************************************************************************************************

skipping: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : Stopping OpenNebula on frontend_server_primary] *********************************************************************************************************************************************************

changed: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “stop, group_names”: “({‘changed’: True, ‘stdout’: ”, ‘stderr’: ”, ‘rc’: 0, ‘cmd’: ‘systemctl stop opennebula’, ‘start’: ‘2022-04-06 03:19:42.714817’, ‘end’: ‘2022-04-06 03:19:48.841833’, ‘delta’: ‘0:00:06.127016’, ‘msg’: ”, ‘stdout_lines’: [], ‘stderr_lines’: [], ‘failed’: False}, [‘apache_servers’, ‘frontend_server_primary’, ‘mysql_servers’])”

}

ok: [testmachine2] => {

    “stop, group_names”: “({‘changed’: True, ‘stdout’: ”, ‘stderr’: ”, ‘rc’: 0, ‘cmd’: ‘systemctl stop opennebula’, ‘start’: ‘2022-04-06 03:19:42.761875’, ‘end’: ‘2022-04-06 03:21:14.632276’, ‘delta’: ‘0:01:31.870401’, ‘msg’: ”, ‘stdout_lines’: [], ‘stderr_lines’: [], ‘failed’: False}, [‘apache_servers’, ‘frontend_HA’, ‘mysql_servers’])”

}

.

TASK [frontend : delete sqlfile if it exists to create a current one.] ***************************************************************************************************************************************************

changed: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : make backup of OpenNebula database] *********************************************************************************************************************************************************************

skipping: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “backup”: {

        “changed”: true,

        “cmd”: “onedb backup -u admin -p admin -d opennebula /var/lib/one/opennebula.sql”,

        “delta”: “0:00:00.406599”,

        “end”: “2022-04-06 03:21:16.346013”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:21:15.939414”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “MySQL dump stored in /var/lib/one/opennebula.sql\nUse ‘onedb restore’ or restore the DB using the mysql command:\nmysql -u user -h server -P port db_name < backup_file”,

        “stdout_lines”: [

            “MySQL dump stored in /var/lib/one/opennebula.sql”,

            “Use ‘onedb restore’ or restore the DB using the mysql command:”,

            “mysql -u user -h server -P port db_name < backup_file”

        ]

    }

}

ok: [testmachine2] => {

    “backup”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

.

TASK [frontend : Fetch the OpenNebula sql dumpfile from frontend_server_primary] *****************************************************************************************************************************************

skipping: [testmachine2]

changed: [testmachine1 -> testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “fetch, group_names”: “({‘changed’: True, ‘md5sum’: ‘a54c58c27e96d29cb99a26a595263164’, ‘dest’: ‘/home/brucewayne/ansible/opennebula-frontend/buffer/tmp/opennebula.sql’, ‘remote_md5sum’: None, ‘checksum’: ‘040e9ae687df46fc26a64f038992bd28e1d7e369’, ‘remote_checksum’: ‘040e9ae687df46fc26a64f038992bd28e1d7e369’, ‘failed’: False}, [‘apache_servers’, ‘frontend_server_primary’, ‘mysql_servers’])”

}

ok: [testmachine2] => {

    “fetch, group_names”: “({‘changed’: False, ‘skipped’: True, ‘skip_reason’: ‘Conditional result was False’}, [‘apache_servers’, ‘frontend_HA’, ‘mysql_servers’])”

}

.

TASK [frontend : Copy the ONsqldump file from master to the secondary HA nodes] *****************************************************************************************************************************************

skipping: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “sqlcopy”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

ok: [testmachine2] => {

    “sqlcopy”: {

        “changed”: true,

        “checksum”: “040e9ae687df46fc26a64f038992bd28e1d7e369”,

        “dest”: “/tmp/opennebula.sql”,

        “diff”: [],

        “failed”: false,

        “gid”: 0,

        “group”: “root”,

        “md5sum”: “a54c58c27e96d29cb99a26a595263164”,

        “mode”: “0644”,

        “owner”: “root”,

        “size”: 41546,

        “src”: “/home/brucewayne/.ansible/tmp/ansible-tmp-1649211677.4405959-9803-36565910128620/source”,

        “state”: “file”,

        “uid”: 0

    }

}

.

TASK [frontend : Fetch the fence_host.sh] ********************************************************************************************************************************************************************************

skipping: [testmachine2]

ok: [testmachine1 -> testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “fence_host, group_names”: “({‘changed’: False, ‘md5sum’: ‘7bb73d0d0ffce907562d75f6cd779fdc’, ‘file’: ‘/var/lib/one/remotes/hooks/ft/fence_host.sh’, ‘dest’: ‘/home/brucewayne/ansible/opennebula-frontend/buffer/tmp/fence_host.sh’, ‘checksum’: ‘ef5e59d9a3d6d7a55d554928057bf85f5dea5f1f’, ‘failed’: False}, [‘apache_servers’, ‘frontend_server_primary’, ‘mysql_servers’])”

}

ok: [testmachine2] => {

    “fence_host, group_names”: “({‘changed’: False, ‘skipped’: True, ‘skip_reason’: ‘Conditional result was False’}, [‘apache_servers’, ‘frontend_HA’, ‘mysql_servers’])”

}

.

TASK [frontend : Copy the fence.sh to frontend_HA hosts] *****************************************************************************************************************************************************************

skipping: [testmachine1]

ok: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “fence_host”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

ok: [testmachine2] => {

    “fence_host”: {

        “changed”: false,

        “checksum”: “ef5e59d9a3d6d7a55d554928057bf85f5dea5f1f”,

        “dest”: “/var/lib/one/remotes/hooks/ft/fence_host.sh”,

        “diff”: {

            “after”: {

                “path”: “/var/lib/one/remotes/hooks/ft/fence_host.sh”

            },

            “before”: {

                “path”: “/var/lib/one/remotes/hooks/ft/fence_host.sh”

            }

        },

        “failed”: false,

        “gid”: 9869,

        “group”: “admin”,

        “mode”: “0750”,

        “owner”: “admin”,

        “path”: “/var/lib/one/remotes/hooks/ft/fence_host.sh”,

        “size”: 4370,

        “state”: “file”,

        “uid”: 9869

    }

}

.

TASK [frontend : Create tar of /etc/one/] ********************************************************************************************************************************************************************************

skipping: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “tar”: {

        “changed”: true,

        “cmd”: “cd /etc/one;tar -cvf /etc/one/one.tar *”,

        “delta”: “0:00:00.016645”,

        “end”: “2022-04-06 03:21:20.659494”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:21:20.642849”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “auth/\nauth/certificates/\nauth/x509_auth.conf\nauth/server_x509_auth.conf\nauth/ldap_auth.conf\naz_driver.conf\naz_driver.default\ncli/\ncli/onevmgroup.yaml\ncli/onevnet.yaml\ncli/oneshowback.yaml\ncli/onehook.yaml\ncli/onetemplate.yaml\ncli/onemarketapp.yaml\ncli/onesecgroup.yaml\ncli/oneacct.yaml\ncli/oneacl.yaml\ncli/onemarket.yaml\ncli/onegroup.yaml\ncli/onevm.yaml\ncli/oneflowtemplate.yaml\ncli/onevrouter.yaml\ncli/onezone.yaml\ncli/oneimage.yaml\ncli/onecluster.yaml\ncli/oneuser.yaml\ncli/onevntemplate.yaml\ncli/onevdc.yaml\ncli/onehost.yaml\ncli/onedatastore.yaml\ncli/oneflow.yaml\ndefaultrc\nec2_driver.conf\nec2_driver.default\nfireedge/\nfireedge/provision/\nfireedge/provision/providers.d/\nfireedge/provision/providers.d/vultr_virtual.yaml\nfireedge/provision/providers.d/digitalocean.yaml\nfireedge/provision/providers.d/vultr_metal.yaml\nfireedge/provision/providers.d/equinix.yaml\nfireedge/provision/providers.d/google.yaml\nfireedge/provision/providers.d/aws.yaml\nfireedge/provision/providers.d/dummy.yaml\nfireedge/provision/provision-server.conf\nfireedge/sunstone/\nfireedge/sunstone/user/\nfireedge/sunstone/user/vm-tab.yaml\nfireedge/sunstone/user/vm-template-tab.yaml\nfireedge/sunstone/sunstone-server.conf\nfireedge/sunstone/admin/\nfireedge/sunstone/admin/vm-tab.yaml\nfireedge/sunstone/admin/cluster-tab.yaml\nfireedge/sunstone/admin/vm-template-tab.yaml\nfireedge/sunstone/admin/host-tab.yaml\nfireedge/sunstone/sunstone-views.yaml\nfireedge-server.conf\nhm/\nhm/hmrc\nmonitord.conf\noned.conf\noneflow-server.conf\nonegate-server.conf\nonehem-server.conf\nsched.conf\nsunstone-logos.yaml\nsunstone-server.conf\nsunstone-views/\nsunstone-views/vcenter/\nsunstone-views/vcenter/admin.yaml\nsunstone-views/vcenter/user.yaml\nsunstone-views/vcenter/groupadmin.yaml\nsunstone-views/vcenter/cloud.yaml\nsunstone-views/mixed/\nsunstone-views/mixed/admin.yaml\nsunstone-views/mixed/user.yaml\nsunstone-views/mixed/groupadmin.yaml\nsunstone-views/mixed/cloud.yaml\nsunstone-views/kvm/\nsunstone-views/kvm/admin.yaml\nsunstone-views/kvm/user.yaml\nsunstone-views/kvm/groupadmin.yaml\nsunstone-views/kvm/cloud.yaml\nsunstone-views.yaml\ntmrc\nvcenter_driver.default\nvmm_exec/\nvmm_exec/vmm_execrc\nvmm_exec/vmm_exec_kvm.conf”,

        “stdout_lines”: [

            “auth/”,

            “auth/certificates/”,

            “auth/x509_auth.conf”,

            “auth/server_x509_auth.conf”,

            “auth/ldap_auth.conf”,

            “az_driver.conf”,

            “az_driver.default”,

            “cli/”,

            “cli/onevmgroup.yaml”,

            “cli/onevnet.yaml”,

            “cli/oneshowback.yaml”,

            “cli/onehook.yaml”,

            “cli/onetemplate.yaml”,

            “cli/onemarketapp.yaml”,

            “cli/onesecgroup.yaml”,

            “cli/oneacct.yaml”,

            “cli/oneacl.yaml”,

            “cli/onemarket.yaml”,

            “cli/onegroup.yaml”,

            “cli/onevm.yaml”,

            “cli/oneflowtemplate.yaml”,

            “cli/onevrouter.yaml”,

            “cli/onezone.yaml”,

            “cli/oneimage.yaml”,

            “cli/onecluster.yaml”,

            “cli/oneuser.yaml”,

            “cli/onevntemplate.yaml”,

            “cli/onevdc.yaml”,

            “cli/onehost.yaml”,

            “cli/onedatastore.yaml”,

            “cli/oneflow.yaml”,

            “defaultrc”,

            “ec2_driver.conf”,

            “ec2_driver.default”,

            “fireedge/”,

            “fireedge/provision/”,

            “fireedge/provision/providers.d/”,

            “fireedge/provision/providers.d/vultr_virtual.yaml”,

            “fireedge/provision/providers.d/digitalocean.yaml”,

            “fireedge/provision/providers.d/vultr_metal.yaml”,

            “fireedge/provision/providers.d/equinix.yaml”,

            “fireedge/provision/providers.d/google.yaml”,

            “fireedge/provision/providers.d/aws.yaml”,

            “fireedge/provision/providers.d/dummy.yaml”,

            “fireedge/provision/provision-server.conf”,

            “fireedge/sunstone/”,

            “fireedge/sunstone/user/”,

            “fireedge/sunstone/user/vm-tab.yaml”,

            “fireedge/sunstone/user/vm-template-tab.yaml”,

            “fireedge/sunstone/sunstone-server.conf”,

            “fireedge/sunstone/admin/”,

            “fireedge/sunstone/admin/vm-tab.yaml”,

            “fireedge/sunstone/admin/cluster-tab.yaml”,

            “fireedge/sunstone/admin/vm-template-tab.yaml”,

            “fireedge/sunstone/admin/host-tab.yaml”,

            “fireedge/sunstone/sunstone-views.yaml”,

            “fireedge-server.conf”,

            “hm/”,

            “hm/hmrc”,

            “monitord.conf”,

            “oned.conf”,

            “oneflow-server.conf”,

            “onegate-server.conf”,

            “onehem-server.conf”,

            “sched.conf”,

            “sunstone-logos.yaml”,

            “sunstone-server.conf”,

            “sunstone-views/”,

            “sunstone-views/vcenter/”,

            “sunstone-views/vcenter/admin.yaml”,

            “sunstone-views/vcenter/user.yaml”,

            “sunstone-views/vcenter/groupadmin.yaml”,

            “sunstone-views/vcenter/cloud.yaml”,

            “sunstone-views/mixed/”,

            “sunstone-views/mixed/admin.yaml”,

            “sunstone-views/mixed/user.yaml”,

            “sunstone-views/mixed/groupadmin.yaml”,

            “sunstone-views/mixed/cloud.yaml”,

            “sunstone-views/kvm/”,

            “sunstone-views/kvm/admin.yaml”,

            “sunstone-views/kvm/user.yaml”,

            “sunstone-views/kvm/groupadmin.yaml”,

            “sunstone-views/kvm/cloud.yaml”,

            “sunstone-views.yaml”,

            “tmrc”,

            “vcenter_driver.default”,

            “vmm_exec/”,

            “vmm_exec/vmm_execrc”,

            “vmm_exec/vmm_exec_kvm.conf”

        ]

    }

}

ok: [testmachine2] => {

    “tar”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

.

TASK [frontend : Fetch the one.tar] **************************************************************************************************************************************************************************************

skipping: [testmachine2]

changed: [testmachine1 -> testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “fence_host, group_names”: “({‘changed’: True, ‘md5sum’: ‘acec4258dbbf2bde83d12f3eb29824a7’, ‘dest’: ‘/home/brucewayne/ansible/opennebula-frontend/buffer/tmp/one.tar’, ‘remote_md5sum’: None, ‘checksum’: ‘2da21a3124f4eb5a78c0126e9791c8d8c9c5c770’, ‘remote_checksum’: ‘2da21a3124f4eb5a78c0126e9791c8d8c9c5c770’, ‘failed’: False}, [‘apache_servers’, ‘frontend_server_primary’, ‘mysql_servers’])”

}

ok: [testmachine2] => {

    “fence_host, group_names”: “({‘changed’: False, ‘skipped’: True, ‘skip_reason’: ‘Conditional result was False’}, [‘apache_servers’, ‘frontend_HA’, ‘mysql_servers’])”

}

.

TASK [frontend : Copy the one.tar to frontend_HA hosts] ******************************************************************************************************************************************************************

skipping: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “fence_host”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

ok: [testmachine2] => {

    “fence_host”: {

        “changed”: true,

        “checksum”: “2da21a3124f4eb5a78c0126e9791c8d8c9c5c770”,

        “dest”: “/etc/one/one.tar”,

        “diff”: [],

        “failed”: false,

        “gid”: 0,

        “group”: “root”,

        “md5sum”: “acec4258dbbf2bde83d12f3eb29824a7”,

        “mode”: “0644”,

        “owner”: “root”,

        “size”: 542720,

        “src”: “/home/brucewayne/.ansible/tmp/ansible-tmp-1649211681.6244745-9943-99432484341658/source”,

        “state”: “file”,

        “uid”: 0

    }

}

.

TASK [frontend : untar one.tar in /etc/one on the frontend_HA hosts] *****************************************************************************************************************************************************

skipping: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “untar”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

ok: [testmachine2] => {

    “untar”: {

        “changed”: true,

        “cmd”: “cd /etc/one;tar -xvf /etc/one/one.tar”,

        “delta”: “0:00:00.018409”,

        “end”: “2022-04-06 03:21:23.162427”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:21:23.144018”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “auth/\nauth/certificates/\nauth/x509_auth.conf\nauth/server_x509_auth.conf\nauth/ldap_auth.conf\naz_driver.conf\naz_driver.default\ncli/\ncli/onevmgroup.yaml\ncli/onevnet.yaml\ncli/oneshowback.yaml\ncli/onehook.yaml\ncli/onetemplate.yaml\ncli/onemarketapp.yaml\ncli/onesecgroup.yaml\ncli/oneacct.yaml\ncli/oneacl.yaml\ncli/onemarket.yaml\ncli/onegroup.yaml\ncli/onevm.yaml\ncli/oneflowtemplate.yaml\ncli/onevrouter.yaml\ncli/onezone.yaml\ncli/oneimage.yaml\ncli/onecluster.yaml\ncli/oneuser.yaml\ncli/onevntemplate.yaml\ncli/onevdc.yaml\ncli/onehost.yaml\ncli/onedatastore.yaml\ncli/oneflow.yaml\ndefaultrc\nec2_driver.conf\nec2_driver.default\nfireedge/\nfireedge/provision/\nfireedge/provision/providers.d/\nfireedge/provision/providers.d/vultr_virtual.yaml\nfireedge/provision/providers.d/digitalocean.yaml\nfireedge/provision/providers.d/vultr_metal.yaml\nfireedge/provision/providers.d/equinix.yaml\nfireedge/provision/providers.d/google.yaml\nfireedge/provision/providers.d/aws.yaml\nfireedge/provision/providers.d/dummy.yaml\nfireedge/provision/provision-server.conf\nfireedge/sunstone/\nfireedge/sunstone/user/\nfireedge/sunstone/user/vm-tab.yaml\nfireedge/sunstone/user/vm-template-tab.yaml\nfireedge/sunstone/sunstone-server.conf\nfireedge/sunstone/admin/\nfireedge/sunstone/admin/vm-tab.yaml\nfireedge/sunstone/admin/cluster-tab.yaml\nfireedge/sunstone/admin/vm-template-tab.yaml\nfireedge/sunstone/admin/host-tab.yaml\nfireedge/sunstone/sunstone-views.yaml\nfireedge-server.conf\nhm/\nhm/hmrc\nmonitord.conf\noned.conf\noneflow-server.conf\nonegate-server.conf\nonehem-server.conf\nsched.conf\nsunstone-logos.yaml\nsunstone-server.conf\nsunstone-views/\nsunstone-views/vcenter/\nsunstone-views/vcenter/admin.yaml\nsunstone-views/vcenter/user.yaml\nsunstone-views/vcenter/groupadmin.yaml\nsunstone-views/vcenter/cloud.yaml\nsunstone-views/mixed/\nsunstone-views/mixed/admin.yaml\nsunstone-views/mixed/user.yaml\nsunstone-views/mixed/groupadmin.yaml\nsunstone-views/mixed/cloud.yaml\nsunstone-views/kvm/\nsunstone-views/kvm/admin.yaml\nsunstone-views/kvm/user.yaml\nsunstone-views/kvm/groupadmin.yaml\nsunstone-views/kvm/cloud.yaml\nsunstone-views.yaml\ntmrc\nvcenter_driver.default\nvmm_exec/\nvmm_exec/vmm_execrc\nvmm_exec/vmm_exec_kvm.conf”,

        “stdout_lines”: [

            “auth/”,

            “auth/certificates/”,

            “auth/x509_auth.conf”,

            “auth/server_x509_auth.conf”,

            “auth/ldap_auth.conf”,

            “az_driver.conf”,

            “az_driver.default”,

            “cli/”,

            “cli/onevmgroup.yaml”,

            “cli/onevnet.yaml”,

            “cli/oneshowback.yaml”,

            “cli/onehook.yaml”,

            “cli/onetemplate.yaml”,

            “cli/onemarketapp.yaml”,

            “cli/onesecgroup.yaml”,

            “cli/oneacct.yaml”,

            “cli/oneacl.yaml”,

            “cli/onemarket.yaml”,

            “cli/onegroup.yaml”,

            “cli/onevm.yaml”,

            “cli/oneflowtemplate.yaml”,

            “cli/onevrouter.yaml”,

            “cli/onezone.yaml”,

            “cli/oneimage.yaml”,

            “cli/onecluster.yaml”,

            “cli/oneuser.yaml”,

            “cli/onevntemplate.yaml”,

            “cli/onevdc.yaml”,

            “cli/onehost.yaml”,

            “cli/onedatastore.yaml”,

            “cli/oneflow.yaml”,

            “defaultrc”,

            “ec2_driver.conf”,

            “ec2_driver.default”,

            “fireedge/”,

            “fireedge/provision/”,

            “fireedge/provision/providers.d/”,

            “fireedge/provision/providers.d/vultr_virtual.yaml”,

            “fireedge/provision/providers.d/digitalocean.yaml”,

            “fireedge/provision/providers.d/vultr_metal.yaml”,

            “fireedge/provision/providers.d/equinix.yaml”,

            “fireedge/provision/providers.d/google.yaml”,

            “fireedge/provision/providers.d/aws.yaml”,

            “fireedge/provision/providers.d/dummy.yaml”,

            “fireedge/provision/provision-server.conf”,

            “fireedge/sunstone/”,

            “fireedge/sunstone/user/”,

            “fireedge/sunstone/user/vm-tab.yaml”,

            “fireedge/sunstone/user/vm-template-tab.yaml”,

            “fireedge/sunstone/sunstone-server.conf”,

            “fireedge/sunstone/admin/”,

            “fireedge/sunstone/admin/vm-tab.yaml”,

            “fireedge/sunstone/admin/cluster-tab.yaml”,

            “fireedge/sunstone/admin/vm-template-tab.yaml”,

            “fireedge/sunstone/admin/host-tab.yaml”,

            “fireedge/sunstone/sunstone-views.yaml”,

            “fireedge-server.conf”,

            “hm/”,

            “hm/hmrc”,

            “monitord.conf”,

            “oned.conf”,

            “oneflow-server.conf”,

            “onegate-server.conf”,

            “onehem-server.conf”,

            “sched.conf”,

            “sunstone-logos.yaml”,

            “sunstone-server.conf”,

            “sunstone-views/”,

            “sunstone-views/vcenter/”,

            “sunstone-views/vcenter/admin.yaml”,

            “sunstone-views/vcenter/user.yaml”,

            “sunstone-views/vcenter/groupadmin.yaml”,

            “sunstone-views/vcenter/cloud.yaml”,

            “sunstone-views/mixed/”,

            “sunstone-views/mixed/admin.yaml”,

            “sunstone-views/mixed/user.yaml”,

            “sunstone-views/mixed/groupadmin.yaml”,

            “sunstone-views/mixed/cloud.yaml”,

            “sunstone-views/kvm/”,

            “sunstone-views/kvm/admin.yaml”,

            “sunstone-views/kvm/user.yaml”,

            “sunstone-views/kvm/groupadmin.yaml”,

            “sunstone-views/kvm/cloud.yaml”,

            “sunstone-views.yaml”,

            “tmrc”,

            “vcenter_driver.default”,

            “vmm_exec/”,

            “vmm_exec/vmm_execrc”,

            “vmm_exec/vmm_exec_kvm.conf”

        ]

    }

}

.

TASK [frontend : updates the rafthook and federation configurations for fronteend_HA secondary servers] ******************************************************************************************************************

skipping: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : start OpenNebula] ***************************************************************************************************************************************************************************************

skipping: [testmachine2]

changed: [testmachine1]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “group_names”: [

        “apache_servers”,

        “frontend_server_primary”,

        “mysql_servers”

    ]

}

ok: [testmachine2] => {

    “group_names”: [

        “apache_servers”,

        “frontend_HA”,

        “mysql_servers”

    ]

}

.

TASK [frontend : finding frontend_HA list] *******************************************************************************************************************************************************************************

skipping: [testmachine1] => (item=apache_servers)

skipping: [testmachine1] => (item=frontend_server_primary)

skipping: [testmachine1] => (item=mysql_servers)

skipping: [testmachine2] => (item=apache_servers)

ok: [testmachine2] => (item=frontend_HA)

skipping: [testmachine2] => (item=mysql_servers)

.

TASK [frontend : Add Secondary Node frontends to the zone] ***************************************************************************************************************************************************************

skipping: [testmachine2] => (item=testmachine2)

changed: [testmachine1] => (item=testmachine2)

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “addzone, group_names”: “({‘results’: [{‘changed’: True, ‘stdout’: ”, ‘stderr’: ”, ‘rc’: 0, ‘cmd’: ‘onezone server-add 0 –name testmachine2 –rpc http://192.168.86.65:2633/RPC2’, ‘start’: ‘2022-04-06 03:21:33.920788’, ‘end’: ‘2022-04-06 03:21:34.174098’, ‘delta’: ‘0:00:00.253310’, ‘msg’: ”, ‘invocation’: {‘module_args’: {‘_raw_params’: ‘onezone server-add 0 –name testmachine2 –rpc http://192.168.86.65:2633/RPC2’, ‘_uses_shell’: True, ‘warn’: False, ‘stdin_add_newline’: True, ‘strip_empty_ends’: True, ‘argv’: None, ‘chdir’: None, ‘executable’: None, ‘creates’: None, ‘removes’: None, ‘stdin’: None}}, ‘stdout_lines’: [], ‘stderr_lines’: [], ‘failed’: False, ‘item’: ‘testmachine2’, ‘ansible_loop_var’: ‘item’}], ‘skipped’: False, ‘changed’: True, ‘msg’: ‘All items completed’}, [‘apache_servers’, ‘frontend_server_primary’, ‘mysql_servers’])”

}

ok: [testmachine2] => {

    “addzone, group_names”: “({‘results’: [{‘changed’: False, ‘skipped’: True, ‘skip_reason’: ‘Conditional result was False’, ‘item’: ‘testmachine2’, ‘ansible_loop_var’: ‘item’}], ‘skipped’: True, ‘msg’: ‘All items skipped’, ‘changed’: False}, [‘apache_servers’, ‘frontend_HA’, ‘mysql_servers’])”

}

.

TASK [frontend : Restore database to secondary nodes] ********************************************************************************************************************************************************************

skipping: [testmachine1]

changed: [testmachine2]

.

TASK [frontend : debug] **************************************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “restoredb”: {

        “changed”: false,

        “skip_reason”: “Conditional result was False”,

        “skipped”: true

    }

}

ok: [testmachine2] => {

    “restoredb”: {

        “changed”: true,

        “cmd”: “onedb restore -f -S localhost -u admin -p admin -d opennebula /tmp/opennebula.sql”,

        “delta”: “0:00:00.988908”,

        “end”: “2022-04-06 03:21:35.749776”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-04-06 03:21:34.760868”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “MySQL DB opennebula at localhost restored.”,

        “stdout_lines”: [

            “MySQL DB opennebula at localhost restored.”

        ]

    }

}

.

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

testmachine1               : ok=70   changed=38   unreachable=0    failed=0    skipped=8    rescued=0    ignored=0   

testmachine2               : ok=71   changed=37   unreachable=0    failed=0    skipped=7    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!

.

.

How to pass an API key with Ansible

https://chronosphere.io/ – Third Party Cloud Monitoring Solution

Chronocollector: – https://github.com/Perfect10NickTailor/chronocollector

This role deploys the chronocollector management service which sends the data to domain.chronosphere.io For those of you who don’t know what it is. Its basically a cloud monitoring tool that scrapes data on your instances and then you can create dashboards or even export the data to promethus to make it look pretty and easy to read. You will likely pay for subscription, they will give you a subdomain which becomes your gateway address (domain.chronosphere.io)

Special note: You then need to deploy the node_exporter to push to the hosts you want scraped. That is a separate playbook and stupid easy.

This role will download the latest collector
It will install the latest collector
It will check to see if the ‘service’ its added to systemd, if nots.. adds it, if the service is there, it will move on and simply start the service.

#nowthatsjustfunny: So its debatable on how to approach passing {{ api_keys }} in a scalable and secure way. A lot of people create an “ansible vault encrypted variable”. This is so that when they push their code to their git repos. The {{ api_key }} isn’t exposed to someone simply glancing by the code. The issue with this approach is now you have to remember a vault password to pass to ansible, so it can decrypt the {{ api_key }} to pass, inorder for it to work when you run the playbook.(LAME)

.

#nowthatsjustcool: So just for the purposes of this post and for fun. I wrote it so that you can simply pass the {{ api_key }} during runtime. This way instead of being prompted for the vault-pass, you are prompted for the api_key to pass as a variable when you run the book. This gets rid of the need to setup a encrypted variable in your code entirely. Everyone has their own way of doing things, but I tend to think outside the box, so it always way more fun to be different in how you think.

.

Ansible Operational Documentation

How to use this role:

1.You must first download the git repository
a.git clone git@github.com:Perfect10NickTailor/chronocollector.git
2.Under your user you will see a directory called chronocollector cd into this directory here you will see the defaults/main.yml where you can see what you can pass to groups_vars & host_vars
b.cd chronocollector

.

3.Next you want edit the hosts.client inside your ansible/inventory/dev/hosts.client

Example file: hosts.dev or hosts.staging

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

Running your playbook:

1.You must run your play book from inside parent ansible directory

.

2.Now there is a playbook called chronocollector.yml in the ansible directory which simply calls the chronocollector role inside the ansible/roles/chronocollector directory, where the role should be living.

Example: of ansible/chronocollector.yml

hosts: all

  gather_facts: no

  vars_prompt:

  – name: api_key

    prompt: Enter the API key

  roles:

    – role: chronocollector

.

Command:

ansible-playbook -i inventory/dev/hosts.dev chronocollector.yml -u nickadmin -Kkb –ask-become –limit=’testmachine3′

-i : This flag tells ansibe-playbook command which hosts file to use, these are always defined by customer 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 run:

.

Notice: It asks you for the API key at runtime.

ntailor@jumphost:~/ansible2$ ansible-playbook -i ansible/inventory/dev/hosts.dev chronocollector.yml -u nicktadmin -Kkb –ask-become –limit=’testmachine3′

SSH password:

BECOME password[defaults to SSH password]:

Enter the API key:

.

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

.

TASK [chronocollector : download node collector] *************************************************************************************************************************************************************************

ok: [testmachine3]

.

TASK [chronocollector : move collector to /usr/local/bin] ****************************************************************************************************************************************************************

ok: [testmachine3]

.

TASK [chronocollector : mkdir directory /etc/chronocollector] ************************************************************************************************************************************************************

ok: [testmachine3]

.

TASK [chronocollector : Copy default config.yml to /etc/chronocollector/] ************************************************************************************************************************************************

ok: [testmachine3]

.

TASK [chronocollector : Touch again the same file, but do not change times this makes the task idempotent] ***************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Ensure API key is present in config file] ********************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Change file ownership, group and permissions apitoken file to secure it from prying eyes other than root] ****************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Check that the service file /etc/systemd/system/collector.service exists] ************************************************************************************************************************

ok: [testmachine3]

.

TASK [chronocollector : Include add systemd task if service file does not exist] *****************************************************************************************************************************************

included: ansible/roles/chronocollector/tasks/systemd.yml for testmachine3

.

TASK [chronocollector : Create startup file for collector in systemd] ****************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Create systemd collector.service] ****************************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : check whether custom line exists] ****************************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Start Collector Service via systemd] *************************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : Show status of collector from systemd] ***********************************************************************************************************************************************************

changed: [testmachine3]

.

TASK [chronocollector : debug] *******************************************************************************************************************************************************************************************

ok: [testmachine3] => {

“status.stdout”: ” Active: failed (Result: exit-code) since Thu 2022-05-19 10:31:49 BST; 315ms ago”

}

.

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

testmachine3 : ok=15 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

How to deploy Netplan with Ansible

Ansible-Netplan: – https://github.com/Perfect10NickTailor/ansible-netplan

This role will push out the config to the designated host and apply it
It will make a backup of the previous config before applying the new config, this is just incase your config change had an yaml error and you need to quickly go in and revert back.
There is a defaults/main.yml file that all the flags and how to use them.

.

Netplan.io- what is it is? Basically yaml files to deploy network configurations in a scalable manner by Ubuntu

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

Put your server under the appropriate group inside the file and save
i.Testmachine1 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:

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)
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.
Group_vars – Are 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
cd host_var
create a file called {{ servername }} and save it for us its testmachine1

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.

https://medium.com/@sujaypillai/connect-to-your-remote-servers-from-visual-studio-code-eb5a5875e348

.

.

5.Now Netplans can be simple or very complicated. Ansible-netplan is broken up into segments that look for these variables to pass.
Network, vlans, ethernets, bridges & bonds

.

6.Now my advice is not to copy the block from this document and to copy download the repo open in visual studio and copy it there.

.

Example files:

ansible/inventory/dev/host_var$ testmachine1 (with Bonding)

 

.

Example Yaml Block :

# testmachine1 netplan config

# This is the network for testmachine1 with network bonding

netplan_configuration:

    network:

      bonds:

        bond0:

          interfaces:

          – ens1f0

          – ens1f1

          parameters:

            mode: balance-rr

      ethernets:

        eno1:

          dhcp4: false

        eno2:

          dhcp4: false

        ens1f0: {}

        ens1f1: {}

      version: 2

.

      vlans:

        vlan.180:

          id: 180

          link: bond0

        #  dhcp4: false

        #  dhcp6: false

        vlan.3200:

          id: 3200

          link: bond0

        #  dhcp4: false

        #  dhcp6: false

        vlan.3300:

          id: 3300

          link: bond0

        #  dhcp4: false

        #  dhcp6: false

.

      bridges:

        br200:

          interfaces: [ vlan.200 ]

          addresses: [ 192.168.50.9/24 ]

          gateway4: 192.168.50.1

          nameservers:

                  addresses: [ 8.8.8.8,8.8.4.8 ]

                  search: [ nicktailor.com ]        

          dhcp4: false

          dhcp6: false

        br3000:

          interfaces: [ vlan.3000 ]

          dhcp4: false

          dhcp6: false

        br3200:

          interfaces: [ vlan.3200 ]

          dhcp4: false

          dhcp6: false

.

Example files:
ansible/inventory/dev/host_var$ testmachine1 (without Bonding)

.

Example Yaml Block :

#testmachine1

netplan_configuration:

    network:

      version: 2

      renderer: networkd

      ethernets:

        eno1:

          dhcp4: false

          dhcp6: false

        eno2:

          dhcp4: false

          dhcp6: false

.

      bridges:

        br0:

          interfaces: [ eno1 ]

          dhcp4: false

          dhcp6: false

        br1:

          interfaces: [ eno2 ]

          dhcp4: false

          dhcp6: false

        br1110:

          interfaces: [ vlan1110 ]

          dhcp4: false

          dhcp6: false

          addresses: [ 172.16.52.10/26 ]

          gateway4: 172.17.52.1

          nameservers:

                  addresses: [ 8.8.8.8,8.8.4.8 ]

.

        br600:

          interfaces: [ vlan600 ]

          dhcp4: false

          dhcp6: false

          addresses: [ 192.168.0.34/24 ]

        br800:

          interfaces: [ vlan800 ]

          dhcp4: false

          dhcp6: false

        br802:

          interfaces: [ vlan802 ]

          dhcp4: false

          dhcp6: false

        br801:

          interfaces: [ vlan801 ]

          dhcp4: false

          dhcp6: false

.

      vlans:

        vlan600:

          id: 600

          link: br0

          dhcp4: false

          dhcp6: false

        vlan800:

          id: 800

          link: br1

          dhcp4: false

          dhcp6: false

        vlan801:

          id: 801

          link: br1

          dhcp4: false

          dhcp6: false          

        vlan802:

          id: 802

          link: br1

          dhcp4: false

          dhcp6: false  

          

.

.

8.You must now edit the the appropriate lines and save the file
vlans, ethernets, blond, addresses, & bridges

.

9.Once saved you want to run the playbook against a test server before you push the code into the git repository. So it good to have a test vm to run your code against first.

.

Running your playbook:

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

Example: of ansible/deploynetplan.yml

hosts: all

  gather_facts: yes

  any_errors_fatal: true

  roles:

    – role: ansible-netplan

      netplan_enabled: true

.

Command:

ansible-playbook -i inventory/dev/hosts deploynetplan.yml -u nickadmin -Kkb –ask-become –limit=’testmachine1′

-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 with bonding:

.

ntailor@KVMtestbox:~/ansible$ ansibleplaybooki inventory/dev/hosts deploynetplan.ymlu nickadminKkbaskbecomelimit=‘testmachine1’

SSH password:

BECOME password[defaults to SSH password]:

.

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

.

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

ok: [testmachine1]

.

TASK [ansiblenetplan : Install netplan] ***************************************************************************************************************************************************************

ok: [testmachine1]

.

TASK [ansiblenetplan : Backup exitsing configurations before removing live ones] **********************************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : copy 00install* netplan existing file to /etc/netplan/backups] ****************************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : keep only 7 days of backups of previous network config /etc/netplan/backups] ***************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : Capturing Existing Configurations] *********************************************************************************************************************************************

skipping: [testmachine1]

.

TASK [ansiblenetplan : debug] *************************************************************************************************************************************************************************

skipping: [testmachine1]

.

TASK [ansiblenetplan : Removing Existing Configurations] **********************************************************************************************************************************************

skipping: [testmachine1]

.

TASK [ansiblenetplan : Configuring Netplan] ***********************************************************************************************************************************************************

ok: [testmachine1]

.

TASK [ansiblenetplan : netplan apply] *****************************************************************************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : debug] *************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “netplanapply”: {

        “changed”: true,

        “cmd”: “netplan apply”,

        “delta”: “0:00:00.601112”,

        “end”: “2022-01-31 16:43:45.295708”,

        “failed”: false,

        “msg”: “”,

        “rc”: 0,

        “start”: “2022-01-31 16:43:44.694596”,

        “stderr”: “”,

        “stderr_lines”: [],

        “stdout”: “”,

        “stdout_lines”: []

    }

}

.

TASK [ansiblenetplan : Show vlans that are up or down] ************************************************************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : debug] *************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “vlan.stdout_lines”: [

        “14: vlan.180@bond0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000”,

        “15: vlan.3300@bond0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000”

    ]

}

.

TASK [ansiblenetplan : show bridge details] ***********************************************************************************************************************************************************

changed: [testmachine1]

.

TASK [ansiblenetplan : debug] *************************************************************************************************************************************************************************

ok: [testmachine1] => {

    “bridges.stdout_lines”: [

        “bridge name\tbridge id\t\tSTP enabled\tinterfaces”,

        “br180\t\t8000.000000000000\tyes\t\t,

        “br3200\t\t8000.000000000000\tyes\t\t,

        “br3300\t\t8000.000000000000\tyes\t\t

    ]

}

.

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

testmachine1               : ok=12   changed=6    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   

.

.

.

Push your inventory/dev/host_var/testmachine1 code to Git :

 

Once you successfully checked your deploy worked by logging on to the client host and confirming everything looks good. You now want to push your code to git repo. Since you were able to clone you repo, you should be able to push to it.

.

Git Add Commands.

1.Git add . (will do every file you changed)
2.Git add filename will only add the file you want

.

Git Commit Commands

1.Git commit
a.This will take you to a message screen. Just type a note of what you did save the file
2.Git push
b.This will push your changes

.

.

How to call a json rest API using Ansible        

So a very useful thing to understand is rest api’s and how to call them as a lot of organisations have these and want to integrate them into automation, a popular method is the http method

They are very simple calls { GET, POST, PUT, DELETE, PATCH }

For the sake of this post. Im going to use commvault public api’s https://api.commvault.com/

You will need to two things.

  1. The api endpoint which is usually an http url

Example:

  1. http://WebConsoleHostName/webconsole/api/CommServ/Failover
  1. The raw  json body of the of the api

Example:

{

    "csFailoverConfigInfo": {

        "configStatus": 0,

        "isAutomaticFailoverEnabled": false

    }

}

Now keep in mind if you are using an api that requires a login. In order for it to work, you will need to store the auth token to pass later to the last task later for the api call to work as intended. You can look at one of my other posts under vmware, where i used a http login to handle the tasks later, as a reference.

You can call these preliminary task as includes to store the token.

It will look something like this before it gets to the api task. You can also just do it all one on book if you wanted to. But for the purposes of this post. Im just giving ya highlevel.

- name: Login task

  include_role:

    name: commvault_login

    tasks_from: login.yml

- name: Setfact for authtoke

  set_fact:

    authtoken: "{{ login_authtoken }}"

  delegate_to: localhost

Now in order for you to pass json api to ansible. You will need to convert the json raw body into yaml format. You can use visual studio code plugins or a site like https://json2yaml.com/

So if we are to use the above raw json example it would look like this

csFailoverConfigInfo:

  configStatus: 0

  isAutomaticFailoverEnabled: false

So now we want to pass this information to the task in the form of a variable. A really cool thing with ansible and this type of action. Is you can create a variable name and simply pass the new yaml converted body right below the varible. You can pass this as extra-vars or create a group variable with the same name and use that.

For those you who use tower passing them as extra-vars to test something can be a pain, since it doesn’t allow you to change the passed vars and rerun the previous run just used, you have to start all over. So I prefer the command line way as its easier to be agile

disable_api_body:

csFailoverConfigInfo:

  configStatus: 0

  isAutomaticFailoverEnabled: false

So now we ansible to use the rest api with ansible. You create a task that after the login is run and the token is stored inside as a fact. It run the following task, in our case this call will be a POST. It will post the headers to the url which will disabled commvault live_sync which is essentially commvault failover redundancy for the backup server itself.

- name: Disable Commvault livesync 

  uri:

    url: http://{{ commvault_primary }}/webconsole/api/v2/CommServ/Failover

    method: POST

    body_format: json

    body: "{{ disable_api_body }}"

    return_content: true

    headers:

      Accept: application/json

      Content-Type: application/json

      Authtoken: "{{ login_authtoken }}"

    status_code: 200

    validate_certs: false

  register: disable_livesync

  retries: "4"

  delay: "10"

  delegate_to: localhost

- debug: 
    var: disable_livesync
     

When you run the book and your have an active failover setup correctly with commvault. In the command center under the control panel you should see livesync. If you click on this you should see either it is checked or unchecked.

How to Deploy LVM’s with Ansible

Provisioning-LVM-Filesystems:

This role is designed to use ansible-merge-vars module. An Ansible plugin to merge all variables in context with a certain suffix (lists or dicts only) and create a new variable that contains the result of this merge. This is an Ansible action plugin, which is basically an Ansible module that runs on the machine running Ansible rather than on the host that Ansible is provisioning.

Benefits: Configuring disks into LVM

 Adds Physical Disk to Volume to Volume Group
 Creates Logical Volume assigned to Volume Group
 Creates the size of the disk to full or whatever you wish to set
 It will format the LVM to whatever file format you wish
 It will then create the mount point and mount the lvm
 It will also add the lvm to fstab upon mounting

Note: This post assumes you have already ansible installed and running.

Install ansible-merge-vars module:

1.       root@KVM-test-box:~# pip install ansible_merge_vars
          Requirement already satisfied: ansible_merge_vars in
          /usr/local/lib/python3.8/dist-packages (5.0.0)

2.Create an action_plugins directory in the directory in which you run Ansible.

By default, Ansible will look for action plugins in an action_plugins folder adjacent to the running playbook. For more information on this, or to change the location where ansible looks for action plugin.

 

3.Create a file called merge_vars.py (or whatever name you picked) in the action_plugins directory, with one line:

  from ansible_merge_vars import ActionModule

.

4.Save the file

.

Role Setup:

Once the plugin has been setup, you now you will want to setup a role.

1.Move inside the ansible/roles directory
a.cd ansible/roles/
2.Create a directory for the role provision-fs
b.mkdir -p provision-fs/tasks
3.Move inside the tasks directory
c.cd ansible/roles/provision-fs/tasks

Now we will create a task that will merge variable names associated with a list and then itemise the list for variables we will pass to provision the filesystem via the inventory/host_var or group_var

.

4.Create a file called main.yml inside provision-fs/tasks/main.yml

.

name: Merge VG variables

  merge_vars:

    suffix_to_merge: vgs__to_merge

    merged_var_name: merged_vgs

    expected_type: ‘list’

.

name: Merge LV variables

  merge_vars:

    suffix_to_merge: lvs__to_merge

    merged_var_name: merged_lvs

    expected_type: ‘list’

.

name: Merge FS variables

  merge_vars:

    suffix_to_merge: fs__to_merge

    merged_var_name: merged_fs

    expected_type: ‘list’

.

name: Merge MOUNT variables

  merge_vars:

    suffix_to_merge: mnt__to_merge

    merged_var_name: merged_mnt

    expected_type: ‘list’

.

name: Create VGs

  lvg:

    vg: {{ item.vg }}”

    pvs: {{ item.pvs }}”

  with_items: {{ merged_vgs }}”

.

name: Create LVs

  lvol:

    vg: {{ item.vg }}”

    lv: {{ item.lv }}”

    size: {{ item.size }}”

    pvs: {{ item.pvs | default(omit) }}”

    shrink: no

  with_items: {{ merged_lvs }}”

.

name: Create FSs

  filesystem:

    dev: {{ item.dev }}”

    fstype: {{ item.fstype }}”

  with_items: {{ merged_fs }}”

.

name: Mount FSs

  mount:

    path: {{ item.path }}”

    src: {{ item.src }}”

    state: mounted

    fstype: {{ item.fstype }}”

    opts: {{ item.opts | default(‘defaults’) }}”

    dump: {{ item.dump | default(‘1’) }}”

    passno: {{ item.passno | default(‘2’) }}”

  with_items: {{ merged_mnt }}”

.

.

5.Save the file

.

Note: Now this currently task has no safe guards for /dev/sda or checks to ensure the disk is wiped properly in order for the disks to be added to the volume group. I have created such safe guards for others. But for the purposes of this blog post this is basics. If you want to my help you can contact me via email or the ticketing system.

.

Now what we are going to do is define our inventory file with what file lvm we want to crave out.

.

Setup inventory:
1.Go inside your inventory/host_var or group_var file and create a file for testserver1

  • .nano inventory/host_var/testserver1
vgs__to_merge:
  – vg: vg_vmguest
    pvs: /dev/sdb
  – vg: vg_sl_storage
    pvs: /dev/sdc
lvs__to_merge:
  – vg: vg_vmguest
    lv: lv_vg_vmguest
    size: 100%FREE
    shrink: no
  – vg: vg_sl_storage
    lv: lv_vg_sl_storage
    size: 100%FREE
    shrink: no
fs__to_merge:
  – dev: /dev/vg_vmguest/lv_vg_vmguest
    fstype: ext4
  – dev: /dev/vg_sl_storage/lv_vg_sl_storage
    fstype: ext4
mnt__to_merge:
  – path: /vmguests
    src: /dev/vg_vmguest/lv_vg_vmguest
    fstype: ext4
  – path: /sl_storage
    src: /dev/vg_sl_storage/lv_vg_sl_storage
    fstype: ext4

.

2. save the file.

.

Definitions of the variables above:

vgs__to_merge: This section is the creation volume/physical groups

  – vg: vg_vmguest (this is the volume group name)

    pvs: /dev/sdb (this is the physical assigned to the above volume group

  – vg: vg_sl_storage (This the second volume name)

    pvs: /dev/sdc (This is the second physical disk assigned to the above

volume
*You can add as many as you like*

.

lvs__to_merge: This section is the logical Volume creations

  – vg: vg_vmguest (this is the volume group created)

    lv: lv_vg_vmguest (this is the logical volume that is attached to above vg

    size: 100%FREE (this says please use the whole disk)

    shrink: no (this is needed to so the disk space is used correctly)

  – vg: vg_sl_storage (this is the second volume created)

    lv: lv_vg_sl_storage (this is the second lvm created attached to above vg)

    size: 100%FREE (this is use the whole disk)

    shrink: no (this is needed so the disk space is properly used)

.

fs__to_merge: This section formats the lvm

  – dev: /dev/vg_vmguest/lv_vg_vmguest (lvm name)

    fstype: ext4 (file system you want to format with)

  – dev: /dev/vg_sl_storage/lv_vg_sl_storage (2nd lvm name)

    fstype: ext4 (file system you want to format with)

.

mnt__to_merge: This section will create the path,mount, and add to fstab

  – path: /vmguests (path you want created for mount)

    src: /dev/vg_vmguest/lv_vg_vmguest (lvm you want to mount)

    fstype: ext4 (this is for fstab adding)

  – path: /sl_storage (this is second path to create)

    src: /dev/vg_sl_storage/lv_vg_sl_storage (second lvm you want to mount)

    fstype: ext4 (to add to fstab)

.

Running your playbook:

1.Go inside your ansible home directory

cd ansible/

2.Create a file called justdofs.yml and save it

Example: of justdofs.yml

hosts: all

  gather_facts: yes

  any_errors_fatal: true

  roles:

    – role: provision-fs

.

3.Ensure the testervernick1 is listed under inventory/hosts
a.Testservernick1 ansible_host=192.168.80.200

Command:

ansible/$ ansible-playbook -i inventory/hosts justdofs.yml -u root -k –limit=’testservernick1′

.

Example of successful play:

ntailor@test-box:~/ansible/computelab$ ansible-playbook –i inventory/hosts justdofs.yml -u root -k –limit=’testservernick1

SSH password:

.

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

.

TASK [provision-fs : Merge VG variables] *************************************************************************************************************************************************************************

ok: [testservernick1]

.

TASK [provision-fs : Merge LV variables] *************************************************************************************************************************************************************************

ok: [testservernick1]

.

TASK [provision-fs : Merge FS variables] *************************************************************************************************************************************************************************

ok: [testservernick1]

.

TASK [provision-fs : Merge MOUNT variables] **********************************************************************************************************************************************************************

ok: [testservernick1]

.

TASK [provision-fs : Create VGs] *********************************************************************************************************************************************************************************

ok: [testservernick1] => (item={‘vg’: ‘vg_vmguest‘, ‘pvs‘: ‘/dev/sdb‘})

ok: [testservernick1] => (item={‘vg’: ‘vg_sl_storage‘, ‘pvs‘: ‘/dev/sdc‘})

.

TASK [provision-fs : Create LVs] *********************************************************************************************************************************************************************************

ok: [testservernick1] => (item={‘vg’: ‘vg_vmguest‘, ‘lv’: ‘lv_vg_vmguest‘, ‘size’: ‘100%FREE’, ‘shrink’: False})

ok: [testservernick1] => (item={‘vg’: ‘vg_sl_storage‘, ‘lv’: ‘lv_vg_sl_storage‘, ‘size’: ‘100%FREE’, ‘shrink’: False})

.

TASK [provision-fs : Create FSs] *********************************************************************************************************************************************************************************

ok: [testservernick1] => (item={‘dev’: ‘/dev/vg_vmguest/lv_vg_vmguest‘, ‘fstype‘: ‘ext4’})

ok: [testservernick1] => (item={‘dev’: ‘/dev/vg_sl_storage/lv_vg_sl_storage‘, ‘fstype‘: ‘ext4’})

.

TASK [provision-fs : Mount FSs] **********************************************************************************************************************************************************************************

ok: [testservernick1] => (item={‘path’: ‘/vmguests‘, ‘src‘: ‘/dev/vg_vmguest/lv_vg_vmguest‘, ‘fstype‘: ‘ext4’})

ok: [testservernick1] => (item={‘path’: ‘/sl_storage‘, ‘src‘: ‘/dev/vg_sl_storage/lv_vg_sl_storage‘, ‘fstype‘: ‘ext4’})

.

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

testservernick1 : ok=8    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

.

How to add VM-Tags and Custom attributes with Anisble(VMware)

So whether your using cloud or doing in house deploys. Tagging is a used a lot especially in cloud type environments. Which we will cover in later posts.

So a common reason to tag your vm is wanting to have the creation date and the type of server or environment its using, handy for backup solutions & other auditables.

.

Pre-requisites: Assumed.

 Ansible 2.9 installed and configured –
 Vmware Community modules configured
 Vmware group variables previously defined for vmware deployments(Is helpful)

.

Step by Step:

1.Create a roles directory inside /etc/ansible/roles

a.mkdir -p /etc/ansible/roles/custom-tags-attributes-vmware/tasks

b.mkdir -p /etc/ansible/roles/ custom-tags-attributes-vmware/defaults

 

2.Now you want to create a task for the snapshots.

c.Inside /etc/ansible/roles/custom-tags-attributes-vmware/tasks/

d.Create a file called main.yml

 

3.Add the following code and save the file 

Note: Okay for the custom attributes to work you need to get the MOID, UUID & Folder of the vm by using the vm name. So we need to gather facts about the vm and the set those facts as variables that we can pass to the next tasks.

 

– name: get list of facts

  vmware_guest_facts:

hostname: “{{ vcenter_host }}”

username: “{{ vcenter_username }}”

password: “{{ vcenter_password }}”

name: “{{ inventory_hostname }}”

    datacenter: “{{ vcenter_dc }}”

    validate_certs: False

  delegate_to: localhost

  ignore_errors: true

register: vm_facts

 

Note: So when we use the vmware_guest_facts module to gather the facts about the vm by register the facts to a variable “vm_facts, which when you run the playbook with –vvvv will spit out the facst you can pass as indicated below..

      hw_folder“: “/SysUnix/Testing“,

hw_guest_full_name“: “Red Hat Enterprise Linux 7 (64-bit)”,

hw_guest_ha_state“: true,

hw_guest_id“: “rhel7_64Guest”,

hw_interfaces“: [

“eth0”

],

hw_is_template“: false,

hw_memtotal_mb“: 2048,

hw_name“: “v-sits-test4”,

hw_power_status“: “poweredOn“,

hw_processor_count“: 2,

hw_product_uuid“: “4226d4e1-6be8-9447-5ced-b037075e2ffd”,

hw_version“: “vmx-11”,

instance_uuid“: “50263518-c95b-c3be-5c77-4e1ea69ec295”,

“ipv4”: “192.168.1.29“,

“ipv6”: null,

module_hw“: true,

        moid“: “vm-296678”,

“snapshots”: [],

vimref“: “vim.VirtualMachine:vm-296678”,

vnc“: {}

.

.Note: Now that we have the UUID, MOID, & Folder. We now want to create static variables for UUID, MOID, & folder by using the previous variable we registered as “vm_facts”, and we want to set them as static variables by setting them as facts we can past to the tasks after. As indicated below. Again setting facts is the same as defining variables in bash. Just ansible way to do it.

 

– set_fact:

    vm_uuid: “{{ vm_facts.instance.instance_uuid }}”

– set_fact:

    moid: “{{ vm_facts.instance.moid }}”

– set_fact:

    vm_folder: “{{ vm_facts.instance.hw_folder }}”

 

Note: Now want to use the ansible server date and pass that as a variable so you don’t have to input the date as manual value each time you deploy a new host. So we want to grab the date and setup a static fact and then pass it as its own variable. Like we did above…

– name: Get Date

shell: date +%Y-%m-%d

register: date

  delegate_to: localhost

 

Note: We use shell module to get the date in the format we want, then register the result as the variable {{ date }}. We then set a static fact of the result and create another variable called date with using the result from the above.

– set_fact:

    date: “{{ date.stdout }}”

 

Note: We now want to pass all the fact to the “vmware_guest_custom_attributesmodule UUID, MOID, DATE, and Folder indicated as below.

– name: Add multiple virtual machine custom attributes

  vmware_guest_custom_attributes:

hostname: “{{ vcenter_host }}”

username: “{{ vcenter_username }}”

password: “{{ vcenter_password }}”

name: “{{ inventory_hostname }}”

    datacenter: “{{ vcenter_dc }}”

    folder: “{{ vm_folder }}”

    uuid: “{{ vm_facts.instance.instance_uuid }}”

    moid: “{{ vm_facts.instance.moid }}”

state: present

    validate_certs: False

    use_instance_uuid: True

attributes:

– name: Creation Date

value: “{{ date }}”   

# – name: MyAttribute2 – Note: You can add additional attributes if you wish

# value: test2 – Note: You can add additional attributes if you wish

  delegate_to: localhost

register: attributes

 

Note: Okay so depending on which module you use, some require you to gather facts about the vmware categories. This is just incase you need the cateogory_id which is usually derived from using a REST API in json or other method. The “community.vmware.vmware_category_factswill be able to pull the info and then you can pass it as a variable or a static value. IF YOU NEED, however this is NOT needed. If you use the vmware_tag_manager” module”

 

– name: Gather facts about tag categories

  community.vmware.vmware_category_facts:

hostname: “{{ vcenter_host }}”

username: “{{ vcenter_username }}”

password: “{{ vcenter_password }}”

    validate_certs: no

  delegate_to: localhost

register: all_tag_category_facts

.

ok: [v-sits-test4] => {

“changed”: false,

“invocation”: {

module_args“: {

“hostname”: “vmware.nicktailor.com“,

“password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,

“port”: 443,

“protocol”: “https”,

“username”: “admin“,

validate_certs“: false

}

},

tag_category_facts“: [

{

category_associable_types“: [

VirtualMachine

],

category_cardinality“: “SINGLE”,

category_description“: “VM Type – Clone, Decomm, Dev, Prod, SRM, SLM, Template or Test”,

category_id“: “urn:vmomi:InventoryServiceCategory:f1024eb4-d7d4-49fe-9725-4dcba39fbe3b:GLOBAL”,

category_name“: “VMType“,

category_used_by“: []

},

{

category_associable_types“: [

VirtualMachine

],

category_cardinality“: “SINGLE”,

category_description“: “Team or Department”,

category_id“: “urn:vmomi:InventoryServiceCategory:888a0877-5335-4477-9347-6d8de5b3e60e:GLOBAL”,

category_name“: “Team/Dept”,

category_used_by“: []

}

]

}

.

.

Note: Now that we want to create the tag for the vm using the “vmware_tag_managermodule. The only variable that is passed from outside the defaults at the inventory_hostname level “host_var/nicktest1” is the {{ vm_tag }} Make sure you have this defined for the role to work properly.

 

– name: Add tags to a virtual machine

  vmware_tag_manager:

hostname: ‘{{ vcenter_host }}’

username: ‘{{ vcenter_username }}’

password: ‘{{ vcenter_password }}’

    validate_certs: no

    tag_names:

      – “{{ vm_tag }}” – passed at the host_var/nicktest1

    object_name: “{{ inventory_hostname }}”

    object_type: VirtualMachine

state: present

  delegate_to: localhost

 

4.Save the file
5.You can either have group_vars set up for individual datacenters, but for now just define the variables under /etc/ansible/roles/custom-tags-attributes-vmware/defaults

.

Note: You will likely have a group_var from you vmdeploy role that you can use for here.

.

e.Create a file called main.yml and the following variables

vcenter_username: admin

vcenter_password: should be vault encrypted variable

vcenter_host: vmware.nicktailor.com

vcenter_dc: London

.

.

f.Save the file

.

 Note: Ensure your host “nicktest1” is listed in your inventory host file.
/etc/ansible/inventory/TEST/hosts
 Note: Make sure your “host_var/nicktest1″ has the “vm_tag: {{ value }}” defined

 

Run your playbook: from /etc/ansible

.

1.ansible-playbook –i inventory/TEST/hosts justremovevmsnap.yml –ask-vault-pass –limit=’nicktest1′

.

Playbook log:

.

[root@ansible-server]# ansible-playbook –i inventory/TEST/hosts justcustomattrib.yml –ask-vault-pass –limit=’v-sits-test4′

Vault password:

.

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

.

TASK [custom-tags-attributes-vmware : get list of facts] ************************************************************************************

[DEPRECATION WARNING]: The ‘vmware_guest_facts‘ module has been renamed to ‘vmware_guest_info‘. This feature will be removed in version

2.13. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : Get Date] *********************************************************************************************

changed: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : set_fact] *********************************************************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : Add multiple virtual machine custom attributes] *******************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : Gather facts about tag categories] ********************************************************************

ok: [v-sits-test4]

.

TASK [custom-tags-attributes-vmware : Add tags to a virtual machine] ************************************************************************

ok: [v-sits-test4]

.

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

v-sits-test4 : ok=9 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

.

How to remove snapshots with Ansible(VMware)

Okay, so lots of folks ask me about this, and there are a number of ways you can do this. 

But if you’re using vmware and redhat satellite for central patch management for your redhat environment.

Then depending on how you patch your systems. If you snapshot every group prior to patching. Then this post will be perfect for you.

Process:

1.Remove snapshot once patching is all done and servers are confirmed OKAY

Pre-requisites: Assumed.

 Ansible 2.9 installed and configured –
 Vmware Community modules configured
 Vmware group variables previously defined for vmware deployments(Is helpful)
 Vmware user/password configure with being able to remove snaphots in either datacenters you have

Step by Step:

1.Create a roles directory inside /etc/ansible/roles

 

a.mkdir -p /etc/ansible/roles/remove-snapshot/tasks

b.mkdir -p /etc/ansible/roles/remove-snapshot/defaults

 

2.Now you want to create a task for the snapshots.

 

c.Inside /etc/ansible/roles/remove-snapshot/tasks/

d.Create a file called main.yml

 

3.Add the following code and save the file

– name: Login into vCenter and get cookies

  delegate_to: localhost

  uri:

url: https://{{ vcenter_host }}/rest/com/vmware/cis/session

    force_basic_auth: yes

    validate_certs: no

method: POST

user: ‘{{ vcenter_username }}’

password: ‘{{ vcenter_password }}’

register: login

 

Note: Okay so what we want to do is find the virtual machine in vsphere by name and then grab its folder value and pass it as a variable so you don’t need to define it statically in your host_var. The main reason is, say you deployed a vm and months later moved it to another folder, your code will likely have the origin folder which would be annoying, and the ansible documentation doesn’t really cover this approach, you basically figure it out as you do it. So im going to save you all time. Here is how you do it. The below will gather vm_facts based on the inventory_hostname

– name: Find Guest’s Folder using name

  vmware_guest_find:

hostname: “{{ vcenter_host }}”

username: “{{ vcenter_username }}”

password: “{{ vcenter_password }}”

     validate_certs: no

name: “{{ inventory_hostname }}”

  delegate_to: localhost

  ignore_errors: true

register: vm_facts

Note: It will than gather those facts and find the folder value. You then register the facts to a variable “vm_facts” Now it will spit out what it finds when you do –vvvv when you do your play. From there you can see the folder setting. You now want to set that that folder setting as its own variable that you can pass to another task as indicated below.

.

ok: [ansible-server] => {

“changed”: false,

    “folders”: [

“/SysUnix/Teststuff

],

“invocation”: {

module_args“: {

datacenter“: null,

“hostname”: “vmware.nicktailor.com“,

“name”: ” ansible-server“,

“password”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,

“port”: 443,

proxy_host“: null,

proxy_port“: null,

use_instance_uuid“: false,

“username”: “svc_ans“,

uuid“: null,

validate_certs“: false

}

}

}

– name: “vm_folder – setting folder value”

  set_fact:

    folder : “{{ vm_facts.folders }}”

 

Note: So you can see that the facts has a sub fact called “folders”. We want to pass that by setting that value as its own variable by making it a fact. Ansible way to set variables is setting facts. So we make that value above into a variable “vm_facts.folders” and then pass that into the next task where it asks for folders. This will get around the having to provide the exact folder the vm_resides to create snapshotting for an array of hosts. This section is basically identical to create except the “state” is set to absent

– name: Remove Snapshot

  vmware_guest_snapshot:

hostname: “{{ vcenter_host }}”

username: “{{ vcenter_username }}”

password: “{{ vcenter_password }}”

     datacenter: “{{ vcenter_dc }}”

     validate_certs: no

name: “{{ inventory_hostname }}”

     state: absent

     snapshot_name: “Ansible Managed Snapshot”

     folder: “‘{{ vm_facts.folders }}'”

description: “This snapshot is created by Ansible Playbook”

  delegate_to: localhost

.

4.Save the file

.

5.You can either have group_vars set up for individual datacenters, but for now just define the variables under /etc/ansible/roles/remove-snapshot/defaults

.

Note: You will likely have a group_var from you vmdeploy role that you can use for here.

.

e.Create a file called main.yml and the following variables

vcenter_username: admin

vcenter_password: should be vault encrypted variable

vcenter_host: vmware.nicktailor.com

vcenter_dc: London

.

.

f.Save the file

.

 Note: Ensure your host “nicktest1” is listed in your inventory host file.
/etc/ansible/inventory/TEST/hosts

Run your playbook: from /etc/ansible

.

1.ansible-playbook –i inventory/TEST/hosts justremovevmsnap.yml –ask-vault-pass –limit=’nicktest1

.

Playbook log:

.

[root@ansible-server]# ansible-playbook –i inventory/TEST/hosts justremovevmsnap.yml –ask-vault-pass –limit=’nicktest1

Vault password:

.

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

.

TASK [remove_snapshot : Login into vCenter and get cookies] *********************************************************************************

ok: [nicktest1]

.

TASK [remove_snapshot : Find Guest’s Folder using name] *************************************************************************************

ok: [nicktest1]

.

TASK [remove_snapshot : vm_folder – setting folder value] ***********************************************************************************

ok: [nicktest1]

.

TASK [remove_snapshot : remove Snapshot] ****************************************************************************************************

ok: [nicktest1]

.

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

nicktest1 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

.

2.Go log into vsphere and check to see the vm no longer has the snapshot name listed.

.

Note: This uses the snapshot name to remove as the one you used to create. If another snapshot exists with a different name it will ignore it entirely. If you pass snapshot variable with another name and run the book again, it will remove another snapshot. The same applies to removing snapshots, it will remove based on the name.

 

0