From 7aac7a56da800c3e091f90f3653a1e3845d6772b Mon Sep 17 00:00:00 2001 From: Stefan Horning Date: Tue, 22 Oct 2019 17:17:01 +0200 Subject: [PATCH] Added missing param to lambda module to pass it through to boto3 (#58822) * Added missing param to lambda module to pass it through to boto3 * Allow updating of runtime, because there is no reason why not * Updated version_added to 2.10 to make tests green again * Updated RETURN docs of Lambda module * Added tests to aws_lambda test-suite. --- .../58822-aws-lamda-tracing-config.yaml | 2 + lib/ansible/modules/cloud/amazon/lambda.py | 26 ++- .../targets/aws_lambda/tasks/main.yml | 187 ++++++++---------- 3 files changed, 106 insertions(+), 109 deletions(-) create mode 100644 changelogs/fragments/58822-aws-lamda-tracing-config.yaml diff --git a/changelogs/fragments/58822-aws-lamda-tracing-config.yaml b/changelogs/fragments/58822-aws-lamda-tracing-config.yaml new file mode 100644 index 00000000000..c88b4ca81b9 --- /dev/null +++ b/changelogs/fragments/58822-aws-lamda-tracing-config.yaml @@ -0,0 +1,2 @@ +minor_changes: + - lambda - add a tracing_mode parameter to set the TracingConfig for AWS X-Ray. Also allow updating Lambda runtime. diff --git a/lib/ansible/modules/cloud/amazon/lambda.py b/lib/ansible/modules/cloud/amazon/lambda.py index 7fed40df69e..68fe149da8e 100644 --- a/lib/ansible/modules/cloud/amazon/lambda.py +++ b/lib/ansible/modules/cloud/amazon/lambda.py @@ -96,6 +96,12 @@ options: description: - The parent object that contains the target Amazon Resource Name (ARN) of an Amazon SQS queue or Amazon SNS topic. version_added: "2.3" + tracing_mode: + description: + - Set mode to 'Active' to sample and trace incoming requests with AWS X-Ray. Turned off (set to 'PassThrough') by default. + choices: ['Active', 'PassThrough'] + version_added: "2.10" + tags: description: - tag dict to apply to the function (requires botocore 1.5.40 or above). @@ -175,7 +181,7 @@ configuration: type: dict sample: { - 'code_sha256': 'SHA256 hash', + 'code_sha256': 'zOAGfF5JLFuzZoSNirUtOrQp+S341IOA3BcoXXoaIaU=', 'code_size': 123, 'description': 'My function', 'environment': { @@ -188,13 +194,16 @@ configuration: 'handler': 'index.handler', 'last_modified': '2017-08-01T00:00:00.000+0000', 'memory_size': 128, + 'revision_id': 'a2x9886d-d48a-4a0c-ab64-82abc005x80c', 'role': 'arn:aws:iam::123456789012:role/lambda_basic_execution', 'runtime': 'nodejs6.10', + 'tracing_config': { 'mode': 'Active' }, 'timeout': 3, 'version': '1', 'vpc_config': { 'security_group_ids': [], - 'subnet_ids': [] + 'subnet_ids': [], + 'vpc_id': '123' } } ''' @@ -336,6 +345,7 @@ def main(): vpc_security_group_ids=dict(type='list'), environment_variables=dict(type='dict'), dead_letter_arn=dict(), + tracing_mode=dict(choices=['Active', 'PassThrough']), tags=dict(type='dict'), ) @@ -370,6 +380,7 @@ def main(): vpc_security_group_ids = module.params.get('vpc_security_group_ids') environment_variables = module.params.get('environment_variables') dead_letter_arn = module.params.get('dead_letter_arn') + tracing_mode = module.params.get('tracing_mode') tags = module.params.get('tags') check_mode = module.check_mode @@ -417,6 +428,8 @@ def main(): func_kwargs.update({'Timeout': timeout}) if memory_size and current_config['MemorySize'] != memory_size: func_kwargs.update({'MemorySize': memory_size}) + if runtime and current_config['Runtime'] != runtime: + func_kwargs.update({'Runtime': runtime}) if (environment_variables is not None) and (current_config.get( 'Environment', {}).get('Variables', {}) != environment_variables): func_kwargs.update({'Environment': {'Variables': environment_variables}}) @@ -427,10 +440,8 @@ def main(): else: if dead_letter_arn != "": func_kwargs.update({'DeadLetterConfig': {'TargetArn': dead_letter_arn}}) - - # Check for unsupported mutation - if current_config['Runtime'] != runtime: - module.fail_json(msg='Cannot change runtime. Please recreate the function') + if tracing_mode and (current_config.get('TracingConfig', {}).get('Mode', 'PassThrough') != tracing_mode): + func_kwargs.update({'TracingConfig': {'Mode': tracing_mode}}) # If VPC configuration is desired if vpc_subnet_ids or vpc_security_group_ids: @@ -555,6 +566,9 @@ def main(): if dead_letter_arn: func_kwargs.update({'DeadLetterConfig': {'TargetArn': dead_letter_arn}}) + if tracing_mode: + func_kwargs.update({'TracingConfig': {'Mode': tracing_mode}}) + # If VPC configuration is given if vpc_subnet_ids or vpc_security_group_ids: if not vpc_subnet_ids or not vpc_security_group_ids: diff --git a/test/integration/targets/aws_lambda/tasks/main.yml b/test/integration/targets/aws_lambda/tasks/main.yml index 767d6ada3b7..a62fb93b671 100644 --- a/test/integration/targets/aws_lambda/tasks/main.yml +++ b/test/integration/targets/aws_lambda/tasks/main.yml @@ -1,9 +1,15 @@ --- -# -# Author: Michael De La Rue -# based on ec2_key.yml + lambda.py +# tasks file for aws_lambda test -- block: +- name: set connection information for AWS modules and run tests + module_defaults: + group/aws: + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + security_token: "{{ security_token | default(omit) }}" + region: "{{ aws_region }}" + + block: # ============================================================ - name: test with no parameters @@ -20,7 +26,7 @@ # ============================================================ - name: test with no parameters except state absent lambda: - state=absent + state: absent register: result ignore_errors: true @@ -33,8 +39,8 @@ # ============================================================ - name: test with no role or handler lambda: - name=ansible-testing-fake-should-not-be-created - runtime="python2.7" + name: ansible-testing-fake-should-not-be-created + runtime: "python2.7" register: result ignore_errors: true @@ -47,10 +53,11 @@ # ============================================================ - name: test with all module required variables but no region lambda: - name=ansible-testing-fake-should-not-be-created - runtime="python2.7" - handler="no-handler" - role=arn:fake-role-doesnt-exist + name: ansible-testing-fake-should-not-be-created + runtime: "python2.7" + handler: "no-handler" + role: "arn:fake-role-doesnt-exist" + region: register: result ignore_errors: true @@ -76,6 +83,7 @@ vpc_security_group_ids: environment_variables: dead_letter_arn: + region: register: result ignore_errors: true @@ -101,31 +109,24 @@ - name: test state=present - upload the lambda lambda: - name="{{lambda_function_name}}" - runtime="python2.7" - handler="mini_lambda.handler" - role="ansible_lambda_role" - ec2_region='{{ec2_region}}' - ec2_access_key='{{ec2_access_key}}' - ec2_secret_key='{{ec2_secret_key}}' - security_token='{{security_token}}' - zip_file="{{zip_res.dest}}" + name: "{{lambda_function_name}}" + runtime: "python2.7" + handler: "mini_lambda.handler" + role: "ansible_lambda_role" + zip_file: "{{zip_res.dest}}" register: result - name: assert lambda upload succeeded assert: that: - - 'result is not failed' + - result is not failed + - result.configuration.tracing_config.mode == "PassThrough" - name: test lambda works execute_lambda: name: "{{lambda_function_name}}" payload: name: "Mr Ansible Tests" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' register: result - name: assert lambda manages to respond as expected @@ -134,16 +135,63 @@ - 'result is not failed' - 'result.result.output.message == "hello Mr Ansible Tests"' + - name: test lambda config updates + lambda: + name: "{{lambda_function_name}}" + runtime: "nodejs10.x" + tracing_mode: 'Active' + handler: "mini_lambda.handler" + role: "ansible_lambda_role" + register: update_result + + - name: assert that update succeeded + assert: + that: + - update_result is not failed + - update_result.changed == True + - update_result.configuration.runtime == 'nodejs10.x' + - update_result.configuration.tracing_config.mode == 'Active' + + - name: test no changes are made with the same parameters + lambda: + name: "{{lambda_function_name}}" + runtime: "nodejs10.x" + tracing_mode: 'Active' + handler: "mini_lambda.handler" + role: "ansible_lambda_role" + register: update_result + + - name: assert that update succeeded + assert: + that: + - update_result is not failed + - update_result.changed == False + - update_result.configuration.runtime == 'nodejs10.x' + - update_result.configuration.tracing_config.mode == 'Active' + + - name: reset config updates for the following tests + lambda: + name: "{{lambda_function_name}}" + runtime: "python2.7" + tracing_mode: 'PassThrough' + handler: "mini_lambda.handler" + role: "ansible_lambda_role" + register: result + + - name: assert that reset succeeded + assert: + that: + - result is not failed + - result.changed == True + - result.configuration.runtime == 'python2.7' + - result.configuration.tracing_config.mode == 'PassThrough' + # ============================================================ - name: test state=present with security group but no vpc lambda: name: "{{lambda_function_name}}" runtime: "python2.7" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" handler: description: @@ -168,10 +216,6 @@ name: "{{lambda_function_name}}" runtime: "python2.7" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" handler: "mini_lambda.handler" # These are not allowed because of mutually exclusive. @@ -191,8 +235,6 @@ - 'result is not failed' - 'result.changed == False' - - # ============================================================ - name: test putting an environment variable changes lambda lambda: @@ -200,10 +242,6 @@ runtime: "python2.7" handler: "mini_lambda.handler" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" environment_variables: EXTRA_MESSAGE: "I think you are great!!" @@ -220,9 +258,6 @@ name: "{{lambda_function_name}}" payload: name: "Mr Ansible Tests" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' security_token: '{{security_token}}' register: result @@ -256,12 +291,8 @@ # ============================================================ - name: test state=absent (expect changed=False) lambda: - name="{{lambda_function_name}}" - ec2_region='{{ec2_region}}' - ec2_access_key='{{ec2_access_key}}' - ec2_secret_key='{{ec2_secret_key}}' - security_token='{{security_token}}' - state=absent + name: "{{lambda_function_name}}" + state: absent register: result - name: assert state=absent @@ -279,10 +310,6 @@ runtime: "python2.7" handler: "mini_lambda.handler" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_1 @@ -293,10 +320,6 @@ runtime: "python2.7" handler: "mini_lambda.handler" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_2 @@ -307,10 +330,6 @@ runtime: "python2.7" handler: "mini_lambda.handler" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_3 @@ -321,10 +340,6 @@ runtime: "python2.7" handler: "mini_lambda.handler" role: "ansible_lambda_role" - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" register: result @@ -356,10 +371,6 @@ lambda: name: "{{lambda_function_name}}_1" state: absent - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_1 @@ -368,10 +379,6 @@ lambda: name: "{{lambda_function_name}}_2" state: absent - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_2 @@ -380,10 +387,6 @@ lambda: name: "{{lambda_function_name}}_3" state: absent - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" async: 1000 register: async_3 @@ -392,10 +395,6 @@ lambda: name: "{{lambda_function_name}}_4" state: absent - ec2_region: '{{ec2_region}}' - ec2_access_key: '{{ec2_access_key}}' - ec2_secret_key: '{{ec2_secret_key}}' - security_token: '{{security_token}}' zip_file: "{{zip_res.dest}}" register: result @@ -422,29 +421,11 @@ until: job_result is finished retries: 30 - - # ============================================================ - # upload via s3 bucket - multi function - - # ============================================================ - # update already existing function - - + # ============================================================ always: - # ============================================================ - - name: test state=absent (expect changed=False) + - name: ensure function is absent at end of test lambda: - name="{{lambda_function_name}}" - ec2_region='{{ec2_region}}' - ec2_access_key='{{ec2_access_key}}' - ec2_secret_key='{{ec2_secret_key}}' - security_token='{{security_token}}' - state=absent - register: result - - - name: assert state=absent - assert: - that: - - 'result is not failed' - - 'result.changed == False' + name: "{{lambda_function_name}}" + state: absent + ignore_errors: true