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

adding plan and container settings to function app #54830

Merged
merged 22 commits into from
Apr 8, 2019
14 changes: 8 additions & 6 deletions lib/ansible/modules/cloud/azure/azure_rm_appserviceplan.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@

try:
from msrestazure.azure_exceptions import CloudError
from msrest.polling import LROPoller
from msrestazure.azure_operation import AzureOperationPoller
from msrest.serialization import Model
from azure.mgmt.web.models import (
Expand Down Expand Up @@ -315,10 +316,11 @@ def get_plan(self):

try:
response = self.web_client.app_service_plans.get(self.resource_group, self.name)
self.log("Response : {0}".format(response))
self.log("App Service Plan : {0} found".format(response.name))
if response:
self.log("Response : {0}".format(response))
self.log("App Service Plan : {0} found".format(response.name))

return appserviceplan_to_dict(response)
return appserviceplan_to_dict(response)
except CloudError as ex:
self.log("Didn't find app service plan {0} in resource group {1}".format(self.name, self.resource_group))

Expand All @@ -340,10 +342,10 @@ def create_or_update_plan(self):
plan_def = AppServicePlan(
location=self.location, app_service_plan_name=self.name, sku=sku_def, reserved=self.is_linux, tags=self.tags if self.tags else None)

poller = self.web_client.app_service_plans.create_or_update(self.resource_group, self.name, plan_def)
response = self.web_client.app_service_plans.create_or_update(self.resource_group, self.name, plan_def)

if isinstance(poller, AzureOperationPoller):
response = self.get_poller_result(poller)
if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's standardize the get poller operation. how about direct get_poller_result?

response = self.get_poller_result(response)

self.log("Response : {0}".format(response))

Expand Down
81 changes: 78 additions & 3 deletions lib/ansible/modules/cloud/azure/azure_rm_functionapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,29 @@
location:
description:
- Valid Azure location. Defaults to location of the resource group.
plan:
description:
- App service plan.
- It can be name of existing app service plan in same resource group as function app.
- "It can be resource id of existing app service plan. eg.,
/subscriptions/<subs_id>/resourceGroups/<resource_group>/providers/Microsoft.Web/serverFarms/<plan_name>"
- It can be a dict which contains C(name), C(resource_group).
- C(name). Name of app service plan.
- C(resource_group). Resource group name of app service plan.
version_added: "2.8"
container_settings:
description: Web app container settings.
suboptions:
name:
description: Name of container. eg. "imagename:tag"
registry_server_url:
description: Container registry server url. eg. mydockerregistry.io
registry_server_user:
description: The container registry server user name.
registry_server_password:
description:
- The container registry server password.
version_added: "2.8"
storage_account:
description:
- Name of the storage account to use.
Expand Down Expand Up @@ -130,12 +153,23 @@

try:
from msrestazure.azure_exceptions import CloudError
from azure.mgmt.web.models import Site, SiteConfig, NameValuePair, SiteSourceControl
from azure.mgmt.web.models import (
site_config, app_service_plan, Site, SiteConfig, NameValuePair, SiteSourceControl,
AppServicePlan, SkuDescription
)
from azure.mgmt.resource.resources import ResourceManagementClient
from msrest.polling import LROPoller
except ImportError:
# This is handled in azure_rm_common
pass

container_settings_spec = dict(
name=dict(type='str', required=True),
registry_server_url=dict(type='str'),
registry_server_user=dict(type='str'),
registry_server_password=dict(type='str', no_log=True)
)


class AzureRMFunctionApp(AzureRMModuleBase):

Expand All @@ -150,7 +184,14 @@ def __init__(self):
type='str',
aliases=['storage', 'storage_account_name']
),
app_settings=dict(type='dict')
app_settings=dict(type='dict'),
plan=dict(
type='raw'
),
container_settings=dict(
type='dict',
options=container_settings_spec
)
)

