Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding gcp auth module for ansible vault lookups #54911

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions lib/ansible/plugins/lookup/hashi_vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
description: Secret id for a vault AppRole auth.
env:
- name: VAULT_SECRET_ID
service_account_email:
description: GCP Service account email for GCP Auth.
service_account_file:
description: Path to the GCP service account json file for GCP Auth.
expiry_length:
description: JWT Expiry length for GCP Auth.
default: 900
auth_method:
description:
- Authentication method to be used.
Expand All @@ -51,6 +58,7 @@
- userpass
- ldap
- approle
- gcp
mount_point:
description: vault mount point, only required if you have a custom mount point.
default: ldap
Expand Down Expand Up @@ -93,7 +101,15 @@

- name: authenticate with a Vault app role
debug:
msg: "{{ lookup('hashi_vault', 'secret=secret/hello:value auth_method=approle role_id=myroleid secret_id=mysecretid url=http://myvault:8200')}}"
msg: "{{ lookup('hashi_vault', 'secret=secret/hello:value
auth_method=approle
role_id=myroleid
service_account_email=serviceacccount@project.iam.gserviceaccount.com
service_account_file=/tmp/gcp_service_account.json url=http://myvault:8200')}}"

- name: authenticate with GCP auth
debug:
msg: "{{ lookup('hashi_vault', 'secret=secret/hello:value auth_method=gcp role_id=myroleid secret_id=mysecretid url=http://myvault:8200')}}"

- name: Return all secrets from a path in a namespace
debug:
Expand All @@ -107,6 +123,7 @@
"""

import os
import time

from ansible.errors import AnsibleError
from ansible.module_utils.parsing.convert_bool import boolean
Expand All @@ -119,6 +136,13 @@
except ImportError:
HAS_HVAC = False

HAS_GCP_API = False
try:
import google.auth.crypt
import google.auth.jwt
HAS_GCP_API = True
except ImportError:
HAS_GCP_API = False

ANSIBLE_HASHI_VAULT_ADDR = 'http://127.0.0.1:8200'

Expand All @@ -131,7 +155,7 @@ def __init__(self, **kwargs):

self.url = kwargs.get('url', ANSIBLE_HASHI_VAULT_ADDR)
self.namespace = kwargs.get('namespace', None)
self.avail_auth_method = ['approle', 'userpass', 'ldap']
self.avail_auth_method = ['approle', 'userpass', 'ldap', 'gcp']

# split secret arg, which has format 'secret/hello:value' into secret='secret/hello' and secret_field='value'
s = kwargs.get('secret')
Expand Down Expand Up @@ -251,6 +275,32 @@ def auth_approle(self, **kwargs):

self.client.auth_approle(role_id, secret_id)

def auth_gcp(self, service_account_email, service_account_file, expiry_length=900, **kwargs):
if not HAS_GCP_API:
raise AnsibleError("Please pip install google-api-python-client to use GCP authentication.")

role_id = kwargs.get('role_id', os.environ.get('VAULT_ROLE_ID', None))

if role_id is None:
raise AnsibleError("Authentication method app role requires a role_id")

now = int(time.time())
audience = "vault/%s" % role_id

payload = {
'iat': now,
"exp": now + expiry_length,
'iss': service_account_email,
'aud': audience,
'sub': service_account_email,
'email': service_account_email
}

signer = google.auth.crypt.RSASigner.from_service_account_file(service_account_file)
jwt = google.auth.jwt.encode(signer, payload)

self.client.auth.gcp.login(role_id, jwt.decode())


class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
Expand Down