{"id":796,"date":"2018-07-26T01:00:00","date_gmt":"2018-07-26T01:00:00","guid":{"rendered":"http:\/\/inswwdev.azurewebsites.net\/au\/insights\/uncategorized\/ansible-azure\/"},"modified":"2024-12-13T02:21:26","modified_gmt":"2024-12-13T02:21:26","slug":"ansible-azure","status":"publish","type":"post","link":"https:\/\/www.insentragroup.com\/gb\/insights\/geek-speak\/modern-workplace\/ansible-azure\/","title":{"rendered":"Ansible &#038; Azure"},"content":{"rendered":"<p style=\"text-align: justify;\">Recently, I have spent significant time trying to use ansible to deploy an azure configuration. There are plenty of websites which describe the individual steps but either I could not find the ONE that encompasses them all or there simply isn\u2019t one. I found this utterly frustrating.<\/p>\n<p style=\"text-align: justify;\">So, what did I learn? \u2013 To temper my frustration and to provide some sanity to all who got frustrated before me \u2013 I decided to create this friendly blog.<\/p>\n<p style=\"text-align: justify;\">So\u2026 what is it about? \u2013 In short \u2013 below are all the steps required to prepare a machine from which you will be running ansible playbooks to create stuff in the Azure Cloud.<\/p>\n<p>So, let us begin.<\/p>\n<p style=\"text-align: justify;\"><strong>1. Prepare a new machine. Do not install ansible as the installation will be covered later. If you install ansible from rpm, it might collide with the python \u2018pip\u2019 installation which pulls the latest packages and in some cases the installation might fail as it will find some older packages and libraries which it will not be able to remove.<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>2. Log into your machine (RHEL or CentOS) as root (or use sudo if need be) and install python pip:<\/strong><\/p>\n<p style=\"text-align: justify;\">curl https:\/\/bootstrap.pypa.io\/get-pip.py -o get-pip.py<\/p>\n<p><span>python get-pip.py<\/span><\/p>\n<p><span>pip install kitchen<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>3. Install ansibe [azure]. This step will also install the latest version of Ansible, so installation of the ansible rpm is not necessary.<\/strong><\/p>\n<p style=\"text-align: justify;\"><span>pip install ansible[azure]<\/span><\/p>\n<p style=\"text-align: justify;\"><span>if the pip is showing any incompatibilities, update the packages. For example:<\/span><\/p>\n<p style=\"text-align: justify;\"><span>adal 1.0.2 has requirement python-dateutil&gt;=2.1.0, but you\u2019ll have python-dateutil&nbsp;<\/span><br \/>\n<span>1.5 which is incompatible.<\/span><\/p>\n<p><span>pip install -U python-dateutil<\/span><\/p>\n<p style=\"text-align: justify;\"><span>Cannot uninstall \u2018pyOpenSSL\u2019. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.<\/span><\/p>\n<p style=\"text-align: justify;\"><span>rpm -qa | grep -i pyopenssl<\/span><br \/>\n<span>pyOpenSSL-0.13.1-3.el7.x86_64<\/span><br \/>\n<span>rpm -e \u2013nodeps pyOpenSSL-0.13.1-3.el7.x86_64<\/span><br \/>\n<span>pip install pyOpenSSL<\/span><\/p>\n<p><strong>4. Repeat the installation of ansible[azure]:<\/strong><\/p>\n<p><span>pip install ansible[azure]<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>5. The next step is to install the Azure CLI \u2018AZ\u2019 on your machine which will give you the way to query Azure for the specific information \u2026 and you can also use the AZ to create configuration in Azure. To install AZ on your machine:<\/strong><\/p>\n<p style=\"text-align: justify;\"><span># rpm \u2013import https:\/\/packages.microsoft.com\/keys\/microsoft.asc<\/span><br \/>\n<span># sh -c \u2018echo -e \u201c[azure-cli]nname=Azure CLI<\/span><br \/>\n<span>nbaseurl=https:\/\/packages.microsoft.com\/yumrepos\/azure-clinenabled=1ngpgcheck=1<\/span><br \/>\n<span>ngpgkey=https:\/\/packages.microsoft.com\/keys\/microsoft.asc\u201d &gt;&nbsp;<\/span><br \/>\n<span>\/etc\/yum.repos.d\/azure-cli.repo\u2019<\/span><\/p>\n<p><span># yum install azure-cli<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>6. Login using \u2018az\u2019. This process is simple. Type az login in your preferred console and you will be directed to the web portal where you will enter your azure credentials. az will cache them and that\u2019s it. ?<\/strong><\/p>\n<p><span>az login<\/span><\/p>\n<ul>\n<li>You can expect the following message:<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span>Not able to launch a browser to login you in, falling back to device code\u2026<\/span><br \/>\n<span>To sign in, use a web browser to open the page https:\/\/microsoft.com\/devicelogin and enter the code HPXE3CWK4 to authenticate.<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\">Launch a browser, enter the URL provided in the message and authenticate using the code.<\/li>\n<\/ul>\n<p><img decoding=\"async\" style=\"width: 573px; height: 572px;\" src=\"https:\/\/www.insentragroup.com\/wp-content\/uploads\/sites\/20\/2021\/02\/ansible_img_1.jpg\" alt=\"\" data-udi=\"umb:\/\/media\/5f4b481ae307412eaf0de5fe139386a5\"><\/p>\n<p style=\"text-align: justify;\"><span>Once you click \u201cContinue\u201d, you will be taken to the portal.azure.com or login.microsoftonline.com. Authenticate using your azure credentials and \u2026 it\u2019s done. Now you have the az superpowers. In the console you should expect something like:<\/span><\/p>\n<p style=\"text-align: justify;\"><span>[<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201ccloudName\u201d: \u201cAzureCloud\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\u201cid\u201d: \u201ce0254def-0000-00000-9743-54ed0fd77d58\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201cisDefault\u201d: true,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201cname\u201d: \u201cPay-As-You-Go\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201cstate\u201d: \u201cEnabled\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u201ctenantId\u201d: \u201c00000000-39c2-4f1f-0000-8642e83b92b1\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u201cuser\u201d: {<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u201cname\u201d: \u201cname@outlook.com\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201ctype\u201d: \u201cuser\u201d<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<\/span><br \/>\n<span>]<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>7. It is now time to configure the credentials for ansible[azure]. More information about this can be found here: https:\/\/docs.ansible.com\/ansible\/devel\/scenario_guides\/guide_azure.html<\/strong><\/p>\n<p style=\"text-align: justify;\">Assuming you like to do everything from \u2018root\u2019, the credentials will be created for this user. If you do not assume superpowers, create the credentials file under the $HOME\/.azure\/credentials. ?<\/p>\n<p style=\"text-align: justify;\">The credentials file has the following format:<\/p>\n<p style=\"text-align: justify;\"><span>[default]<br \/>\nsubscription_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br \/>\nclient_id=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<br \/>\nsecret=xxxxxxxxxxxxxxxxx<br \/>\ntenant=xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx<\/span><\/p>\n<p style=\"text-align: justify;\"><span>The idea is to find all the elements identified in the credentials file. Microsoft or Ansible folks did not make it easy and none of the parameters specified in the file matches the name in the azure portal configuration.<\/span><\/p>\n<p style=\"text-align: justify;\"><span>Let\u2019s start with the subscription_id. This is probably the easiest part to find, however requires some searching. ?<\/span><\/p>\n<p><strong>8. Log in to the portal.azure.com<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>9. Verify if you have rights to actually do anything with Ansible. To verify that, click on the \u2018Azure Active Directory\u2019:<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong><img decoding=\"async\" style=\"width: 357px; height: 902px;\" src=\"https:\/\/www.insentragroup.com\/wp-content\/uploads\/sites\/20\/2021\/02\/ansible_azure_img2.jpg\" alt=\"\" data-udi=\"umb:\/\/media\/9cdb7e1a12b142d5885e571d95f21111\"><\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>10. In the Azure Active Directory, click on \u2018User Settings\u2019 and verify if you can select \u2018Yes\u2019 for \u2018users can register applications\u2019:<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong><img decoding=\"async\" style=\"width: 622px; height: 517px;\" src=\"https:\/\/www.insentragroup.com\/wp-content\/uploads\/sites\/20\/2021\/02\/ansible_azure_img3.jpg\" alt=\"\" data-udi=\"umb:\/\/media\/3a5064098bbb41debc8ccd036148fb7a\"><\/strong><\/p>\n<p style=\"text-align: justify;\"><span>If you cannot select \u2018Yes\u2019, that means you do not have permissions and it is time for a little chat with your admin, unless you are \u2018The One\u2019.<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>11. When you are sorted, find the subscription_id and tenant_id for our credentials file. In one of the previous steps we installed \u2018az\u2019 on your machine and if you followed those steps to the letter, you should be already logged in. Now it is enough to run the following to get the required information:<\/strong><\/p>\n<p style=\"text-align: justify;\"><span>az account list -otable \u2013query \u2018[].{subscriptionId: id, name: name, isDefault:&nbsp;<\/span><br \/>\n<span>isDefault, tenantId: tenantId, state: state, cloudName: cloudName}\u2019<\/span><\/p>\n<p>You can expect the following output:<\/p>\n<table border=\"0\">\n<tbody>\n<tr class=\"vc-th\">\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">SubscriptionId<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">Name<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">IsDefault<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">TenantId<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">State<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">CloudName<\/span><\/td>\n<\/tr>\n<tr>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">e0254def-0000-00000-9743-54ed0fd77d58<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">Pay-As-You-Go<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">True<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">7b5ba730-0000-0000-0000-8600e83b92b1<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">Enabled<\/span><\/td>\n<td class=\"vc_table_cell\"><span class=\"vc_table_content\">AzureCloud<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>12. Grab the SubscriptionId and TenantID and copy them to your credentials file.<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>13. The last step is to get client_id and secret\u2026 to do that, just use the following command:<\/strong><\/p>\n<p style=\"text-align: justify;\"><span>az ad sp create-for-rbac \u2013query \u2018{\u201cclient_id\u201d: appId, \u201csecret\u201d: password,&nbsp;<br \/>\n\u201ctenant\u201d: tenant}\u2019<\/span><\/p>\n<p style=\"text-align: justify;\"><span>{<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u201cclient_id\u201d: \u201c1139aa32-0000-0000-0000-1230000850b7\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \u201csecret\u201d: \u201c84655b60-0000-0000-0000-200007960000\u201d,<\/span><br \/>\n<span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\u201ctenant\u201d: \u201c7b5ba730-0000-0000-0000-8600e83b92b1\u201d<\/span><br \/>\n<span>}<\/span><\/p>\n<p style=\"text-align: justify;\"><strong>14. Update your credentials file and we are ready to run some ansible.<\/strong><\/p>\n<p style=\"text-align: justify;\"><strong>15. The following are ansible playbooks that perform a few tasks. Firstly, I put all the variable into the variables section to easily modify the content. There are also a few other details that need to be addressed.<\/strong><\/p>\n<ul>\n<li style=\"text-align: justify;\">The inventory file is not necessary as ansible is using the local azure api to run all the modules. As a result, both hosts and connections are set to localhost and local respectively.<\/li>\n<li style=\"text-align: justify;\">The playbook creates the following azure objects:\n<ul>\n<li>Resource Group<\/li>\n<li>Vvirtual network<\/li>\n<li>Ssubnet<\/li>\n<li>Public IP<\/li>\n<li>Ssecurity group<\/li>\n<li>NIC<\/li>\n<li>Load Balancer<\/li>\n<li>Vvirtual machine<\/li>\n<\/ul>\n<\/li>\n<li>The playbook is using tags to create everything<\/li>\n<li style=\"text-align: justify;\">The playbook is using tags to forcibly remove the entire resource group\u2026 so be careful what you remove. The playbook will not ask twice ?<\/li>\n<li style=\"text-align: justify;\">If you do not specify any tags, all the tasks will be run, and the resource group will be removed at the end.<\/li>\n<li style=\"text-align: justify;\">I added two playbooks below. The first playbook creates the configuration with the loadbalancer. Another one creates everything with the VM machine connected to the public IP, so you can log in using SSH from the outside<\/li>\n<li style=\"text-align: justify;\">If you create the playbook, called playbook.yml and want to create something, run the following:<\/li>\n<\/ul>\n<p><span>ansible-playbook playbook.yml \u2013tags create<\/span><\/p>\n<ul>\n<li style=\"text-align: justify;\">If you create the playbook, called playbook.yml and want to remove everything, run the following:<\/li>\n<\/ul>\n<p style=\"text-align: justify;\"><span>o If you create the playbook, called playbook.yml and want to remove everything, run the following:<\/span><\/p>\n<p class=\"P-BodyText\"><span>Playbook with the loadbalancer:<\/span><\/p>\n<p>\u2014<\/p>\n<p>\u2013 name: Create Azure VM<\/p>\n<p>hosts: localhost<\/p>\n<p>connection: local<\/p>\n<p>vars:<\/p>\n<p>\u2013 reg_grp: rg-austeast-web1<\/p>\n<p>\u2013 reg_grp_location: australiaeast<\/p>\n<p>\u2013 virt_net: vnet-web01<\/p>\n<p>\u2013 virt_net_prefix: \u201c192.168.0.0\/16\u201d<\/p>\n<p>\u2013 subnet_name: subnet-web1<\/p>\n<p>\u2013 subnet_net_prefix: \u201c192.168.1.0\/24\u201d<\/p>\n<p>\u2013 public_ip_name: pub-ip-web1<\/p>\n<p>\u2013 sec_grp_name: nsg-web1<\/p>\n<p>\u2013 virt_inst_size: Standard_D2s_v3<\/p>\n<p>\u2013 vm_user_name: \u201cyour_username\u201d<\/p>\n<p>\u2013 vm_user_pass: \u201cyour_password\u201d<\/p>\n<p>\u2013 image_offer_name: CentOS<\/p>\n<p>\u2013 image_publisher: OpenLogic<\/p>\n<p>\u2013 image_sku: \u20187.5\u2019<\/p>\n<p>\u2013 virt_instance_name: azure-web1<\/p>\n<p>tasks:<\/p>\n<p>\u2013 name: Create Resource Group<\/p>\n<p>azure_rm_resourcegroup:<\/p>\n<p>name: \u201c{{ reg_grp }}\u201d<\/p>\n<p>location: \u201c{{ reg_grp_location }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create VNET<\/p>\n<p>azure_rm_virtualnetwork:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ virt_net }}\u201d<\/p>\n<p>address_prefixes: \u201c{{ virt_net_prefix }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create subnet<\/p>\n<p>azure_rm_subnet:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ subnet_name }}\u201d<\/p>\n<p>address_prefix: \u201c{{ subnet_net_prefix }}\u201d<\/p>\n<p>virtual_network: \u201c{{ virt_net }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create Public IP<\/p>\n<p>azure_rm_publicipaddress:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>allocation_method: Static<\/p>\n<p>name: \u201c{{ public_ip_name }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create NSG with rules<\/p>\n<p>azure_rm_securitygroup:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ sec_grp_name }}\u201d<\/p>\n<p>rules:<\/p>\n<p>\u2013 name: \u201c{{ sec_grp_name }}-ssh\u201d<\/p>\n<p>protocol: Tcp<\/p>\n<p>destination_port_range: 22<\/p>\n<p>access: Allow<\/p>\n<p>priority: 1000<\/p>\n<p>direction: Inbound<\/p>\n<p>\u2013 name: \u201c{{ sec_grp_name }}-http\u201d<\/p>\n<p>protocol: Tcp<\/p>\n<p>destination_port_range: 80<\/p>\n<p>access: Allow<\/p>\n<p>priority: 1001<\/p>\n<p>direction: Inbound<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create a load balancer<\/p>\n<p>azure_rm_loadbalancer:<\/p>\n<p>name: \u201c{{ reg_grp }}-lb1\u201d<\/p>\n<p>location: \u201c{{ reg_grp_location }}\u201d<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public_ip: \u201c{{ public_ip_name }}\u201d<\/p>\n<p>probe_protocol: Tcp<\/p>\n<p>probe_port: 80<\/p>\n<p>probe_interval: 10<\/p>\n<p>probe_fail_count: 3<\/p>\n<p>protocol: Tcp<\/p>\n<p>load_distribution: Default<\/p>\n<p>frontend_port: 80<\/p>\n<p>backend_port: 8080<\/p>\n<p>idle_timeout: 4<\/p>\n<p>natpool_frontend_port_start: 1030<\/p>\n<p>natpool_frontend_port_end: 1040<\/p>\n<p>natpool_backend_port: 80<\/p>\n<p>natpool_protocol: Tcp<\/p>\n<p>backend_address_pools:<\/p>\n<p>\u2013 name: backendpool1<\/p>\n<p>frontend_ip_configurations:<\/p>\n<p>\u2013 name: frontendpool1<\/p>\n<p>public_ip_address: \u201c{{ public_ip_name }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Get facts for one load balancer<\/p>\n<p>azure_rm_loadbalancer_facts:<\/p>\n<p>name: \u201c{{ reg_grp }}-lb1\u201d<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 createnic<\/p>\n<p>\u2013 name: Create NIC<\/p>\n<p>azure_rm_networkinterface:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ reg_grp }}-nic1\u201d<\/p>\n<p>virtual_network: \u201c{{ virt_net }}\u201d<\/p>\n<p>subnet: \u201c{{ subnet_name }}\u201d<\/p>\n<p>security_group: \u201c{{ sec_grp_name }}\u201d<\/p>\n<p>ip_configurations:<\/p>\n<p>\u2013 name: ipconfig1<\/p>\n<p style=\"text-align: justify;\">load_balancer_backend_address_pools: \u201c{{ azure_loadbalancers[0].properties.backendAddressPools[0].id }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 createnic<\/p>\n<p>\u2013 name: Create VM<\/p>\n<p>azure_rm_virtualmachine:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ virt_instance_name }}\u201d<\/p>\n<p>vm_size: \u201c{{ virt_inst_size }}\u201d<\/p>\n<p>admin_username: \u201c{{ vm_user_name }}\u201d<\/p>\n<p>admin_password: \u201c{{ vm_user_pass }}\u201d<\/p>\n<p>ssh_password_enabled: true<\/p>\n<p>network_interfaces: \u201c{{ reg_grp }}-nic1\u201d<\/p>\n<p>image:<\/p>\n<p>offer: \u201c{{ image_offer_name }}\u201d<\/p>\n<p>publisher: \u201c{{ image_publisher }}\u201d<\/p>\n<p>sku: \u201c{{ image_sku }}\u201d<\/p>\n<p>version: latest<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 createvm<\/p>\n<p>\u2013 name: Delete a resource group<\/p>\n<p>azure_rm_resourcegroup:<\/p>\n<p>name: \u201c{{ reg_grp }}\u201d<\/p>\n<p>state: absent<\/p>\n<p>force: yes<\/p>\n<p>tags:<\/p>\n<p>\u2013 remove<\/p>\n<p>Playbook with the VM connected to the public IP:<\/p>\n<p>\u2014<\/p>\n<p>\u2013 name: Create Azure VM<\/p>\n<p>hosts: localhost<\/p>\n<p>connection: local<\/p>\n<p>vars:<\/p>\n<p>\u2013 reg_grp: rg-austeast-web1<\/p>\n<p>\u2013 reg_grp_location: australiaeast<\/p>\n<p>\u2013 virt_net: vnet-web01<\/p>\n<p>\u2013 virt_net_prefix: \u201c192.168.0.0\/16\u201d<\/p>\n<p>\u2013 subnet_name: subnet-web1<\/p>\n<p>\u2013 subnet_net_prefix: \u201c192.168.1.0\/24\u201d<\/p>\n<p>\u2013 public_ip_name: pub-ip-web1<\/p>\n<p>\u2013 sec_grp_name: nsg-web1<\/p>\n<p>\u2013 virt_inst_size: Standard_D2s_v3<\/p>\n<p>\u2013 vm_user_name: your_user<\/p>\n<p>\u2013 vm_user_pass: \u201cyour_password\u201d<\/p>\n<p>\u2013 image_offer_name: CentOS<\/p>\n<p>\u2013 image_publisher: OpenLogic<\/p>\n<p>\u2013 image_sku: \u20187.5\u2019<\/p>\n<p>\u2013 virt_instance_name: azure-web1<\/p>\n<p>tasks:<\/p>\n<p>\u2013 name: Create Resource Group<\/p>\n<p>azure_rm_resourcegroup:<\/p>\n<p>name: \u201c{{ reg_grp }}\u201d<\/p>\n<p>location: \u201c{{ reg_grp_location }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create VNET<\/p>\n<p>azure_rm_virtualnetwork:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ virt_net }}\u201d<\/p>\n<p>address_prefixes: \u201c{{ virt_net_prefix }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create subnet<\/p>\n<p>azure_rm_subnet:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ subnet_name }}\u201d<\/p>\n<p>address_prefix: \u201c{{ subnet_net_prefix }}\u201d<\/p>\n<p>virtual_network: \u201c{{ virt_net }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create Public IP<\/p>\n<p>azure_rm_publicipaddress:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>allocation_method: Static<\/p>\n<p>name: \u201c{{ public_ip_name }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create NSG with rules<\/p>\n<p>azure_rm_securitygroup:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ sec_grp_name }}\u201d<\/p>\n<p>rules:<\/p>\n<p>\u2013 name: \u201c{{ sec_grp_name }}-ssh\u201d<\/p>\n<p>protocol: Tcp<\/p>\n<p>destination_port_range: 22<\/p>\n<p>access: Allow<\/p>\n<p>priority: 1000<\/p>\n<p>direction: Inbound<\/p>\n<p>\u2013 name: \u201c{{ sec_grp_name }}-http\u201d<\/p>\n<p>protocol: Tcp<\/p>\n<p>destination_port_range: 80<\/p>\n<p>access: Allow<\/p>\n<p>priority: 1001<\/p>\n<p>direction: Inbound<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create NIC<\/p>\n<p>azure_rm_networkinterface:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ reg_grp }}-nic1\u201d<\/p>\n<p>virtual_network: \u201c{{ virt_net }}\u201d<\/p>\n<p>subnet: \u201c{{ subnet_name }}\u201d<\/p>\n<p>public_ip_name: \u201c{{ public_ip_name }}\u201d<\/p>\n<p>security_group: \u201c{{ sec_grp_name }}\u201d<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 name: Create VM<\/p>\n<p>azure_rm_virtualmachine:<\/p>\n<p>resource_group: \u201c{{ reg_grp }}\u201d<\/p>\n<p>name: \u201c{{ virt_instance_name }}\u201d<\/p>\n<p>vm_size: \u201c{{ virt_inst_size }}\u201d<\/p>\n<p>admin_username: \u201c{{ vm_user_name }}\u201d<\/p>\n<p>admin_password: \u201c{{ vm_user_pass }}\u201d<\/p>\n<p>ssh_password_enabled: true<\/p>\n<p>network_interfaces: \u201c{{ reg_grp }}-nic1\u201d<\/p>\n<p>image:<\/p>\n<p>offer: \u201c{{ image_offer_name }}\u201d<\/p>\n<p>publisher: \u201c{{ image_publisher }}\u201d<\/p>\n<p>sku: \u201c{{ image_sku }}\u201d<\/p>\n<p>version: latest<\/p>\n<p>tags:<\/p>\n<p>\u2013 create<\/p>\n<p>\u2013 createvm<\/p>\n<p>\u2013 name: Delete a resource group<\/p>\n<p>azure_rm_resourcegroup:<\/p>\n<p>name: \u201c{{ reg_grp }}\u201d<\/p>\n<p>state: absent<\/p>\n<p>force: yes<\/p>\n<p>tags:<\/p>\n<p>\u2013 remove<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently, I have spent significant time trying to use ansible to deploy an azure configuration. There are plenty of websites which describe the individual steps but either I could not find the ONE that encompasses them all or there simply isn\u2019t one. I found this utterly frustrating. So, what did I learn? \u2013 To temper&hellip; <a class=\"more-link\" href=\"https:\/\/www.insentragroup.com\/gb\/insights\/geek-speak\/modern-workplace\/ansible-azure\/\">Continue reading <span class=\"screen-reader-text\">Ansible &#038; Azure<\/span><\/a><\/p>\n","protected":false},"author":67,"featured_media":6862,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"content-type":"","footnotes":""},"categories":[19],"tags":[],"class_list":["post-796","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-workplace","entry"],"_links":{"self":[{"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/posts\/796","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/comments?post=796"}],"version-history":[{"count":1,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/posts\/796\/revisions"}],"predecessor-version":[{"id":6863,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/posts\/796\/revisions\/6863"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/media\/6862"}],"wp:attachment":[{"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/media?parent=796"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/categories?post=796"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.insentragroup.com\/gb\/wp-json\/wp\/v2\/tags?post=796"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}