Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support netowrk_acls to azure_rm_keyvault.py #1738

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 102 additions & 2 deletions plugins/modules/azure_rm_keyvault.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,60 @@
description:
- Create vault in recovery mode.
type: bool
public_network_access:
description:
- Property to specify whether the vault will accept traffic from public internet.
type: str
choices:
- Disabled
- Enabled
network_acls:
description:
- A collection of rules governing the accessibility of the vault from specific network locations.
type: dict
suboptions:
bypass:
description:
- Tells what traffic can bypass network rules.
- If not specified the default is 'AzureServices'.
type: str
choices:
- AzureServices
- None
default: AzureServices
default_action:
description:
- The default action when no rule from ipRules and from virtualNetworkRules match.
- This is only used after the bypass property has been evaluated.
type: str
choices:
- Allow
- Deny
ip_rules:
description:
- The list of IP address rules.
type: list
elements: dict
suboptions:
value:
description:
- An IPv4 address range in CIDR notation.
- Such as C(124.56.78.91) (simple IP address) or C(124.56.78.0/24) (all addresses that start with 124.56.78).
type: str
virtual_network_rules:
description:
- The list of virtual network rules.
type: list
elements: dict
suboptions:
id:
description:
- Full resource id of a vnet subnet.
type: str
ignore_missing_vnet_service_endpoint:
description:
- Property to specify whether NRP will ignore the check if parent subnet has serviceEndpoints configured.
type: bool
state:
description:
- Assert the state of the KeyVault. Use C(present) to create or update an KeyVault and C(absent) to delete it.
Expand Down Expand Up @@ -215,7 +269,7 @@
'''

import time
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase
from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt

try:
from azure.core.polling import LROPoller
Expand All @@ -230,7 +284,7 @@ class Actions:
NoAction, Create, Update, Delete = range(4)


class AzureRMVaults(AzureRMModuleBase):
class AzureRMVaults(AzureRMModuleBaseExt):
"""Configuration class for an Azure RM Key Vault resource"""

def __init__(self):
Expand Down Expand Up @@ -305,6 +359,32 @@ def __init__(self):
recover_mode=dict(
type='bool'
),
public_network_access=dict(
type='str',
choices=['Disabled', 'Enabled']
),
network_acls=dict(
type='dict',
options=dict(
bypass=dict(type='str', choices=['AzureServices', 'None'], default='AzureServices'),
default_action=dict(type='str', choices=['Allow', 'Deny']),
ip_rules=dict(
type='list',
elements='dict',
options=dict(
value=dict(type='str'),
)
),
virtual_network_rules=dict(
type='list',
elements='dict',
options=dict(
id=dict(type='str'),
ignore_missing_vnet_service_endpoint=dict(type='bool')
)
)
)
),
state=dict(
type='str',
default='present',
Expand Down Expand Up @@ -343,6 +423,10 @@ def exec_module(self, **kwargs):
self.parameters.setdefault("properties", {})["tenant_id"] = kwargs[key]
elif key == "sku":
self.parameters.setdefault("properties", {})["sku"] = kwargs[key]
elif key == "public_network_access":
self.parameters.setdefault("properties", {})["public_network_access"] = kwargs[key]
elif key == "network_acls":
self.parameters.setdefault("properties", {})["network_acls"] = kwargs[key]
elif key == "access_policies":
access_policies = kwargs[key]
for policy in access_policies:
Expand Down Expand Up @@ -466,6 +550,22 @@ def exec_module(self, **kwargs):
self.to_do = Actions.Update
break

if 'public_network_access' in self.parameters['properties'] and \
self.parameters['properties']['public_network_access'].capitalize() != old_response['properties'].get('public_network_access'):
self.to_do = Actions.Update
else:
self.parameters['properties']['public_network_access'] = old_response['properties'].get('public_network_access')

if old_response['properties'].get('network_acls') is not None:
if old_response['properties']['network_acls'].get('ip_rules') is not None:
old_response['properties']['network_acls']['ip_rules'] = list()
for item in old_response['properties']['network_acls']['ip_rules']:
old_response['properties']['network_acls']['ip_rules'].append(dict(value=item['value'].split('/')[0]))

if not self.default_compare({}, self.parameters['properties'].get('network_acls'),
old_response['properties'].get('network_acls'), '', dict(compare=[])):
self.to_do = Actions.Update

update_tags, newtags = self.update_tags(old_response.get('tags', dict()))

if update_tags:
Expand Down
53 changes: 51 additions & 2 deletions plugins/modules/azure_rm_keyvault_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,48 @@
type: str
returned: always
sample: standard
public_network_access:
description:
- Property to specify whether the vault will accept traffic from public internet.
type: str
returned: always
sample: Disabled
network_acls:
description:
- A collection of rules governing the accessibility of the vault from specific network locations.
returned: always
type: complex
contains:
bypass:
description:
- Tells what traffic can bypass network rules.
type: str
returned: always
sample: AzureServices
default_action:
description:
- The default action when no rule from ipRules and from virtualNetworkRules match.
type: str
returned: always
sample: Allow
ip_rules:
description:
- The list of IP address rules.
type: list
returned: always
sample: [{'value': '124.56.78.91/32'}]
virtual_network_rules:
description:
- The list of virtual network rules.
type: list
returned: always
sample: [{'id': "/subscriptions/**/resourcegroups/**/providers/microsoft.network/virtualnetworks/**/subnets/subnet01",
'ignore_missing_vnet_service_endpoint': True}]
access_policies:
description:
- List of policies.
returned: always
type: list
type: complex
contains:
object_id:
description: The object if of a user, service principal or security group in AAD for the vault.
Expand Down Expand Up @@ -227,7 +264,19 @@ def keyvault_to_dict(vault):
sku=dict(
family=vault.properties.sku.family,
name=vault.properties.sku.name
)
),
public_network_access=vault.properties.public_network_access,
network_acls=dict(
bypass=vault.properties.network_acls.bypass,
default_action=vault.properties.network_acls.default_action,
ip_rules=[dict(
value=item.value
) for item in vault.properties.network_acls.ip_rules] if vault.properties.network_acls.ip_rules else None,
virtual_network_rules=[dict(
id=item.id,
ignore_missing_vnet_service_endpoint=item.ignore_missing_vnet_service_endpoint
) for item in vault.properties.network_acls.virtual_network_rules] if vault.properties.network_acls.virtual_network_rules else None
) if vault.properties.network_acls else None
)


Expand Down
125 changes: 125 additions & 0 deletions tests/integration/targets/azure_rm_keyvault/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,131 @@
- facts['keyvaults'][0]['id'] != None
- facts['keyvaults'][0]['enable_soft_delete'] == true
- facts['keyvaults'][0]['soft_delete_retention_in_days'] == 7

- name: Create virtual network
azure_rm_virtualnetwork:
name: vnet{{ rpfx }}
address_prefixes_cidr:
- 10.1.0.0/16
dns_servers:
- 127.0.0.1
- 127.0.0.3
resource_group: "{{ resource_group }}"

- name: Create network security group
azure_rm_securitygroup:
name: secgroup{{ rpfx }}
resource_group: "{{ resource_group }}"

- name: Create the subnet
azure_rm_subnet:
name: subnet{{ rpfx }}
virtual_network_name: vnet{{ rpfx }}
resource_group: "{{ resource_group }}"
address_prefix_cidr: "10.1.0.0/16"
security_group: secgroup{{ rpfx }}
private_endpoint_network_policies: Enabled
private_link_service_network_policies: Enabled
service_endpoints:
- service: Microsoft.KeyVault
locations:
- eastus
register: subnet_output

- name: Create a secodary instance of Key Vault
azure_rm_keyvault:
resource_group: "{{ resource_group }}"
vault_name: "vault{{ rpfx }}-sec"
enabled_for_deployment: false
vault_tenant: "{{ tenant_id }}"
soft_delete_retention_in_days: 7
public_network_access: "Disabled"
network_acls:
bypass: None
default_action: Allow
ip_rules:
- value: 124.56.78.91
virtual_network_rules:
- id: "{{ subnet_output.state.id }}"
ignore_missing_vnet_service_endpoint: true
sku:
name: standard
family: A
access_policies:
- tenant_id: "{{ tenant_id }}"
object_id: "{{ object_id }}"
secrets:
- get
- list
- set
- delete
- recover
- backup
- restore
register: output

- name: Assert the keyvault created
ansible.builtin.assert:
that: output.changed

- name: Update instance of Key Vault
azure_rm_keyvault:
resource_group: "{{ resource_group }}"
vault_name: "vault{{ rpfx }}-sec"
enabled_for_deployment: false
vault_tenant: "{{ tenant_id }}"
soft_delete_retention_in_days: 7
public_network_access: "Enabled"
network_acls:
bypass: AzureServices
default_action: Deny
ip_rules:
- value: 124.56.78.91
- value: 124.56.78.92
- value: 124.56.78.93
virtual_network_rules:
- id: "{{ subnet_output.state.id }}"
ignore_missing_vnet_service_endpoint: true
sku:
name: standard
family: A
access_policies:
- tenant_id: "{{ tenant_id }}"
object_id: "{{ object_id }}"
secrets:
- get
- list
- set
- delete
- recover
- backup
- restore
register: output

- name: Assert the keyvault Updated
ansible.builtin.assert:
that: output.changed

- name: Get key vault facts
azure_rm_keyvault_info:
resource_group: "{{ resource_group }}"
name: "vault{{ rpfx }}-sec"
register: facts

- name: Assert the facts are properly set
ansible.builtin.assert:
that:
- facts['keyvaults'][0]['public_network_access'] == 'Enabled'
- facts['keyvaults'][0]['network_acls']['bypass'] == 'AzureServices'
- facts['keyvaults'][0]['network_acls']['default_action'] == 'Deny'
- facts['keyvaults'][0]['network_acls']['ip_rules'] | length == 3
- facts['keyvaults'][0]['network_acls']['virtual_network_rules'] | length == 1

- name: Delete the secondary Key Vault
azure_rm_keyvault:
resource_group: "{{ resource_group }}"
vault_name: "vault{{ rpfx }}-sec"
state: absent
#
# azure_rm_keyvaultkey tests
#
Expand Down