Restructured folders and various content edits

This commit is contained in:
Pui Chee Chan 2019-10-25 12:01:01 -07:00
Родитель c85d48213e
Коммит 1b4e97505a
20 изменённых файлов: 531 добавлений и 87 удалений

Просмотреть файл

Просмотреть файл

@ -153,7 +153,7 @@ localhost : ok=3 changed=1 unreachable=0 failed=0 s
Congratulations, you have created your first playbook. Go to [Azure portal](https://portal.azure.com) to verify that you have created the resources.
> **CODE**: You can refer to [lab1.yml](lab1.yml) for a complete sample playbook.
> **CODE**: You can refer to [lab1.yml](Code/lab1.yml) for a complete sample playbook.
## Further readings

Просмотреть файл

Просмотреть файл

@ -144,13 +144,11 @@ Expand to see how you can create a VM using SSH key to access the host.
version: latest
```
</details>
You can go to [Azure portal](https://portal.azure.com) to verify that you have created the resources.
> **CODE**: To view all of the completed code for this part of the lab, go [here](lab2.yml).
> **CODE**: To view all of the completed code for this part of the lab, go [here](code/lab2.yml).
## Registering variables and working with conditionals
@ -227,6 +225,6 @@ mySubNet: "{{ myVnet }}Subnet"
> - right clicking vars.yml and select **"Upload to Cloud Shell"**.
> - in Cloud Shell terminal, move the file to ./clouddrive/ansible-playbooks/ by doing `mv vars.yml ./clouddrive/ansible-playbooks/`
> **CODE**: The [Code](../03-Helpers/Lab3/Code) folder in **Lab #3 - 03-Helpers** contains the sample playbook and vars.yml you can refer to.
> **CODE**: The [/Code/Code_vars_files](../03-Helpers/Code/Code-vars_files) folder in **Lab #3 - 03-Helpers** contains the sample playbook and vars.yml you can refer to.
- Refer to [Ansible documentation](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html) for more details and ways to use variables.

Просмотреть файл

Просмотреть файл

@ -144,6 +144,4 @@ Expand to see how you use loop to create the NSG rules
```
</details>
> **CODE**: To view all of the completed codes, go to [lab3.yml](lab3.yml).
**<TODO - add excape hatches for Azure modules>**
> **CODE**: To view all of the completed codes, go to [lab3.yml](code/lab3.yml).

Просмотреть файл

@ -5,7 +5,7 @@
---
- hosts: localhost
vars:
keyvault_name: myKeyVault
keyvault_name: mykeyvaul
secret_name: myVMSecret
roles:
- ./modules

Просмотреть файл

@ -7,7 +7,7 @@
myNetworkSecurityGroup: myNSG
myNIC: myNIC
myVM: myVM
mylist:
NSGlist:
- name: Allow-SSH
access: Allow
protocol: Tcp
@ -67,7 +67,7 @@
destination_port_range: "{{ item.port }}"
priority: "{{ item.priority }}"
source_address_prefix: "{{ item.source_address_prefix }}"
loop: "{{ mylist }}"
loop: "{{ NSGlist }}"
- name: Create virtual network interface card(NIC)
azure_rm_networkinterface:

Просмотреть файл

@ -37,7 +37,7 @@ While preparing for this workshop, we discovered we do not have a module for ret
We will be adding a new module called azure_rm_keyvaultsecret_info in future release. For the purpose of this lab, we will embed the new module using the `roles` keyword. (Roles will be explained in Lab 5.)
1. Copy `azure_rm_keyvaultsecret_info.py` in `modules/library`(/modules/library) to `clouddrive/ansible-playbooks/modules/library`
1. You will perform an extra step in this lab to copy the preview version of azure_rm_keyvaultsecret_info to your environment. Copy `azure_rm_keyvaultsecret_info.py` in `modules/library`(code/modules/library) to `clouddrive/ansible-playbooks/modules/library`. Make sure you keep the same folder structure `modules/library`
2. In the header, add:
```yml
@ -61,7 +61,7 @@ We will be adding a new module called azure_rm_keyvaultsecret_info in future rel
version: 12345
```
#### Cheat Sheet: get secret
### Cheat Sheet: get secret
<details>
<summary>
Expand to see how you can get a key vault secret
@ -80,19 +80,21 @@ Expand to see how you can get a key vault secret
</details>
> **CODE**: To view all of the completed codes, go to [lab4-keyvault.yml](lab4-keyvault.yml).
> **CODE**: To view all of the completed codes, go to [lab4-keyvault.yml](Code/lab4-keyvault.yml).
## Replace hard coded password in previous lab
Next, instead of hard coding the password and exposing a major security risk when provisioning the VM, you can now:
1. Make sure you have already copied `azure_rm_keyvaultsecret_info.py` in `modules/library`(/modules/library) to `clouddrive/ansible-playbooks/modules/library`
2. Run a task to retrieve the secret from Azure Key Vault. **Hint**: use `register output`.
1. Make sure you have already copied `azure_rm_keyvaultsecret_info.py` in `modules/library`(/modules/library) to `clouddrive/ansible-playbooks/modules/library`
2. Run a task to retrieve the secret from Azure Key Vault. **Hint**: use `register output`
3. Use the value retrieved back from key vault to configure the admin password for the VM. **Hint**: use `output.secret.value`
#### Cheat Sheet: get secret
### Cheat Sheet: pass secret retrieved from Key Vault to the next task
<details>
<summary>
Expand to see how you can get a key vault secret
Expand to see how you can pass secret retrieved from Key Vault to the next task
</summary>
```yml
@ -119,7 +121,7 @@ Expand to see how you can get a key vault secret
</details>
> **CODE:** To view all of the completed codes, go to [lab4.yml](lab4.yml).
> **CODE:** To view all of the completed codes, go to [lab4.yml](Code/lab4.yml).
## Further readings

Просмотреть файл

@ -23,7 +23,7 @@
protocol: "{{ item.protocol }}"
destination_port_range: "{{ item.port }}"
priority: "{{ item.priority }}"
direction: " {{ item.direction }}"
direction: "{{ item.direction }}"
source_address_prefix: "{{ item.source_address_prefix }}"
loop: "{{ NSGlist }}"
register: NSG

Просмотреть файл

@ -10,10 +10,6 @@
name: "{{ myVM }}"
admin_username: "testadmin"
admin_password: "{{ output.secret.value }}"
# ssh_password_enabled: false
# ssh_public_keys:
# - path: /home/testadmin/.ssh/authorized_keys
# key_data: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
vm_size: Standard_B1ms
network_interfaces: "{{ NIC.state.name }}"
image:

Просмотреть файл

@ -1,6 +1,6 @@
- hosts: localhost
vars_files:
- ./vars.yml
- vars/vars.yml
roles:
- ./modules
gather_facts: no
@ -28,7 +28,21 @@
subnetAddPrefix: "172.16.10.0/24"
myNetworkSecurityGroup: myNSG
myNIC: myNIC
NSGlist: [{ name: 'Allow-SSH', access: 'Allow', protocol: 'Tcp', direction: 'Inbound', priority: '300', port: '22', source_address_prefix: 'Internet'},{ name: 'Allow-HTTP', access: 'Allow', protocol: 'Tcp', direction: 'Inbound', priority: '100', port: '80', source_address_prefix: 'Internet'}]
NSGlist:
- name: Allow-SSH
access: Allow
protocol: Tcp
direction: Inbound
priority: 300
port: 22
source_address_prefix: Internet
- name: Allow-HTTP
access: Allow
protocol: Tcp
direction: Inbound
priority: 100
port: 80
source_address_prefix: Internet
include_tasks: ./confignetwork.yml
# - name: Show NIC details
@ -48,7 +62,28 @@
subnetAddPrefix: "172.16.20.0/24"
myNetworkSecurityGroup: myNSG-BE
myNIC: myNIC-BE
NSGlist: [{ name: 'Allow-SSH', access: 'Allow', protocol: 'Tcp', direction: 'Inbound', priority: '200', port: '22', source_address_prefix: 'Internet'},{ name: 'Allow-MySQL-FE', access: 'Allow', protocol: 'Tcp', direction: 'Inbound', priority: '100', port: '3306', source_address_prefix: '172.16.10.0/24'}, { name: 'Deny-internet-all', access: 'Deny', protocol: 'Tcp', direction: 'Outbound', priority: '300', port: '*', source_address_prefix: '*'}]
NSGlist:
- name: Allow-SSH
access: Allow
protocol: Tcp
direction: Inbound
priority: 200
port: 22
source_address_prefix: Internet
- name: Allow-MySQL-FE
access: Allow
protocol: Tcp
direction: Inbound
priority: 100
port: 3306
source_address_prefix: 172.16.10.0/24
- name: Deny-internet-all
access: Allow
protocol: Tcp
direction: Outbound
priority: 300
port: "*"
source_address_prefix: "*"
include_tasks: ./confignetwork.yml
# - name: Show NIC details

Просмотреть файл

@ -0,0 +1,202 @@
#!/usr/bin/python
#
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: azure_rm_keyvaultkey_info
version_added: "2.9"
short_description: Get Azure Key Vault secret facts.
description:
- Get facts of Azure Key Vault secret.
options:
vault_uri:
description:
- Vault uri where the secret stored in.
required: True
type: str
name:
description:
- secret name.
required: True
type: str
version:
description:
- secret version.
default: current (latest)
type: str
extends_documentation_fragment:
- azure
'''
EXAMPLES = '''
- name: Get latest version of a secret
azure_rm_keyvaultsecret_info::
vault_uri: "https://myVault.vault.azure.net"
name: mysecret
- name: Get a specific version of a secret
azure_rm_keyvaultsecret_info:
vault_uri: "https://myVault.vault.azure.net"
name: mysecret
version: 12345
'''
from ansible.module_utils.azure_rm_common import AzureRMModuleBase
try:
from azure.keyvault import KeyVaultClient, KeyVaultId, KeyVaultAuthentication, KeyId
from azure.keyvault.models import KeyAttributes, JsonWebKey
from azure.common.credentials import ServicePrincipalCredentials
from azure.keyvault.models.key_vault_error import KeyVaultErrorException
from msrestazure.azure_active_directory import MSIAuthentication
except ImportError:
# This is handled in azure_rm_common
pass
def keyitem_to_dict(keyitem):
return dict(
id=keyitem.id,
value=keyitem.value,
version=KeyVaultId.parse_secret_id(keyitem.id).version,
manged=keyitem.managed,
attributes=dict(
enabled=keyitem.attributes.enabled,
not_before=keyitem.attributes.not_before,
expires=keyitem.attributes.expires,
created=keyitem.attributes.created,
updated=keyitem.attributes.updated,
recovery_level=keyitem.attributes.recovery_level
)
)
class AzureRMKeyVaultSecretInfo(AzureRMModuleBase):
def __init__(self):
self.module_arg_spec = dict(
version=dict(type='str', default='current'),
name=dict(type='str', required=True),
vault_uri=dict(type='str', required=True),
tags=dict(type='list')
)
self.vault_uri = None
self.name = None
self.version = None
self.tags = None
self.results = dict(changed=False)
self._client = None
super(AzureRMKeyVaultSecretInfo, self).__init__(derived_arg_spec=self.module_arg_spec,
supports_check_mode=False,
supports_tags=False)
def exec_module(self, **kwargs):
"""Main module execution method"""
for key in list(self.module_arg_spec.keys()):
if hasattr(self, key):
setattr(self, key, kwargs[key])
self._client = self.get_keyvault_client()
versions = self.get_secret_versions()
# self.results['versions'] = versions
if self.version == 'current':
self.version = versions[-1]
secret = self.get_secret()
self.results['secret'] = keyitem_to_dict(secret)
return self.results
def get_keyvault_client(self):
try:
self.log("Get KeyVaultClient from MSI")
credentials = MSIAuthentication(resource='https://vault.azure.net')
return KeyVaultClient(credentials)
except Exception:
self.log("Get KeyVaultClient from service principal")
# Create KeyVault Client using KeyVault auth class and auth_callback
def auth_callback(server, resource, scope):
if self.credentials['client_id'] is None or self.credentials['secret'] is None:
self.fail('Please specify client_id, secret and tenant to access azure Key Vault.')
tenant = self.credentials.get('tenant')
if not self.credentials['tenant']:
tenant = "common"
authcredential = ServicePrincipalCredentials(
client_id=self.credentials['client_id'],
secret=self.credentials['secret'],
tenant=tenant,
cloud_environment=self._cloud_environment,
resource="https://vault.azure.net")
token = authcredential.token
return token['token_type'], token['access_token']
return KeyVaultClient(KeyVaultAuthentication(auth_callback))
def get_secret(self):
'''
Gets the properties of the specified key in key vault.
:return: deserialized key state dictionary
'''
self.log("Get the key {0}".format(self.name))
response = None
try:
response = self._client.get_secret(vault_base_url=self.vault_uri, secret_name=self.name, secret_version=self.version)
except KeyVaultErrorException as e:
self.log("Did not find the key vault secret {0}: {1}".format(self.name, str(e)))
return response
def get_secret_versions(self):
'''
Lists secret versions.
:return: deserialized versions of secrets, includes key identifier, attributes and tags
'''
self.log("Get the secret versions {0}".format(self.name))
versions = []
try:
response = self._client.get_secret_versions(vault_base_url=self.vault_uri, secret_name=self.name)
self.log("Response : {0}".format(response))
if response:
for item in response:
version = KeyVaultId.parse_secret_id(item.id).version
versions.append(version)
except KeyVaultErrorException as e:
self.log("Did not find secret versions {0} : {1}.".format(self.name, str(e)))
return versions
def main():
"""Main execution"""
AzureRMKeyVaultSecretInfo()
if __name__ == '__main__':
main()

Просмотреть файл

@ -0,0 +1,5 @@
myResource_group: myResource_group
myVnet: myVnet
keyvault_name: mykeyvault
secret_name: myVMSecret
myVM: myVM

Просмотреть файл

@ -15,86 +15,167 @@ Running playbooks in Cloud Shell presents a couple of limitations:
- you can only upload file to Cloud Shell one by one
- after uploading to Cloud Shell, you need to perform an additional step to move files uploaded to the right location.
It can become cumbersome to continue running your playbook in Cloud Shell.
It can become cumbersome to continue running your playbooks in Cloud Shell.
The VS Code Ansible extension provides better integration experience when you need to work with multiple files so we recommend running Ansible in the remote host via SSH. You can hit `F1` to copy files to remote host.
1. Hit `F1`; type "Ansible: copy folder to Remote Host"
1. Follow the prompt to provide the source directory
1. Select "Set up host" if this is the first time. Else select your remote host
1. Next specify the target folder
1. Select "Set up host" if this is the first time. Else select your remote host from the list of remote hosts.
1. Next, specify the target folder
## Reusing task(s) in your playbook
You can use the [include](https://docs.ansible.com/ansible/latest/modules/include_module.html) and [include_tasks](https://docs.ansible.com/ansible/latest/modules/include_tasks_module.html#include-tasks-module) modules to dynamically include a task or a list of tasks.
Let's modify what you have done so far to create a multi-tier application.
Let's modify what you have done so far to create a network of multi-tier applications based on this [Azure CLI sample](https://docs.microsoft.com/en-us/azure/virtual-network/scripts/virtual-network-cli-sample-multi-tier-application).
Based on the Azure CLI sample, let's build a [network of multi-tier applications](https://docs.microsoft.com/en-us/azure/virtual-network/scripts/virtual-network-cli-sample-multi-tier-application).
- a virtual network (172.16.0.0/16) with front-end and back-end subnets
- two virtual machines: web and MySQL; one in each subnet
- a virtual network (172.16.0.0/16) with front-end (172.16.10.0/24) and back-end (176.16.20.0/24) subnets:
- Traffic to the front-end subnet is limited to HTTP and SSH
- Traffic to the back-end subnet is limited to MySQL, port 3306 and SSH. All outbound traffic from the back-end subnet should be blocked.
- two virtual machines, one in each subnet
![Sample multi-tier applications](../../Terraform/05%20-%20Reusability/Assets/labnet.png "Azure resources to be provisioned.")
What you have done so far:
- A VNet 172.16.0.0/16
- A front-end subnet - 172.16.10.0/24 with NSG rules that allow:
- SSH traffic from the Internet to the front-end subnetSSH on port 22
- HTTP traffic in from the Internet to the front-end subnet on port 80
- And a VM in the front-end subnet that can act as the front-end web server
- A front-end subnet - 172.16.10.0/24 with NSG rules that:
- allows SSH traffic from the Internet to the front-end subnet on port 22
- allows HTTP traffic in from the Internet to the front-end subnet on port 80
- And a VM in the front-end subnet that acts as the front-end web server
You need to add:
- A backend subnet 172.16.20/24 with NSG rules that:
- allows SSH traffic from the Internet to the front-end subnet on port 22
- allows MySQL traffic from the front-end subnet to the back-end subnet on port 3306
- blocks all outbound traffic from the back-end subnet to the Internet
- A VM in the back-end subnet.
![Sample multi-tier applications](../../Terraform/05%20-%20Reusability/Assets/labnet.png "Azure resources to be provisioned.")
- A VM (MySQL) in the back-end subnet.
Let's start by restructuring your playbook and break the tasks out into a few playbooks.
1. Move all common tasks related to subnet configuration to one YAML file say configurenetwork.yml so that you can use the same list of tasks to provision and configure the subnet, public IP etc. networking related tasks.
1. Move all common tasks related to network configuration to one YAML file say `configurenetwork.yml` so that you can use the same list of tasks to provision and configure the subnet, public IP etc. networking related tasks.
```yml
- name: Create a subset within the virtual network
azure_rm_subnet:
...
register: subnet
- name: Create public IP address
azure_rm_publicipaddress:
...
register: publicIP
- name: Create Network Security Group
azure_rm_securitygroup:
...
loop: "{{ NSGlist }}"
register: NSG
- name: Create virtual network interface card(NIC) with public IP
azure_rm_networkinterface:
...
register: NIC
```
>**Note**: you can register a variable after each task and use "debug" to show the output. By doing so, you can also refer to value in the Azure resource by using e.g., `"{{ NIC.state.name }}"` in subsequent task.
For example:
```yml
- name: Show NIC details
debug:
var: NIC
```
### Cheat Sheet: confignetwork.yml
<details>
<summary>
Expand to see confignetwork.yml
</summary>
```yml
- name: Create a subset within the virtual network
azure_rm_subnet:
...
resource_group: "{{ myResource_group }}"
virtual_network_name: "{{ myVnet }}"
name: "{{ myVnetSubNet }}"
address_prefix_cidr: "{{ subnetAddPrefix }}"
register: subnet
- name: Create public IP address
azure_rm_publicipaddress:
...
resource_group: "{{ myResource_group }}"
allocation_method: Static
name: "{{ myPublicIP }}"
register: publicIP
- name: Create Network Security Group
azure_rm_securitygroup:
...
resource_group: "{{ myResource_group }}"
name: "{{ myNetworkSecurityGroup}}"
rules:
- name: "Allow-{{ item.name }}"
access: "{{ item.access }}"
protocol: "{{ item.protocol }}"
destination_port_range: "{{ item.port }}"
priority: "{{ item.priority }}"
direction: " {{ item.direction }}"
source_address_prefix: "{{ item.source_address_prefix }}"
loop: "{{ NSGlist }}"
register: NSG
- name: Create virtual network interface card(NIC) with public IP
azure_rm_networkinterface:
...
resource_group: "{{ myResource_group }}"
name: "{{ myNIC }}"
virtual_network: "{{ myVnet }}"
subnet: "{{ myVnetSubNet }}"
ip_configurations:
- name: ipconfig
public_ip_address_name: "{{ myPublicIP }}"
security_group: "{{ myNetworkSecurityGroup }}"
register: NIC
```
>**Note**: you can register a variable after each task and use "debug" to show the output. By doing so, you can also refer to value in the Azure resource by using e.g., `"{{ NIC.state.name }}"` in subsequent task.
For example:
```yml
- name: Show NIC details
debug:
var: NIC
```
</details>
2. Move the task to create the VM to a file called `createvm.yml`. Let's add an additional configuration (a tag) to each VM.
- For the front-end, add a tag by setting `tags: "Ansible=web"`
- For the back-end, add a tag by setting `tags: "Ansible=MySQL"`
### Cheat Sheet: createvm.yml
<details>
<summary>
Expand to see createvm.yml
</summary>
```yml
- name: Get latest version of a secret
azure_rm_keyvaultsecret_info:
vault_uri: "https://{{ keyvault_name }}.vault.azure.net"
name: "{{ secret_name }}"
register: output
- name: Create a virtual machines
azure_rm_virtualmachine:
resource_group: "{{ myResource_group }}"
name: "{{ myVM }}"
admin_username: "testadmin"
admin_password: "{{ output.secret.value }}"
vm_size: Standard_B1ms
network_interfaces: "{{ NIC.state.name }}"
image:
offer: UbuntuServer
publisher: Canonical
sku: 16.04-LTS
version: latest
tags: "{{ myTags }}"
```
</details>
3. main.yml will be your main playbook. The structure is similar to this:
```yml
@ -133,7 +214,108 @@ For example:
```
> **CODE**: To view all of the completed codes, go to [lab5](/lab5).
### Cheat Sheet: main.yml
<details>
<summary>
Expand to see a sample of main.yml
</summary>
```yml
- hosts: localhost
vars_files:
- ./vars.yml
roles:
- ./modules
gather_facts: no
tasks:
# ----------------------------------------------------------------------------------
# Start with a resource group so that clean up is easy. This tasks is commented out
# since you cannot create resource group in this workshop.
# ----------------------------------------------------------------------------------
# - name: Create a resource group
# azure_rm_resourcegroup:
# name: "{{ myResource_group }}"
# location: eastus2
- name: Create a virtual network.
azure_rm_virtualnetwork:
resource_group: "{{ myResource_group }}"
name: "{{ myVnet }}"
address_prefixes: "172.16.0.0/16"
- name: Create front-end subnet and NSG rules
vars:
myVnetSubNet: myVnetSubNet
myPublicIP: myPublicIP
subnetAddPrefix: "172.16.10.0/24"
myNetworkSecurityGroup: myNSG
myNIC: myNIC
NSGlist:
- name: Allow-SSH
access: Allow
protocol: Tcp
direction: Inbound
priority: 300
port: 22
source_address_prefix: Internet
- name: Allow-HTTP
access: Allow
protocol: Tcp
direction: Inbound
priority: 100
port: 80
source_address_prefix: Internet
include_tasks: ./confignetwork.yml
- name: Create a front-end virtual machines
vars:
myVM: myVM
myTags: "Ansible=web"
include: ./createvm.yml
- name: Create back-end subnet and NSG rules
vars:
myVnetSubNet: myVnetSubNet-BE
myPublicIP: myPublicIP-BE
subnetAddPrefix: "172.16.20.0/24"
myNetworkSecurityGroup: myNSG-BE
myNIC: myNIC-BE
NSGlist:
- name: Allow-SSH
access: Allow
protocol: Tcp
direction: Inbound
priority: 200
port: 22
source_address_prefix: Internet
- name: Allow-MySQL-FE
access: Allow
protocol: Tcp
direction: Inbound
priority: 100
port: 3306
source_address_prefix: 172.16.10.0/24
- name: Deny-internet-all
access: Allow
protocol: Tcp
direction: Outbound
priority: 300
port: "*"
source_address_prefix: "*"
include_tasks: ./confignetwork.yml
- name: Create a back-end virtual machines
vars:
myVM: myVM-BE
myTags: "Ansible=MySQL"
include: ./createvm.yml
```
</details>
> **CODE**: To view all of the completed codes, go to [lab5](Code).
## Dynamic inventory
@ -153,10 +335,11 @@ include_vm_resource_groups:
keyed_groups:
- prefix: tag
key: tags
```
1. Run the following command to view the populated inventory:
> **CODE**: Go [here](Code/myazure_rm.yml) to see the code.
2. Run the following command to view the populated inventory:
```bash
ansible-inventory -i myazure_rm.yml --graph
@ -164,7 +347,8 @@ ansible-inventory -i myazure_rm.yml --graph
You should see something like this:
```
```output
@all:
|--@tag_Ansible_SQL:
| |--myVM-BE_7ac4
@ -184,15 +368,13 @@ You can test connection to myVM-BE by doing:
ansible -u testadmin -i myazure_rm.yml -m ping tag_Ansible_web -k
```
Likewise, for myVM-FE, run:
```bash
ansible -u testadmin -i myazure_rm.yml -m ping tag_Ansible_MySQL -k
```
>**_Note_**: since the VMs are using userid/password for authentication, you need to add `-k` to the command and provide password used to SSH into the VMs.
>**Note**: since the VMs are using userid/password for authentication, you need to add `-k` to the command and provide password used to SSH into the VMs.
With dynamic inventory, you can run playbook by targeting vm(s) with the specific tag. For instance, if you wish to apply `XXX.yml` to the back-end VM, you can do so by running the command:
@ -211,23 +393,26 @@ To take it one step further, you can create Roles so that you can reuse and furt
Example of project structure:
```yml
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
webservers/
tasks/
defaults/
meta/
```output
testrole
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
└── main.yml
8 directories, 8 files
```
[Ansible Galaxy or Galaxy](https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html), is a free site for finding, downloading, and sharing community developed roles. Downloading roles from Galaxy is a great way to jumpstart your automation projects.
@ -242,8 +427,36 @@ Roles may also include modules and other plugin types. In Lab 4, you saw how we
For further exploration, the [AKS role](https://galaxy.ansible.com/azure/aks) we shared in Ansible Galaxy is a good example on how you can reuse and share common configurations and tasks to provision AKS cluster in your organization.
To create an AKS with monitoring enabled:
1. Install AKS role by doing in your Ansible host
>**Note**: you cannot install roles in CloudShell
```output
ansible-galaxy install azure.aks
```
2. Run this playbook:
```yml
- hosts: localhost
tasks:
- include_role:
name: azure.aks
vars:
monitoring: yes
name: akscluster
resource_group: aksroletest
```
## Further readings
### Roles
- [Ansible Galaxy](https://galaxy.ansible.com)
- [Ansible Roles Explained | Cheat Sheet](https://linuxacademy.com/blog/linux-academy/ansible-roles-explained/)
- [Ansible roles tutorialspoint](https://www.tutorialspoint.com/ansible/ansible_roles.htm)
### Sample playbooks and labs:
- [Ansible playbooks for Azure](https://github.com/Azure-Samples/ansible-playbooks)
- [Ansible Deployment Labs for Microsoft Azure](https://github.com/Microsoft/Ansiblelabs)

Просмотреть файл

@ -1,5 +0,0 @@
myResource_group: myResource_group_pc10
myVnet: myVnet
keyvault_name: pckeyvault10
secret_name: myVMSecret
myVM: myVM