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

azure_rm_deployment can't send int type parameter to ARM template #35536

Closed
ilseokoh opened this issue Jan 31, 2018 · 21 comments
Closed

azure_rm_deployment can't send int type parameter to ARM template #35536

ilseokoh opened this issue Jan 31, 2018 · 21 comments
Labels
affects_2.4 This issue/PR affects Ansible v2.4 azure bug This issue/PR relates to a bug. cloud module This issue/PR relates to a module. needs_info This issue requires further information. Please answer any outstanding questions. support:certified This issue/PR relates to certified code.

Comments

@ilseokoh
Copy link

ilseokoh commented Jan 31, 2018

ISSUE TYPE

Bug Report

COMPONENT NAME

lib/ansible/modules/cloud/azure/azure_rm_deployment.py

ANSIBLE VERSION
ansible 2.4.2.0
  config file = None
  configured module search path = [u'/home/kevinoh/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 2.7.12 (default, Dec  4 2017, 14:50:18) [GCC 5.4.0 20160609]
CONFIGURATION

no result

OS / ENVIRONMENT

Ubuntu 16.04.3 LTS

SUMMARY

I want to put the 'int' type parameter value from playbook to arm template parameter.
But there is an error

TASK [world : Create Azure Deploy] *********************************************************************
fatal: [127.0.0.1 -> 127.0.0.1]: FAILED! => {"changed": false, "failed_deployment_operations": [], "msg": "Deployment failed with status code: 400 and message: Deployment template validation failed: 'The provided value for the template parameter 'FieldVMCount' at line '1' and column '1982' is not valid.'."}
STEPS TO REPRODUCE

command line:

$ vmCount=3
ansible-playbook ansible/world.yml --tags create --extra-vars "worldnum=$worldnum intsubaddrprefix=$intsubaddrprefix extsubnameprefix=$extsubnameprefix baseimagename=$baseimagename fieldvmcount=$vmCount"

playbook task

- name: Create Azure Deploy
  azure_rm_deployment:
    state: present
    location: koreacentral
    resource_group_name: RG-krz-world{{ worldnum }}-VM
    parameters:
      FieldVMCount: 
        value: "{{ fieldvmcount }}"
      WorldNum: 
        value: "{{ worldnum }}"
      Created:
        value: "{{ ansible_date_time.date }}"
      IntGMAddPrefix:
        value: "{{ intsubaddrprefix }}"
      ExtGMAddPrefix: 
        value: "{{ extsubnameprefix }}"
      ImageName: 
        value: "{{ baseimagename }}"
      VMadminName:
        value: "admin"
      VMadminPassword: 
        value: "kdlsfoi3kdD23"
    template: "{{ lookup('file','../armtemplate/world-deployment.json') | from_json }}"
  tags:
    - create
  delegate_to: 127.0.0.1

ARM Template

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "FieldVMCount": {
      "type": "int",
      "metadata": {
        "description": "the number of field server in the World"
      }
    },
    "WorldNum": {
      "type": "string",
      "metadata": {
        "description": "world num"
      }
    },
    "Created": {
      "type": "string",
      "metadata": {
        "description": "date of creation"
      }
    },
    "IntGMAddPrefix": {
      "type": "string",
      "metadata": {
        "description": "subnet name"
      }
    },
    "ExtGMAddPrefix": {
      "type": "string",
      "metadata": {
        "description": "subnet name"
      }
    },
    "ImageName": {
      "type": "string",
      "metadata": {
        "description": "base image name"
      }
    },
    "VMadminName": {
      "type": "string",
      "defaultValue": "admin username"
   },
    "VMadminPassword": {
      "type": "string",
      "metadata": {
        "description": "admin password"
      }
   }
  },
  "variables": {

...
EXPECTED RESULTS

I want to have VMs on azure without errors.

another failed try:
parameters:
FieldVMCount:
value: "{{ fieldvmcount | int }}"
--> failed

NO error with hard-coded int number in the playbook task,
parameters:
FieldVMCount:
value: 10

ACTUAL RESULTS
TASK [world : Create Azure Deploy] *********************************************************************
fatal: [127.0.0.1 -> 127.0.0.1]: FAILED! => {"changed": false, "failed_deployment_operations": [], "msg": "Deployment failed with status code: 400 and message: Deployment template validation failed: 'The provided value for the template parameter 'FieldVMCount' at line '1' and column '1982' is not valid.'."}

with -vvvv

The full traceback is:
  File "/tmp/ansible_MucHMw/ansible_module_azure_rm_deployment.py", line 509, in deploy_template
    deploy_parameter)
  File "/usr/local/lib/python2.7/dist-packages/azure_mgmt_resource-1.2.2-py2.7.egg/azure/mgmt/resource/resources/v2017_05_10/operations/deployments_operations.py", line 282, in create_or_update
    get_long_running_status, long_running_operation_timeout)
  File "/usr/local/lib/python2.7/dist-packages/msrestazure/azure_operation.py", line 350, in __init__
    raise CloudError(self._response)

