diff options
author | RĂ©mi REY <rrey94@gmail.com> | 2019-02-25 21:27:33 +0100 |
---|---|---|
committer | Sloane Hertel <shertel@redhat.com> | 2019-02-25 21:27:33 +0100 |
commit | 30b3ce0f81f6e74ff12fc5ad3c4e24f02386ce14 (patch) | |
tree | dcd0c700eda728f4cbc422ecd6920cd43df4f883 /test/integration/targets/aws_secret | |
parent | Revert "foreman: Use generic python in test run (#52544)" (diff) | |
download | ansible-30b3ce0f81f6e74ff12fc5ad3c4e24f02386ce14.tar.xz ansible-30b3ce0f81f6e74ff12fc5ad3c4e24f02386ce14.zip |
Add aws_secret module for managing secretsmanager on AWS (#48486)
* Adding module for managing AWS Secrets Manager resources
* adding aws_secret lookup plugin
Also use the data returned by describe_secret everywhere.
* replace the explicit /root use by a temporary dir
* aws_secret: rework module
Reworked module to use a class avoiding using client and module in every
functions.
* Added support of "recovery_window" parameter to allow user to provide
recovery period.
* updated return value to be the api output providing more details about
the secret.
* Fix Python 3 bug in tests if the role is not removed
* Add unsupported alias due to issue restricting resource for creating secrets
Diffstat (limited to 'test/integration/targets/aws_secret')
-rw-r--r-- | test/integration/targets/aws_secret/aliases | 2 | ||||
-rw-r--r-- | test/integration/targets/aws_secret/defaults/main.yaml | 2 | ||||
-rw-r--r-- | test/integration/targets/aws_secret/files/hello_world.zip | bin | 0 -> 401 bytes | |||
-rw-r--r-- | test/integration/targets/aws_secret/files/secretsmanager-trust-policy.json | 19 | ||||
-rw-r--r-- | test/integration/targets/aws_secret/tasks/main.yaml | 265 |
5 files changed, 288 insertions, 0 deletions
diff --git a/test/integration/targets/aws_secret/aliases b/test/integration/targets/aws_secret/aliases new file mode 100644 index 0000000000..5692719518 --- /dev/null +++ b/test/integration/targets/aws_secret/aliases @@ -0,0 +1,2 @@ +cloud/aws +unsupported diff --git a/test/integration/targets/aws_secret/defaults/main.yaml b/test/integration/targets/aws_secret/defaults/main.yaml new file mode 100644 index 0000000000..f85fd58b59 --- /dev/null +++ b/test/integration/targets/aws_secret/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +super_secret_string: 'Test12345' diff --git a/test/integration/targets/aws_secret/files/hello_world.zip b/test/integration/targets/aws_secret/files/hello_world.zip Binary files differnew file mode 100644 index 0000000000..8fd9e058f4 --- /dev/null +++ b/test/integration/targets/aws_secret/files/hello_world.zip diff --git a/test/integration/targets/aws_secret/files/secretsmanager-trust-policy.json b/test/integration/targets/aws_secret/files/secretsmanager-trust-policy.json new file mode 100644 index 0000000000..c53e309641 --- /dev/null +++ b/test/integration/targets/aws_secret/files/secretsmanager-trust-policy.json @@ -0,0 +1,19 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + }, + "Action": "sts:AssumeRole" + }, + { + "Effect": "Allow", + "Principal": { + "Service": "secretsmanager.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} diff --git a/test/integration/targets/aws_secret/tasks/main.yaml b/test/integration/targets/aws_secret/tasks/main.yaml new file mode 100644 index 0000000000..b626365168 --- /dev/null +++ b/test/integration/targets/aws_secret/tasks/main.yaml @@ -0,0 +1,265 @@ +--- +- block: + - name: set connection information for all tasks + set_fact: + aws_connection_info: &aws_connection_info + aws_access_key: "{{ aws_access_key }}" + aws_secret_key: "{{ aws_secret_key }}" + region: "{{ aws_region }}" + security_token: "{{ security_token }}" + no_log: true + + - name: retrieve caller facts + aws_caller_facts: + <<: *aws_connection_info + register: test_caller_facts + + - name: ensure IAM role exists + iam_role: + <<: *aws_connection_info + name: "test-secrets-manager-role" + assume_role_policy_document: "{{ lookup('file','secretsmanager-trust-policy.json') }}" + state: present + create_instance_profile: no + managed_policy: + - 'arn:aws:iam::aws:policy/SecretsManagerReadWrite' + register: iam_role_output + ignore_errors: yes + + # CI does not remove the role and comparing policies has a bug on Python3; fall back to use iam_role_facts + - name: get IAM role + iam_role_facts: + <<: *aws_connection_info + name: "test-secrets-manager-role" + when: iam_role_output is failed + register: iam_role_facts + + - name: set iam_role_output + set_fact: + iam_role_output: "{{ iam_role_facts.iam_roles[0] }}" + when: iam_role_facts is defined + + - name: create a temporary directory + tempfile: + state: directory + register: tmp + + - name: move lambda into place for upload + copy: + src: "files/hello_world.zip" + dest: "{{ tmp.path }}/hello_world.zip" + + - name: dummy lambda for testing + lambda: + <<: *aws_connection_info + name: "hello-world-{{ resource_prefix }}" + state: present + zip_file: "{{ tmp.path }}/hello_world.zip" + runtime: 'python2.7' + role: "{{ iam_role_output.arn }}" + handler: 'hello_world.lambda_handler' + register: lambda_output + until: not lambda_output.failed + retries: 10 + delay: 5 + + - debug: + var: lambda_output + + # ============================================================ + # Module parameter testing + # ============================================================ + - name: test with no parameters + aws_secret: + register: result + ignore_errors: true + check_mode: true + + - name: assert failure when called with no parameters + assert: + that: + - result.failed + - 'result.msg.startswith("missing required arguments:")' + + # ============================================================ + # Creation/Deletion testing + # ============================================================ + - name: add secret to AWS Secrets Manager + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + register: result + + - name: assert correct keys are returned + assert: + that: + - result.changed + - result.arn is not none + - result.name is not none + - result.tags is not none + - result.version_ids_to_stages is not none + + - name: no changes to secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + register: result + + - name: assert correct keys are returned + assert: + that: + - not result.changed + - result.arn is not none + + - name: make change to secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + description: 'this is a change to this secret' + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + register: result + + - debug: + var: result + + - name: assert correct keys are returned + assert: + that: + - result.changed + - result.arn is not none + - result.name is not none + - result.tags is not none + - result.version_ids_to_stages is not none + + - name: add tags to secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + description: 'this is a change to this secret' + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + tags: + Foo: 'Bar' + Test: 'Tag' + register: result + + - name: assert correct keys are returned + assert: + that: + - result.changed + + - name: remove tags from secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + description: 'this is a change to this secret' + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + register: result + + - name: assert correct keys are returned + assert: + that: + - result.changed + + - name: lambda policy for secrets manager + lambda_policy: + <<: *aws_connection_info + state: present + function_name: "hello-world-{{ resource_prefix }}" + statement_id: LambdaSecretsManagerTestPolicy + action: 'lambda:InvokeFunction' + principal: "secretsmanager.amazonaws.com" + + - name: add rotation lambda to secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + description: 'this is a change to this secret' + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + rotation_lambda: "arn:aws:lambda:{{ aws_region }}:{{ test_caller_facts.account }}:function:hello-world-{{ resource_prefix }}" + register: result + retries: 100 + delay: 5 + until: not result.failed + + - name: assert correct keys are returned + assert: + that: + - result.changed + + - name: remove rotation lambda from secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + description: 'this is a change to this secret' + state: present + secret_type: 'string' + secret: "{{ super_secret_string }}" + register: result + + - name: assert correct keys are returned + assert: + that: + - result.changed + + always: + - name: remove secret + aws_secret: + <<: *aws_connection_info + name: "test-secret-string-{{ resource_prefix }}" + state: absent + secret_type: 'string' + secret: "{{ super_secret_string }}" + recovery_window: 0 + ignore_errors: yes + + - name: remove lambda policy + lambda_policy: + <<: *aws_connection_info + state: absent + function_name: "hello-world-{{ resource_prefix }}" + statement_id: lambda-secretsmanager-test-policy + action: lambda:InvokeFunction + principal: secretsmanager.amazonaws.com + ignore_errors: yes + + - name: remove dummy lambda + lambda: + <<: *aws_connection_info + name: "hello-world-{{ resource_prefix }}" + state: absent + zip_file: "{{ tmp.path }}/hello_world.zip" + runtime: 'python2.7' + role: "test-secrets-manager-role" + handler: 'hello_world.lambda_handler' + ignore_errors: yes + + # CI does not remove the IAM role + - name: remove IAM role + iam_role: + <<: *aws_connection_info + name: "test-secrets-manager-role" + assume_role_policy_document: "{{ lookup('file','secretsmanager-trust-policy.json') }}" + state: absent + create_instance_profile: no + managed_policy: + - 'arn:aws:iam::aws:policy/SecretsManagerReadWrite' + ignore_errors: yes + + - name: remove temporary dir + file: + path: "{{ tmp.path }}" + state: absent |