summaryrefslogtreecommitdiff
path: root/test/integration/targets/lambda_policy/tasks/main.yml
blob: df525351e5eaaf6ee04381b7a41ba34ced7f7784 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
---
#
#  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