Client gave us controlled Azure Subscriptions where we are
not able to create anything manually using Azure portal. Client’s Dev team has
setup Ansible and some roles to work with Azure Resources (e.g. there are roles
to create logic apps, storage account, service bus, azure function etc.). In
order to create/modify any resource in Azure, we have to use pre-defined
Ansible roles.
Development team has a requirement to use Azure Storage Table in the code. There
is no role available in client’s Ansible Role repository to create storage
account.
REST API Approach
To create storage table, there are REST APIs, which we can
use, but problem with REST API is that we need to have Authorization Header in
the request, and in order to get the authorization header, we need to
authenticate using Storage Account connection string. Since we have controlled
environments, storage account connection strings (which are stored in Key Vault
as Secrets) are not accessible to everyone and we cannot use the sensitive information
like Key in the code.
Even after creating the Authorization for REST APIs, we were
getting the following error while making a REST API call to create Azure storage
table:
"msg": "Status code was 403 and
not [200]: HTTP Error 403: Server failed to authenticate the request. Make sure
the value of Authorization header is formed correctly including the
signature."
Ansible Approach
Ansible has predefined modules for Azure available to work
with Azure resources e.g. in our case, we used TableService. We created a
python module, which creates the Azure Storage table for us using Table
Services.
Following is the code snippet for the module
from azure.storage.table import TableService
def create_azure_table_using_symmetric_key(data):
account_key = data['account_key']
account_name = data['account_name']
table_name = data['table_name']
table_service = TableService(account_name, account_key)
table_service.create_table(table_name)
return False, {'status': True }
def main():
module = AnsibleModule(
argument_spec=dict(
account_key=dict(required=True, type='str'),
account_name=dict(required=True, type='str'),
table_name=dict(required=True, type='str'),
)
)
is_error, result = create_azure_table_using_symmetric_key(module.params)
if not is_error:
module.exit_json(changed=False, meta=result)
else:
module.fail_json(msg="Error creating Azure Storage Table", meta=result)
Following is the playbook we used in Ansible:
- name: Get Storage Account Key to enable SAS
token generation
include_role:
name: ansible-role-azure-keyvault-secrets
vars:
azure_keyvault_secrets:
- name: "{{ azure_storage_acc_key_secretname }}"
- name: Create Azure Storage Table
create_table:
account_key: "{{
kvsecrets[azure_storage_acc_key_secretname] }}"
account_name: "{{ azure_storage_acc_name }}"
table_name: "{{ azure_storage_table_name }}"
here we are fetching a secret from
KeyVault using another Ansible role and calling create_table module created
above.
Thanks for the your useful post, its really helpful for others. Continue your good work.
ReplyDeleteWhat is Rest API? Rest API Explained with Examples | Rest API Tutorial for Beginners