Compare commits

...

19 commits

Author SHA1 Message Date
Daniel Hougaard
7f992d3e59 Update distribute.yaml 2025-07-23 02:03:54 +04:00
Daniel Hougaard
89ab21f235 feat: ansible docker image 2025-07-23 02:01:52 +04:00
Daniel Hougaard
510e8c666f
Update read_secrets.py 2025-01-23 23:41:24 +01:00
Daniel Hougaard
728bc04de1
Merge pull request #11 from Infisical/daniel/update-sdk
feat: update SDK to use new Python SDK
2025-01-23 18:24:02 +01:00
Daniel Hougaard
189c664df7 Update read_secrets.py 2025-01-23 05:00:50 +01:00
Daniel Hougaard
50e046d71e Fix: Potential fix for publishing failing 2024-04-26 20:09:52 +02:00
Daniel Hougaard
3f11722a9d Update distribute.yaml 2024-04-26 06:36:42 +02:00
Daniel Hougaard
59f556f769 Update distribute.yaml 2024-04-26 06:05:44 +02:00
Daniel Hougaard
324514d92e Test release 2024-04-26 06:02:58 +02:00
Daniel Hougaard
29d09a401d
Merge pull request #4 from Infisical/daniel/upgrade-to-new-sdk
Feat: Upgrade to new Python SDK
2024-03-11 15:58:46 +01:00
Daniel Hougaard
054c8eecda Update README.md 2024-03-11 15:03:21 +01:00
Daniel Hougaard
3734effe53 Feat: Update to new Python SDK 2024-03-11 15:00:47 +01:00
Daniel Hougaard
4bda5c777a Create .gitignore 2024-03-11 15:00:38 +01:00
Maidul Islam
414ce80fc3
Update README.md 2023-12-20 13:00:14 -05:00
Maidul Islam
dd71333296
Merge pull request #2 from ku9nov/main
Fixed fetching single secret bug; updated the name variable name in README to be correct.
2023-12-01 12:16:53 -05:00
ku9nov
8d44160447 fix get single secret bug, upd secret_name variable 2023-11-30 16:56:13 +02:00
Maidul Islam
c154f3a039
Update README.md 2023-11-09 18:54:12 -06:00
Maidul Islam
521d5f9a95
update namespace 2023-11-08 22:07:19 -06:00
Maidul Islam
aa65ac1bef
Update README.md 2023-11-06 20:34:57 -06:00
6 changed files with 146 additions and 45 deletions

View file

@ -1,21 +1,47 @@
---
name: Deploy Collection
# Trigger the workflow however you prefer
on:
release:
types:
- published
push:
tags:
- "*.*.*"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Get the version name from the tags
run: echo "RELEASE_VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
- name: Build and Deploy Collection
uses: artis3n/ansible_galaxy_collection@v2
with:
api_key: "${{ secrets.GALAXY_API_KEY }}"
galaxy_version: "${{ env.RELEASE_VERSION }}"
release-galaxy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build and Deploy Collection
uses: artis3n/ansible_galaxy_collection@v2
with:
api_key: "${{ secrets.GALAXY_API_KEY }}"
galaxy_version: "${{ github.ref_name }}"
release-docker:
needs: release-galaxy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 🔧 Set up QEMU
uses: docker/setup-qemu-action@v1
- name: 🔧 Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: 🐋 Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
build-args: VERSION=${{ github.ref_name }}
context: docker
push: true
platforms: linux/amd64,linux/arm64
tags: |
infisical/ansible-collection:latest
infisical/ansible-collection:${{ github.ref_name }}

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
.venv/**/*
ansible.cfg
inventory
test.yml
__pycache__
infisical-vault-1.0.0.tar.gz

View file

