feat(secretmanager): added support for regional secret manager

This commit is contained in:
durgesh-ninave-crest 2025-05-13 18:36:36 +05:30
commit 9101671c0e
10 changed files with 595 additions and 62 deletions

View file

@ -5,8 +5,9 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
DOCUMENTATION = ''' DOCUMENTATION = '''
author:
- Dave Costakos <dcostako@redhat.com>
name: gcp_secret_manager name: gcp_secret_manager
author: Dave Costakos (@davecostakos) <dcostako@redhat.com>
short_description: Get Secrets from Google Cloud as a Lookup plugin short_description: Get Secrets from Google Cloud as a Lookup plugin
description: description:
- retrieve secret keys in Secret Manager for use in playbooks - retrieve secret keys in Secret Manager for use in playbooks
@ -14,6 +15,8 @@ DOCUMENTATION = '''
credentials for Google Cloud and the format of such credentials credentials for Google Cloud and the format of such credentials
- once a secret value is retreived, it is returned decoded. It is up to the developer - once a secret value is retreived, it is returned decoded. It is up to the developer
to maintain secrecy of this value once returned. to maintain secrecy of this value once returned.
- if location option is defined, then it deals with the regional secrets of the
location
options: options:
key: key:
@ -30,6 +33,10 @@ DOCUMENTATION = '''
- The name of the google cloud project - The name of the google cloud project
- defaults to OS env variable GCP_PROJECT if not present - defaults to OS env variable GCP_PROJECT if not present
type: str type: str
location:
description:
- If provided, it defines the location of the regional secret.
type: str
auth_kind: auth_kind:
description: description:
- the type of authentication to use with Google Cloud (i.e. serviceaccount or machineaccount) - the type of authentication to use with Google Cloud (i.e. serviceaccount or machineaccount)
@ -58,7 +65,7 @@ DOCUMENTATION = '''
description: description:
- JSON Object representing the contents of a service_account_file obtained from Google Cloud - JSON Object representing the contents of a service_account_file obtained from Google Cloud
- defaults to OS env variable GCP_SERVICE_ACCOUNT_INFO if not present - defaults to OS env variable GCP_SERVICE_ACCOUNT_INFO if not present
type: str type: jsonarg
required: False required: False
access_token: access_token:
description: description:
@ -83,7 +90,6 @@ DOCUMENTATION = '''
description: description:
- Authenticaiton scopes for Google Secret Manager - Authenticaiton scopes for Google Secret Manager
type: list type: list
elements: str
default: ["https://www.googleapis.com/auth/cloud-platform"] default: ["https://www.googleapis.com/auth/cloud-platform"]
''' '''
@ -103,6 +109,22 @@ EXAMPLES = '''
- name: Test getting specific version of a secret (new version) - name: Test getting specific version of a secret (new version)
ansible.builtin.debug: ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', version='2') }}" msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', version='2') }}"
- name: Test regional secret using env variables for credentials
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', location='us-central1') }}"
- name: Test regional secret using explicit credentials
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', location='us-central1', project='project', auth_kind='serviceaccount', service_account_file='file.json') }}"
- name: Test getting specific version of a regional secret (old version)
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', location='us-central1', version='1') }}"
- name: Test getting specific version of a regional secret (new version)
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key='secret_key', location='us-central1', version='2') }}"
''' '''
RETURN = ''' RETURN = '''
@ -168,6 +190,7 @@ class LookupModule(LookupBase):
self.set_options(var_options=variables, direct=kwargs) self.set_options(var_options=variables, direct=kwargs)
params = { params = {
"key": self.get_option("key"), "key": self.get_option("key"),
"location": self.get_option("location"),
"version": self.get_option("version"), "version": self.get_option("version"),
"access_token": self.get_option("access_token"), "access_token": self.get_option("access_token"),
"scopes": self.get_option("scopes"), "scopes": self.get_option("scopes"),
@ -199,7 +222,7 @@ class LookupModule(LookupBase):
# to be set if secret versions get disabled # to be set if secret versions get disabled
# see https://issuetracker.google.com/issues/286489671 # see https://issuetracker.google.com/issues/286489671
def get_latest_version(self, module, auth): def get_latest_version(self, module, auth):
url = "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions?filter=state:ENABLED".format( url = (self.make_url_prefix(module) + "secrets/{name}/versions?filter=state:ENABLED").format(
**module.params **module.params
) )
response = auth.get(url) response = auth.get(url)
@ -234,7 +257,7 @@ class LookupModule(LookupBase):
if module.params['calc_version'] is None: if module.params['calc_version'] is None:
return '' return ''
url = "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions/{calc_version}:access".format( url = (self.make_url_prefix(module) + "secrets/{name}/versions/{calc_version}:access").format(
**module.params **module.params
) )
response = auth.get(url) response = auth.get(url)
@ -244,3 +267,8 @@ class LookupModule(LookupBase):
return '' return ''
return response.json()['payload']['data'] return response.json()['payload']['data']
def make_url_prefix(self, module):
if module.params['location']:
return "https://secretmanager.{location}.rep.googleapis.com/v1/projects/{project}/locations/{location}/"
return "https://secretmanager.googleapis.com/v1/projects/{project}/"

View file

@ -24,8 +24,9 @@ description:
- Create new secret values. - Create new secret values.
- Add/remove versions of secrets. - Add/remove versions of secrets.
- Please note that other features like etags, replication, annontation expected to be managed outside of Ansible. - Please note that other features like etags, replication, annontation expected to be managed outside of Ansible.
- Deals with regional secrets if location option is defined.
short_description: Access and Update Google Cloud Secrets Manager objects short_description: Access and Update Google Cloud Secrets Manager objects
author: Dave Costakos (@davecostakos) <dcostako@redhat.com> author: Dave Costakos @RedHat
requirements: requirements:
- python >= 2.6 - python >= 2.6
- requests >= 2.18.4 - requests >= 2.18.4
@ -44,7 +45,6 @@ options:
- application - application
- machineaccount - machineaccount
- serviceaccount - serviceaccount
- accesstoken
service_account_contents: service_account_contents:
description: description:
- The contents of a Service Account JSON file, either in a dictionary or as a - The contents of a Service Account JSON file, either in a dictionary or as a
@ -59,21 +59,11 @@ options:
- An optional service account email address if machineaccount is selected and - An optional service account email address if machineaccount is selected and
the user does not wish to use the default email. the user does not wish to use the default email.
type: str type: str
access_token:
description:
- An OAuth2 access token if credential type is accesstoken.
type: str
scopes: scopes:
description: description:
- Array of scopes to be used - Array of scopes to be used
type: list type: list
elements: str elements: str
env_type:
description:
- Specifies which Ansible environment you're running this module within.
- This should not be set unless you know what you're doing.
- This only alters the User Agent string for any API requests.
type: str
name: name:
description: description:
- Name of the secret to be used - Name of the secret to be used
@ -83,6 +73,10 @@ options:
- key - key
- secret - secret
- secret_id - secret_id
location:
description:
- If provided, it defines the location of the regional secret.
type: str
value: value:
description: description:
- The secret value that the secret should have - The secret value that the secret should have
@ -116,7 +110,6 @@ options:
- only used in creation - only used in creation
- Note that the "value" piece of a label must contain only readable chars - Note that the "value" piece of a label must contain only readable chars
type: dict type: dict
default: {}
notes: notes:
- 'API Reference: U(https://cloud.google.com/secret-manager/docs/reference/rests)' - 'API Reference: U(https://cloud.google.com/secret-manager/docs/reference/rests)'
- 'Official Documentation: U(https://cloud.google.com/secret-manager/docs/overview)' - 'Official Documentation: U(https://cloud.google.com/secret-manager/docs/overview)'
@ -176,6 +169,57 @@ EXAMPLES = r'''
value: super_secret value: super_secret
labels: labels:
key_name: "ansible_rox" key_name: "ansible_rox"
- name: Create a new regional secret
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
value: super_secret
state: present
auth_kind: serviceaccount
service_account_file: service_account_creds.json
- name: Ensure the regional secret exists, fail otherwise and return the value
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
state: present
- name: Ensure regional secret exists but don't return the value
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
state: present
return_value: false
- name: Add a new version of a regional secret
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
value: updated super secret
state: present
- name: Delete version 1 of a regional secret (but not the secret itself)
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
version: 1
state: absent
- name: Delete all versions of a regional secret
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
version: all
state: absent
- name: Create a regional secret with labels
google.cloud.gcp_secret_manager:
name: secret_key
location: us-central1
value: super_secret
labels:
key_name: "ansible_rox"
''' '''
RETURN = r''' RETURN = r'''
@ -183,12 +227,16 @@ resources:
description: List of resources description: List of resources
returned: always returned: always
type: complex type: complex
contains:
name: name:
description: description:
- The name of the secret - The name of the secret
returned: success returned: success
type: str type: str
location:
description:
- The location of the regional secret.
returned: success
type: str
version: version:
description: description:
- the version number of the secret returned - the version number of the secret returned
@ -217,7 +265,7 @@ resources:
payload: payload:
description: description:
- The base 64 secret payload including CRC for validation - The base 64 secret payload including CRC for validation
returned: success retunred: success
type: dict type: dict
''' '''
@ -241,24 +289,30 @@ def get_auth(module):
return GcpSession(module, 'secret-manager') return GcpSession(module, 'secret-manager')
def make_url_prefix(module):
if module.params['location']:
return "https://secretmanager.{location}.rep.googleapis.com/v1/projects/{project}/locations/{location}/"
return "https://secretmanager.googleapis.com/v1/projects/{project}/"
def self_access_link(module): def self_access_link(module):
return "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions/{calc_version}:access".format(**module.params) return (make_url_prefix(module) + "secrets/{name}/versions/{calc_version}:access").format(**module.params)
def self_get_link(module): def self_get_link(module):
return "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions/{calc_version}".format(**module.params) return (make_url_prefix(module) + "secrets/{name}/versions/{calc_version}").format(**module.params)
def self_update_link(module): def self_update_link(module):
return "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions/{calc_version:version}".format(**module.params) return (make_url_prefix(module) + "secrets/{name}/versions/{calc_version:version}").format(**module.params)
def self_list_link(module): def self_list_link(module):
return "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}/versions?filter=state:ENABLED".format(**module.params) return (make_url_prefix(module) + "secrets/{name}/versions?filter=state:ENABLED").format(**module.params)
def self_delete_link(module): def self_delete_link(module):
return "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}".format(**module.params) return (make_url_prefix(module) + "secrets/{name}").format(**module.params)
def fetch_resource(module, allow_not_found=True): def fetch_resource(module, allow_not_found=True):
@ -307,10 +361,12 @@ def merge_dicts(x, y):
def create_secret(module): def create_secret(module):
# build the payload # build the payload
payload = {"replication": {"automatic": {}}} payload = {"replication": {"automatic": {}}}
if module.params['location']:
payload = dict()
if module.params['labels']: if module.params['labels']:
payload['labels'] = module.params['labels'] payload['labels'] = module.params['labels']
url = "https://secretmanager.googleapis.com/v1/projects/{project}/secrets".format(**module.params) url = (make_url_prefix(module) + "secrets").format(**module.params)
auth = get_auth(module) auth = get_auth(module)
post_response = auth.post(url, body=payload, params={'secretId': module.params['name']}) post_response = auth.post(url, body=payload, params={'secretId': module.params['name']})
# validate create # validate create
@ -327,7 +383,7 @@ def update_secret(module):
} }
} }
auth = get_auth(module) auth = get_auth(module)
url = "https://secretmanager.googleapis.com/v1/projects/{project}/secrets/{name}:addVersion".format(**module.params) url = (make_url_prefix(module) + "secrets/{name}:addVersion").format(**module.params)
return return_if_object(module, auth.post(url, payload), False) return return_if_object(module, auth.post(url, payload), False)
@ -376,6 +432,10 @@ def return_if_object(module, response, allow_not_found=False):
result['status_code'] = response.status_code result['status_code'] = response.status_code
if "name" in result: if "name" in result:
result['version'] = result['name'].split("/")[-1] result['version'] = result['name'].split("/")[-1]
if 'locations' in result['name'].split("/"):
result['location'] = result['name'].split("/")[3]
result['name'] = result['name'].split("/")[5]
else:
result['name'] = result['name'].split("/")[3] result['name'] = result['name'].split("/")[3]
# base64 decode the value # base64 decode the value
@ -401,6 +461,7 @@ def main():
argument_spec=dict( argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'), state=dict(default='present', choices=['present', 'absent'], type='str'),
name=dict(required=True, type='str', aliases=['key', 'secret', 'secret_id']), name=dict(required=True, type='str', aliases=['key', 'secret', 'secret_id']),
location=dict(required=False, type='str'),
value=dict(required=False, type='str'), value=dict(required=False, type='str'),
version=dict(required=False, type='str', default='latest'), version=dict(required=False, type='str', default='latest'),
return_value=dict(required=False, type='bool', default=True), return_value=dict(required=False, type='bool', default=True),

View file

@ -0,0 +1 @@
cloud/gcp

View file

@ -0,0 +1,3 @@
---
resource_name: "{{ resource_prefix }}"
lookup_resource_name: "{{ resource_prefix }}_lookup"

View file

@ -0,0 +1,9 @@
---
- name: Secrets tests
ansible.builtin.include_tasks: secrets.yml
- name: Secrets lookup tests
ansible.builtin.include_tasks: secretslookup.yml
- name: Regional Secrets tests
ansible.builtin.include_tasks: regionalsecrets.yml
- name: Regional Secrets lookup tests
ansible.builtin.include_tasks: regionalsecretslookup.yml

View file

@ -0,0 +1,146 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Pre-test setup
- name: Delete the regional test secret if it exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "all"
location: "us-central1"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
# ----------------------------------------------------------
- name: Create a regional secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
value: "ansible-test-regional-secret-value"
labels:
key1: "val1"
key2: "val2"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create a regional secret that already exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
value: "ansible-test-regional-secret-value"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Add a new version to a regional secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
value: "ansible-test-regional-secret-value-updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Add a version that exists to a regional secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
value: "ansible-test-regional-secret-value-updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Ensure the regional secret exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Delete the regional secret version
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
version: "1"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Delete the regional secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Delete the regional secret that does not exist
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
location: "us-central1"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false

View file

@ -0,0 +1,76 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Pre-test setup
- name: Delete the regional test secret if it exists
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
version: "all"
location: "us-central1"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
- name: Create a regional secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
location: "us-central1"
value: "ansible lookup test regional secret value"
labels:
key1: "val1"
key2: "val2"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
- name: Add a new version to a regional secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
location: "us-central1"
value: "ansible lookup test regional secret value updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
# ----------------------------------------------------------
- name: Retrieve the latest secret version of a regional secret
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key=lookup_resource_name, location='us-central1', project=gcp_project, auth_kind=gcp_cred_kind, service_account_file=gcp_cred_file | default(omit)) }}"
register: result
- name: Assert secret value
ansible.builtin.assert:
that:
- result.msg == "ansible lookup test regional secret value updated"
# ----------------------------------------------------------
- name: Retrieve the specified secret version of a regional secret
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key=lookup_resource_name, location='us-central1', version='1', project=gcp_project, auth_kind=gcp_cred_kind, service_account_file=gcp_cred_file | default(omit)) }}"
register: result
- name: Assert secret value
ansible.builtin.assert:
that:
- result.msg == "ansible lookup test regional secret value"
# ---------------------------------------------------------
# Post-test teardown
# If errors happen, don't crash the playbook!
- name: Delete the regional test secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
location: "us-central1"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
ignore_errors: true