self.results = dict(
Expand All @@ -164,6 +205,8 @@ def __init__(self):
self.location = None
self.storage_account = None
self.app_settings = None
self.plan = None
self.container_settings = None

required_if = [('state', 'present', ['storage_account'])]

Expand Down Expand Up @@ -213,10 +256,28 @@ def exec_module(self, **kwargs):
else:
self.results['changed'] = False
else:
kind = 'functionapp'
linux_fx_version = None
if self.container_settings and self.container_settings.get('name'):
kind = 'functionapp,linux,container'
linux_fx_version = 'DOCKER|'
if self.container_settings.get('registry_server_url'):
self.app_settings['DOCKER_REGISTRY_SERVER_URL'] = 'https://' + self.container_settings['registry_server_url']
linux_fx_version += self.container_settings['registry_server_url'] + '/'
linux_fx_version += self.container_settings['name']
if self.container_settings.get('registry_server_user'):
self.app_settings['DOCKER_REGISTRY_SERVER_USERNAME'] = self.container_settings.get('registry_server_user')

if self.container_settings.get('registry_server_password'):
self.app_settings['DOCKER_REGISTRY_SERVER_PASSWORD'] = self.container_settings.get('registry_server_password')

if not self.plan and function_app:
self.plan = function_app.server_farm_id

if not exists:
function_app = Site(
location=self.location,
kind='functionapp',
kind=kind,
site_config=SiteConfig(
app_settings=self.aggregated_app_settings(),
scm_type='LocalGit'
Expand All @@ -226,6 +287,20 @@ def exec_module(self, **kwargs):
else:
self.results['changed'], function_app = self.update(function_app)

# get app service plan
if self.plan:
if isinstance(self.plan, dict):
self.plan = "/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Web/serverfarms/{2}".format(
self.subscription_id,
self.plan.get('resource_group', self.resource_group),
self.plan.get('name')
)
function_app.server_farm_id = self.plan

# set linux fx version
if linux_fx_version:
function_app.site_config.linux_fx_version = linux_fx_version

if self.check_mode:
self.results['state'] = function_app.as_dict()
elif self.results['changed']:
Expand Down
68 changes: 54 additions & 14 deletions test/integration/targets/azure_rm_functionapp/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
- name: Fix resource prefix
set_fact:
fixed_resource_prefix: "{{ (resource_prefix | replace('-','x'))[-22:] }}"
fixed_resource_prefix: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"

- name: Fix resource prefix
set_fact:
funcapp_name_basic: "fa{{ fixed_resource_prefix }}basic"
funcapp_name_container: "fa{{ fixed_resource_prefix }}container"
funcapp_name_params: "fa{{ fixed_resource_prefix }}params"
storage_account_name: "sa{{ fixed_resource_prefix }}"
plan_name: "ap{{ fixed_resource_prefix }}"

- name: create storage account for function apps
azure_rm_storageaccount:
resource_group: '{{ resource_group }}'
name: sa{{ fixed_resource_prefix }}
name: "{{ storage_account_name }}"
account_type: Standard_LRS

- name: create basic function app
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}
storage_account: sa{{ fixed_resource_prefix }}
resource_group: "{{ resource_group }}"
name: "{{ funcapp_name_basic }}"
storage_account: "{{ storage_account_name }}"
register: output

- name: assert the function was created
Expand All @@ -22,19 +30,19 @@
- name: list facts for function
azure_rm_functionapp_facts:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}
name: "{{ funcapp_name_basic }}"
register: results

- name: assert the facts were retrieved
assert:
that:
- results.ansible_facts.azure_functionapps|length == 1
- results.ansible_facts.azure_functionapps[0].name == 'af{{ fixed_resource_prefix }}'
- results.ansible_facts.azure_functionapps[0].name == "{{ funcapp_name_basic }}"

- name: delete basic function app
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}
name: "{{ funcapp_name_basic }}"
state: absent
register: output

Expand All @@ -45,8 +53,8 @@
- name: create a function with app settings
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}x
storage_account: sa{{ fixed_resource_prefix }}
name: "{{ funcapp_name_params }}"
storage_account: "{{ storage_account_name }}"
app_settings:
hello: world
things: more stuff
Expand All @@ -60,8 +68,8 @@
- name: change app settings
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}x
storage_account: sa{{ fixed_resource_prefix }}
name: "{{ funcapp_name_params }}"
storage_account: "{{ storage_account_name }}"
app_settings:
hello: world
things: more stuff
Expand All @@ -76,16 +84,48 @@
- name: delete the function app
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: af{{ fixed_resource_prefix }}x
name: "{{ funcapp_name_params }}"
state: absent
register: output

- name: assert the function was deleted
assert:
that: output.changed

- name: Create a linux app service plan
azure_rm_appserviceplan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
sku: S1
is_linux: true
number_of_workers: 1

- name: "Create azure function app {{ function_app }}"
azure_rm_functionapp:
resource_group: "{{ resource_group }}"
name: "{{ funcapp_name_container }}"
storage_account: "{{ storage_account_name }}"
plan:
resource_group: "{{ resource_group }}"
name: "{{ plan_name }}"
container_settings:
name: httpd
app_settings:
FUNCTIONS_EXTENSION_VERSION: "~2"
register: output

- name: assert the function was changed
assert:
that: output.changed

- name: delete the function app
azure_rm_functionapp:
resource_group: '{{ resource_group }}'
name: "{{ funcapp_name_container }}"
state: absent

- name: delete storage account
azure_rm_storageaccount:
resource_group: '{{ resource_group }}'
name: sa{{ fixed_resource_prefix }}
name: "{{ storage_account_name }}"
state: absent