@ -1,6 +1,8 @@
# Infisical Collection
This Ansible Infisical collection includes a variety of Ansible content to help automate the management of Infisical services. This collection is maintained by the Infisical team.
[View full documentation](https://galaxy.ansible.com/ui/repo/published/infisical/vault/)
## Ansible version compatibility
Tested with the Ansible Core >= 2.12.0 versions, and the current development version of Ansible. Ansible Core versions prior to 2.12.0 have not been tested.
@ -15,12 +17,12 @@ Requires Python 3.7 or greater.
You can install the Infisical collection with the Ansible Galaxy CLI:
ansible-galaxy collection install maidul98.infisical_vault
ansible-galaxy collection install infisical.vault
The python module dependencies are not installed by `ansible-galaxy`. They can
be manually installed using pip:
pip install infisical
pip install infisical-python
## Using this collection
@ -29,10 +31,10 @@ You can either call modules by their Fully Qualified Collection Name (FQCN), suc
```yaml
---
vars:
read_all_secrets_within_scope: "{{ lookup('infisical.vault.read_secrets', token='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}"
read_all_secrets_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}"
# [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }]
read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', token='<>', path='/', env_slug='dev', name='HOST', url='https://spotify.infisical.com') }}"
read_secret_by_name_within_scope: "{{ lookup('infisical.vault.read_secrets', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}"
# [{ "key": "HOST", "value": "google.com" }]
```

25
docker/Dockerfile Normal file
View file

@ -0,0 +1,25 @@
FROM python:3.11-slim
ENV PYTHONUNBUFFERED=1
ENV ANSIBLE_HOST_KEY_CHECKING=false
ENV ANSIBLE_STDOUT_CALLBACK=yaml
ENV ANSIBLE_CALLBACKS_ENABLED=profile_tasks
ARG VERSION
RUN apt-get update && apt-get install -y \
git \
openssh-client \
sshpass \
&& rm -rf /var/lib/apt/lists/*
RUN pip install --no-cache-dir ansible infisicalsdk
RUN ansible-galaxy collection install infisical.vault==${VERSION}
WORKDIR /ansible
RUN mkdir -p /root/.ansible
# Set default command
CMD ["/bin/bash"]

View file

@ -2,7 +2,7 @@
# The namespace of the collection. This can be a company/brand/organization or product namespace under which all
# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with
# underscores or numbers and cannot contain consecutive underscores
namespace: infisical_inc
namespace: infisical
# The name of the collection. Has the same character restrictions as 'namespace'
name: vault
@ -62,7 +62,7 @@ issues: https://github.com/Infisical/ansible-collection/issues
# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This
# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry',
# and '.git' are always filtered. Mutually exclusive with 'manifest'
build_ignore: []
build_ignore: ["/docker/*"]
# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a
# list of MANIFEST.in style
# L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key

View file

@ -3,9 +3,9 @@ from ansible.plugins.lookup import LookupBase
HAS_INFISICAL = False
try:
from infisical import InfisicalClient
from infisical_sdk import InfisicalSDKClient
HAS_INFISICAL = True
except ImportError:
except ImportError as e:
HAS_INFISICAL = False
DOCUMENTATION = r"""
@ -19,10 +19,17 @@ description:
- Secrets can be located either by their name for individual secret loopups or by environment/folder path to return all secrets within the given scope.
options:
token:
description: The Infisical token used to authenticate
universal_auth_client_id:
description: The Machine Identity Client ID used to authenticate
env:
- name: INFISICAL_TOKEN
- name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_ID
required: True
type: string
version_added: 1.0.0
universal_auth_client_secret:
description: The Machine Identity Client Secret used to authenticate
env:
- name: UNIVERSAL_AUTH_MACHINE_IDENTITY_CLIENT_SECRET
required: True
type: string
version_added: 1.0.0
@ -44,6 +51,11 @@ options:
required: True
type: string
version_added: 1.0.0
project_id:
description: "The ID of the project where the secrets are stored"
required: True
type: string
version_added: 1.0.0
secret_name:
description: The name of the secret that should be fetched. The name should be exactly as it appears in Infisical
required: False
@ -53,51 +65,81 @@ options:
EXAMPLES = r"""
vars:
read_all_secrets_within_scope: "{{ lookup('infisical_vault', token='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}"
read_all_secrets_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', url='https://spotify.infisical.com') }}"
# [{ "key": "HOST", "value": "google.com" }, { "key": "SMTP", "value": "gmail.smtp.edu" }]
read_secret_by_name_within_scope: "{{ lookup('infisical_vault', token='<>', path='/', env_slug='dev', name='HOST', url='https://spotify.infisical.com') }}"
read_secret_by_name_within_scope: "{{ lookup('infisical_vault', universal_auth_client_id='<>', universal_auth_client_secret='<>', project_id='<>', path='/', env_slug='dev', secret_name='HOST', url='https://spotify.infisical.com') }}"
# [{ "key": "HOST", "value": "google.com" }]
"""
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):
self.set_options(var_options=variables, direct=kwargs)
if not HAS_INFISICAL:
raise AnsibleError("Please pip install infisical to use the infisical_vault lookup module.")
raise AnsibleError("Please pip install infisicalsdk to use the infisical_vault lookup module.")
infisical_token = self.get_option("token")
machine_identity_client_id = self.get_option("universal_auth_client_id")
machine_identity_client_secret = self.get_option("universal_auth_client_secret")
url = self.get_option("url")
if not infisical_token:
raise AnsibleError("Infisical token is required")
# Check if the required environment variables are set
if not machine_identity_client_id or not machine_identity_client_secret:
raise AnsibleError("Please provide the universal_auth_client_id and universal_auth_client_secret")
# Initialize the Infisical client
client = InfisicalClient(token=infisical_token, site_url=url)
client = InfisicalSDKClient(host=url)
client.auth.universal_auth.login(
machine_identity_client_id,
machine_identity_client_secret
)
secretName = kwargs.get('secret_name')
envSlug = kwargs.get('env_slug')
path = kwargs.get('path')
project_id = kwargs.get('project_id')
if secretName:
return self.get_single_secret(client, secretName, envSlug, path)
return self.get_single_secret(
client,
project_id,
secretName,
envSlug,
path
)
else:
return self.get_all_secrets(client, envSlug, path)
return self.get_all_secrets(client, project_id, envSlug, path)
def get_single_secret(self, client, secret_name, environment, path):
def get_single_secret(
self,
client,
project_id,
secret_name,
environment,
path
):
try:
print(secret_name, environment, path)
secret = client.get_secret(secret_name=secret_name, environment=environment, path=path)
return [{"value": s.secret_value, "key": s.secret_name}]
secret = client.secrets.get_secret_by_name(
secret_name=secret_name,
project_id=project_id,
environment_slug=environment,
secret_path=path
)
return [{"value": secret.secretValue, "key": secret.secretKey}]
except Exception as e:
print(e)
raise AnsibleError(f"Error fetching all secrets {e}")
raise AnsibleError(f"Error fetching single secret {e}")
def get_all_secrets(self, client, environment="dev", path="/"):
def get_all_secrets(self, client, project_id, environment="dev", path="/"):
try:
secrets = client.get_all_secrets(environment=environment, path=path)
return [{"value": s.secret_value, "key": s.secret_name} for s in secrets]
secrets = client.secrets.list_secrets(
project_id=project_id,
environment_slug=environment,
secret_path=path
)
return [{"value": s.secretValue, "key": s.secretKey} for s in secrets.secrets]
except Exception as e:
raise AnsibleError(f"Error fetching all secrets {e}")