#!/usr/bin/env python3 """Assemble individual GitLab CI/CD variables into a temporary Ansible vars file. Reads a fixed allowlist of environment variables (injected by GitLab from masked CI/CD variables), maps them to their Ansible names, and writes them to a YAML vars file for ``--extra-vars @``. An optional private key is written to a separate 0600 file for ``--private-key``. Values never appear on the process command line or in this script's output. Only the allowlisted variable names are consumed; everything else is ignored. """ import argparse import os import stat from pathlib import Path import yaml # GitLab variable name -> Ansible variable name. Extend this mapping when a new # connection variable needs to be supplied per environment. VAR_MAP = { "ANSIBLE_USER": "ansible_user", "ANSIBLE_PASSWORD": "ansible_password", "ANSIBLE_BECOME_PASSWORD": "ansible_become_password", "VCENTER_HOSTNAME": "vcenter_hostname", "VCENTER_USERNAME": "vcenter_username", "VCENTER_PASSWORD": "vcenter_password", } PRIVATE_KEY_ENV = "ANSIBLE_PRIVATE_KEY" VARS_FILENAME = "ansible-vars.yml" KEY_FILENAME = "ansible-private-key" def write_secret_file(path: Path, data: bytes) -> None: path.write_bytes(data) path.chmod(stat.S_IRUSR | stat.S_IWUSR) def main() -> int: parser = argparse.ArgumentParser() parser.add_argument( "--out-dir", type=Path, required=True, help="Directory for the generated vars file and private key", ) args = parser.parse_args() args.out_dir.mkdir(parents=True, exist_ok=True) os.chmod(args.out_dir, stat.S_IRWXU) variables = { ansible_name: os.environ[gitlab_name] for gitlab_name, ansible_name in VAR_MAP.items() if os.environ.get(gitlab_name) } private_key = os.environ.get(PRIVATE_KEY_ENV) if not variables and not private_key: raise SystemExit( "no Ansible secrets were provided. Define at least one of " + ", ".join(VAR_MAP) + f" or {PRIVATE_KEY_ENV} as an environment-scoped CI/CD variable." ) vars_file = args.out_dir / VARS_FILENAME write_secret_file( vars_file, yaml.safe_dump(variables, sort_keys=True, default_flow_style=False).encode( "utf-8" ), ) print(f"Wrote Ansible variables to {vars_file}") if private_key: key_data = ( Path(private_key).read_bytes() if os.path.isfile(private_key) else private_key.encode("utf-8") ) key_file = args.out_dir / KEY_FILENAME write_secret_file(key_file, key_data) print(f"Wrote private key to {key_file}") return 0 if __name__ == "__main__": raise SystemExit(main())