fatal: [127.0.0.1 -> 127.0.0.1]: FAILED! => {
    "changed": false,
    "failed_deployment_operations": [],
    "invocation": {
        "module_args": {
            "ad_user": null,
            "append_tags": true,
            "cli_default_profile": null,
            "client_id": null,
            "cloud_environment": null,
            "deployment_mode": "incremental",
            "deployment_name": "ansible-arm",
            "location": "koreacentral",
            "parameters": {
                "Created": {
                    "value": "2018-01-31"
                },
                "ExtGMAddPrefix": {
                    "value": "10.192.64."
                },
                "FieldVMCount": {
                    "value": "3"
                },
                "ImageName": {
                    "value": "templatevmimage"
                },
                "IntGMAddPrefix": {
                    "value": "10.192.1."
                },
                "VMadminName": {
                    "value": "admin"
                },
                "VMadminPassword": {
                    "value": "sdfasdf"
                },
                "WorldNum": {
                    "value": "1"
                }
            },
            "parameters_link": null,
            "password": null,
@ansibot
Copy link
Contributor

ansibot commented Jan 31, 2018

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot
Copy link
Contributor

ansibot commented Jan 31, 2018

@ansibot ansibot added affects_2.4 This issue/PR affects Ansible v2.4 azure bug_report cloud module This issue/PR relates to a module. needs_triage Needs a first human triage before being processed. support:certified This issue/PR relates to certified code. labels Jan 31, 2018
@gundalow gundalow removed the needs_triage Needs a first human triage before being processed. label Jan 31, 2018
@MarkRoddick
Copy link

seeing the same

@zikalino
Copy link
Contributor

i will look into this today

@zikalino
Copy link
Contributor

Seems like this more generic issue -- not just this module.

Please refer to this discussion here, as people are experiencing this problem in many other places.
#15249

The problem is that jinjia template will be always expanded to string. So if you do:
WorldNum:
value: "{{ worldnum }}"
value will always be string.
I have also tried:
WorldNum:
value: !!int "{{ worldnum }}"
but it doesn't work either (more explanation in the discussion i mentioned).
WorldNum:
value: 10
but that's not ideal.

Also there's a proposal to solve this problem, so "!!int" or "!!float" could be used to ensure proper data type is passed:
ansible/proposals#72

At this point i am considering following solution (in the module):

  • add additional parameter (force_numeric)
  • module will convert all the parameters containing "force_numeric: yes" to numeric.
    Sample:
    WorldNum:
    value: !!int "{{ worldnum }}"
    force_numeric: yes

If somebody votes for this solution I will make a fix!

@MarkRoddick
Copy link

Looks like you could just do the string to int conversion in the ARM template.

{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"stringToConvert": {
"type": "string",
"defaultValue": "4"
}
},
"varibles": {
"integerConvertedfromString": "[int(parameters('stringToConvert'))]"
},
"resources": [
]
}

See - https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-numeric#example-4

@zikalino
Copy link
Contributor

@MarkRoddick but this would require changes in existing ARM template. If existing ARM template expects number as a parameter, there's no way to pass it right now.

@MarkRoddick
Copy link

yeah agreed, but least its a workaround if you are using custom ARM templates

@ilseokoh
Copy link
Author

I also modified my ARM template converting from string to int.

@zikalino
Copy link
Contributor

zikalino commented Feb 22, 2018

I was thinking about this issue during Chinese New Year holidays, and I think I figured out the only proper solution (before there's any generic fix).
I think it should work as follows:

  • if user specifies template we will check and adjust all non-string paramaters if necessary
  • this won't work with template_url parameter. instead user should use template parameter with {{ lookup('url', ....)}}

@ilseokoh @MarkRoddick do you think that would be good approach?

@zikalino
Copy link
Contributor

implemented the solution as mentioned above.

@jborean93
Copy link
Contributor

jborean93 commented Mar 7, 2018

While that PR should help I would have thought you could still get this working right now. I've done some digging myself with a test module and found that the int type was still preserved in jinja, e.g.

- hosts: localhost
  vars:
    int_variable: 1234
  tasks:
  - module:
      int_option: "{{ int_variable }}"

Still resulted in an integer. If int_variable was declared like int_variable: '1234' then it would be a string which makes me wonder how fieldvmcount is being defined in your code. Are you able to share some info on that?

needs_info

@ansibot ansibot added the needs_info This issue requires further information. Please answer any outstanding questions. label Mar 7, 2018
@zikalino
Copy link
Contributor

zikalino commented Mar 8, 2018

yes, it's preserved, and you can convert sth to integer too, but eventually you have to put in in "" as you can't start field with naked {{ }} in ansible and it's get converted back to string.

@jborean93
Copy link
Contributor

jborean93 commented Mar 8, 2018

@zikalino I tested that, it still stayed the same as the original variable declaration. The quotation is just a yaml rule but the parsing is technically done in jinja

@zikalino
Copy link
Contributor

zikalino commented Mar 8, 2018

@jborean93 you mean putting "{{ something integer in }}" resulted in integer? i have to retest that. perhaps something was fixed somewhere else in the meantime.

@jborean93
Copy link
Contributor

in the latest devel branch, that example I gave you meant 1234 was sent as an integer to the module. This was the same in dictionary variables as well. The outlier to this was when you use the | int filter, it seems like the variable returned by jinja is a string and not an int which you alluded to in your previous comments.

I didn't test it out with the azure_rm_deployment module but with just a custom one and it worked fine for me.

@zikalino
Copy link
Contributor

zikalino commented Mar 8, 2018

yes {{ var | int }} is converted to int, bit if you do "{{ var | int }}" it's converted back to string, so there's no workaround for this.

@jborean93
Copy link
Contributor

@zikalino I'm not fully sure on the rules but if you omit the | int and the variable is an int then the value being passed to a module is still an int. Was just a suggestion to get over this issue for now until we wait for the PR to be merged and included in a release.

@zikalino
Copy link
Contributor

zikalino commented Mar 8, 2018

yes, i will retest it again.

@ansibot
Copy link
Contributor

ansibot commented Apr 9, 2018

@ilseokoh This issue is waiting for your response. Please respond or the issue will be closed.

click here for bot help

@ansibot
Copy link
Contributor

ansibot commented May 11, 2018

@ilseokoh You have not responded to information requests in this issue so we will assume it no longer affects you. If you are still interested in this, please create a new issue with the requested information.

click here for bot help

@ansibot ansibot closed this as completed May 11, 2018
@ansible ansible locked and limited conversation to collaborators May 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.4 This issue/PR affects Ansible v2.4 azure bug This issue/PR relates to a bug. cloud module This issue/PR relates to a module. needs_info This issue requires further information. Please answer any outstanding questions. support:certified This issue/PR relates to certified code.
Projects
None yet
Development

No branches or pull requests

6 participants