--- # ============================================================ - name: set up aws connection info set_fact: aws_connection_info: &aws_connection_info aws_access_key: "{{ aws_access_key }}" aws_secret_key: "{{ aws_secret_key }}" security_token: "{{ security_token }}" region: "{{ aws_region }}" no_log: yes # ============================================================ - name: test add s3 bucket notification block: - name: move lambda into place for archive module copy: src: "mini_lambda.py" dest: "{{output_dir}}/mini_lambda.py" - name: bundle lambda into a zip archive: format: zip path: "{{output_dir}}/mini_lambda.py" dest: "{{output_dir}}/mini_lambda.zip" register: function_res - name: register bucket s3_bucket: name: "{{resource_prefix}}-bucket" state: present <<: *aws_connection_info register: bucket_info - name: register lambda lambda: name: "{{resource_prefix}}-lambda" state: present role: "ansible_lambda_role" runtime: "python3.7" zip_file: "{{function_res.dest}}" handler: "lambda_function.lambda_handler" memory_size: "128" timeout: "30" <<: *aws_connection_info register: lambda_info - name: register notification without invoke permissions s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: images/ suffix: .jpg <<: *aws_connection_info register: result ignore_errors: true - name: assert nice message returned assert: that: - result is failed - result.msg != 'MODULE FAILURE' - name: Add invocation permission of Lambda function on AWS lambda_policy: function_name: "{{ lambda_info.configuration.function_arn }}" statement_id: allow_lambda_invoke action: lambda:InvokeFunction principal: "s3.amazonaws.com" source_arn: "arn:aws:s3:::{{bucket_info.name}}" <<: *aws_connection_info - name: register s3 bucket notification s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: images/ suffix: .jpg <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True # ============================================================ - name: test check_mode without change s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: images/ suffix: .jpg <<: *aws_connection_info register: result check_mode: yes - name: assert result.changed == False assert: that: - result.changed == False - name: test check_mode change events s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*"] prefix: images/ suffix: .jpg <<: *aws_connection_info register: result check_mode: yes - name: assert result.changed == True assert: that: - result.changed == True - name: test that check_mode didn't change events s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: images/ suffix: .jpg <<: *aws_connection_info register: result - name: assert result.changed == False assert: that: - result.changed == False # ============================================================ - name: test mutually exclusive parameters s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:Post"] prefix: photos/ suffix: .gif lambda_version: 0 lambda_alias: 0 <<: *aws_connection_info register: result ignore_errors: true - name: assert task failed assert: that: - result is failed - "result.msg == 'parameters are mutually exclusive: lambda_alias|lambda_version'" # ============================================================ # Test configuration changes - name: test configuration change on suffix s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: images/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True - name: test configuration change on prefix s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True - name: test configuration change on new events added s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*", "s3:ObjectRestore:Post"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True - name: test configuration change on events removed s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:Post"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True # ============================================================ # Test idempotency of CRUD - name: change events s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*", "s3:ObjectRestore:Post"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: test that event order does not matter s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectRestore:Post", "s3:ObjectRemoved:*", "s3:ObjectCreated:*"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == False assert: that: - result.changed == False - name: test that configuration is the same as previous task s3_bucket_notification: state: present event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" lambda_function_arn: "{{ lambda_info.configuration.function_arn }}" events: ["s3:ObjectCreated:*", "s3:ObjectRemoved:*", "s3:ObjectRestore:Post"] prefix: photos/ suffix: .gif <<: *aws_connection_info register: result - name: assert result.changed == False assert: that: - result.changed == False - name: test remove notification s3_bucket_notification: state: absent event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" <<: *aws_connection_info register: result - name: assert result.changed == True assert: that: - result.changed == True - name: test that events is already removed s3_bucket_notification: state: absent event_name: "{{resource_prefix}}-on_file_add_or_remove" bucket_name: "{{resource_prefix}}-bucket" <<: *aws_connection_info register: result - name: assert result.changed == False assert: that: - result.changed == False always: - name: clean-up bucket s3_bucket: name: "{{resource_prefix}}-bucket" state: absent <<: *aws_connection_info - name: clean-up lambda lambda: name: "{{resource_prefix}}-lambda" state: absent <<: *aws_connection_info # ============================================================ - - block: # ============================================================ - name: test with no parameters except state absent s3_bucket_notification: state=absent register: result ignore_errors: true - name: assert failure when called with no parameters assert: that: - 'result.failed' - 'result.msg.startswith("missing required arguments: event_name, bucket_name")' # ============================================================ - name: test abesnt s3_bucket_notification: state=absent register: result ignore_errors: true - name: assert failure when called with no parameters assert: that: - 'result.failed' - 'result.msg.startswith("missing required arguments: event_name, bucket_name")'