View file

@ -0,0 +1,137 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Pre-test setup
- name: Delete the test secret if it exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
# ----------------------------------------------------------
- name: Create a secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value"
labels:
key1: "val1"
key2: "val2"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Create a secret that already exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Add a new version to a secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value-updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Add a version that exists to a secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
value: "ansible-test-secret-value-updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Ensure the secret exists
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false
# ----------------------------------------------------------
- name: Delete the secret version
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "1"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Delete the secret
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is true
ansible.builtin.assert:
that:
- result.changed == true
# ----------------------------------------------------------
- name: Delete the secret that does not exist
google.cloud.gcp_secret_manager:
name: "{{ resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
register: result
- name: Assert changed is false
ansible.builtin.assert:
that:
- result.changed == false

View file

@ -0,0 +1,72 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
# Pre-test setup
- name: Delete the test secret if it exists
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
- name: Create a secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
value: "ansible lookup test secret value"
labels:
key1: "val1"
key2: "val2"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
- name: Add a new version to a secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
value: "ansible lookup test secret value updated"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: present
# ----------------------------------------------------------
- name: Retrieve the latest secret version of a secret
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key=lookup_resource_name, project=gcp_project, auth_kind=gcp_cred_kind, service_account_file=gcp_cred_file | default(omit)) }}"
register: result
- name: Assert secret value
ansible.builtin.assert:
that:
- result.msg == "ansible lookup test secret value updated"
# ----------------------------------------------------------
- name: Retrieve the specified secret version of a secret
ansible.builtin.debug:
msg: "{{ lookup('google.cloud.gcp_secret_manager', key=lookup_resource_name, version='1', project=gcp_project, auth_kind=gcp_cred_kind, service_account_file=gcp_cred_file | default(omit)) }}"
register: result
- name: Assert secret value
ansible.builtin.assert:
that:
- result.msg == "ansible lookup test secret value"
# ---------------------------------------------------------
# Post-test teardown
# If errors happen, don't crash the playbook!
- name: Delete the test secret
google.cloud.gcp_secret_manager:
name: "{{ lookup_resource_name }}"
version: "all"
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file | default(omit) }}"
state: absent
ignore_errors: true