--- # # Author: Michael De La Rue # based on ec2_key.yml + lambda.py - block: - name: set up AWS credentials set_fact: aws_connection_info: &aws_connection_info aws_region: '{{ aws_region }}' aws_access_key: '{{ aws_access_key }}' aws_secret_key: '{{ aws_secret_key }}' security_token: '{{ security_token }}' no_log: yes # ============================================================ - name: test with no parameters lambda_policy: register: result ignore_errors: true - name: assert failure when called with no parameters assert: that: - 'result.failed' - 'result.msg.startswith("missing required arguments: ")' # ============================================================ - name: test with all required dummy parameters but no region lambda_policy: statement_id: dummy principal: api_fakeway action: fake:do_something_fake function_name: dummy_fake_function ignore_errors: true register: result - name: assert failure and appropriate message when called without region assert: that: - 'result.failed' - '"region must be specified" in result.msg' # ============================================================ - name: test with all required dummy parameters but no region lambda_policy: statement_id: dummy principal: api_fakeway action: fake:do_something_fake function_name: dummy_fake_function region: null ignore_errors: true register: result - name: assert failure and appropriate message when called false region region assert: that: - 'result.failed' - '"region must be specified" in result.msg' # ============================================================ - name: test exceptions generated by forcing bad ec2 url lambda_policy: function_name: "{{ lambda_function_name }}" state: present statement_id: api-gateway-invoke-lambdas action: lambda:InvokeFunction principal: apigateway.amazonaws.com source_arn: "arn:aws:execute-api:no-north-0:1234567:*/*" ec2_url: https://noexist.example.com ec2_region: 'no-north-0' ec2_access_key: 'iamnotreallyanaccesskey' ec2_secret_key: 'thisisabadsecretkey' security_token: 'andthisisabadsecuritytoken' register: result ignore_errors: true - name: assert lambda manages to respond as expected assert: that: - 'result is failed' - 'result.msg != "MODULE FAILURE"' - 'result.changed == False' # ============================================================ # direct zip file upload - name: move lambda into place for archive module copy: src: "mini_http_lambda.py" dest: "{{output_dir}}/mini_http_lambda.py" - name: bundle lambda into a zip archive: format: zip path: "{{output_dir}}/mini_http_lambda.py" dest: "{{output_dir}}/mini_http_lambda.zip" register: zip_res # This should exist, but there's no expectation that the test user should be able to # create/update this role, merely validate that it's there. # Use ansible -m iam_role -a 'name=ansible_lambda_role # assume_role_policy_document={{ lookup("file", "test/integration/targets/lambda_policy/files/minimal_trust_policy.json", convert_data=False) }} # ' -vvv localhost # to create this through more privileged credentials before running this test suite. - name: create minimal lambda role iam_role: name: ansible_lambda_role assume_role_policy_document: "{{ lookup('file', 'minimal_trust_policy.json', convert_data=False) }}" create_instance_profile: no <<: *aws_connection_info register: iam_role - name: wait 10 seconds for role to become available pause: seconds: 10 when: iam_role.changed - name: test state=present - upload the lambda lambda: name: "{{lambda_function_name}}" runtime: "python2.7" handler: "mini_http_lambda.handler" role: "ansible_lambda_role" zip_file: "{{zip_res.dest}}" <<: *aws_connection_info register: lambda_result - name: get the aws account ID for use in future commands aws_caller_info: <<: *aws_connection_info register: aws_caller_info - name: register lambda uri for use in template set_fact: mini_lambda_uri: "arn:aws:apigateway:{{ aws_region }}:lambda:path/2015-03-31/functions/arn:aws:lambda:{{ aws_region }}:{{ aws_caller_info.account }}:function:{{ lambda_result.configuration.function_name }}/invocations" - name: build API file template: src: endpoint-test-swagger-api.yml.j2 dest: "{{output_dir}}/endpoint-test-swagger-api.yml.j2" - name: deploy new API aws_api_gateway: api_file: "{{output_dir}}/endpoint-test-swagger-api.yml.j2" stage: "lambdabased" <<: *aws_connection_info register: create_result - name: register api id for later set_fact: api_id: "{{ create_result.api_id }}" - name: check API fails with permissions failure uri: url: "https://{{create_result.api_id}}.execute-api.{{aws_region}}.amazonaws.com/lambdabased/mini/Mr_Ansible_Tester" register: unauth_uri_result ignore_errors: true - name: assert internal server error due to permissions assert: that: - unauth_uri_result is failed - 'unauth_uri_result.status == 500' - name: give api gateway execute permissions on lambda lambda_policy: function_name: "{{ lambda_function_name }}" state: present statement_id: api-gateway-invoke-lambdas action: lambda:InvokeFunction principal: apigateway.amazonaws.com source_arn: "arn:aws:execute-api:{{ aws_region }}:{{ aws_caller_info.account }}:*/*" <<: *aws_connection_info - name: try again but with ARN lambda_policy: function_name: "{{ lambda_result.configuration.function_arn }}" state: present statement_id: api-gateway-invoke-lambdas action: lambda:InvokeFunction principal: apigateway.amazonaws.com source_arn: "arn:aws:execute-api:{{ aws_region }}:{{ aws_caller_info.account }}:*/*" <<: *aws_connection_info - name: check API works with execute permissions uri: url: "https://{{create_result.api_id}}.execute-api.{{aws_region}}.amazonaws.com/lambdabased/mini/Mr_Ansible_Tester" register: uri_result - name: assert API works success assert: that: - 'uri_result' - name: deploy new API aws_api_gateway: api_file: "{{output_dir}}/endpoint-test-swagger-api.yml.j2" stage: "lambdabased" <<: *aws_connection_info register: create_result ignore_errors: true always: # ============================================================ - name: destroy lambda for test cleanup if created lambda: name: "{{lambda_function_name}}" <<: *aws_connection_info state: absent register: result ignore_errors: yes - name: destroy API for test cleanup if created aws_api_gateway: state: absent api_id: '{{api_id}}' <<: *aws_connection_info register: destroy_result ignore_errors: yes