{"id":15046124,"url":"https://github.com/roche/gitlab-configuration-as-code","last_synced_at":"2025-10-26T02:31:13.814Z","repository":{"id":45937124,"uuid":"221479942","full_name":"Roche/gitlab-configuration-as-code","owner":"Roche","description":"Manage GitLab configuration as code to make GitLab easily managable, traceable and reproducible.","archived":false,"fork":false,"pushed_at":"2022-08-01T12:18:52.000Z","size":191,"stargazers_count":49,"open_issues_count":0,"forks_count":5,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-01-31T13:43:39.796Z","etag":null,"topics":["configuration-as-code","configuration-management","gitlab","gitlab-api","yaml"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Roche.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null}},"created_at":"2019-11-13T14:37:37.000Z","updated_at":"2025-01-25T22:37:46.000Z","dependencies_parsed_at":"2022-09-26T21:31:45.504Z","dependency_job_id":null,"html_url":"https://github.com/Roche/gitlab-configuration-as-code","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roche%2Fgitlab-configuration-as-code","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roche%2Fgitlab-configuration-as-code/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roche%2Fgitlab-configuration-as-code/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Roche%2Fgitlab-configuration-as-code/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Roche","download_url":"https://codeload.github.com/Roche/gitlab-configuration-as-code/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238247984,"owners_count":19440879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration-as-code","configuration-management","gitlab","gitlab-api","yaml"],"created_at":"2024-09-24T20:52:44.418Z","updated_at":"2025-10-26T02:31:13.456Z","avatar_url":"https://github.com/Roche.png","language":"Python","readme":"![CI/CD](https://github.com/Roche/gitlab-configuration-as-code/workflows/CI/CD/badge.svg)\n[![Docker Pull count](https://img.shields.io/docker/pulls/hoffmannlaroche/gcasc)](https://hub.docker.com/r/hoffmannlaroche/gcasc)\n[![PyPI](https://img.shields.io/pypi/v/gitlab-configuration-as-code)](https://pypi.org/project/gitlab-configuration-as-code)\n[![Documentation Status](https://readthedocs.org/projects/gitlab-configuration-as-code/badge/?version=latest)](https://gitlab-configuration-as-code.readthedocs.io/en/latest/?badge=latest)\n[![Last Commit](https://img.shields.io/github/last-commit/Roche/gitlab-configuration-as-code)]()\n[![Python versions](https://img.shields.io/badge/python-3.6%20%7C%203.7%20%7C%203.8-blue)]()\n[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE)\n\n# GitLab Configuration as Code (*GCasC*)\n\nManage GitLab configuration as code to make it easily manageable, traceable and reproducible.\n\n### Table of Contents\n\n* [Introduction](#introduction)\n* [Quick start](#quick-start)\n   * [Configure client](#configure-client)\n   * [Prepare GitLab configuration](#prepare-gitlab-configuration)\n   * [Run GCasC](#run-gcasc)\n       * [CLI](#cli)\n       * [Docker image](#docker-image)\n   * [Examples](#examples)\n* [Building](#building)\n   * [Docker image](#docker-image-1)\n   * [Python package](#python-package)\n* [Testing](#testing)\n* [Contribution](#contribution)\n* [License](#license)\n\n## Introduction\n\nWhen configuring your GitLab instance, part of the settings you put in [Omnibus](https://docs.gitlab.com/12.7/omnibus/settings/README.html)\nor [Helm Chart](https://docs.gitlab.com/charts/charts/) configuration, and the rest you configure through GitLab UI\nor [API](https://docs.gitlab.com/12.7/ee/api/settings.html). Due to tons of configuration options in UI,\nmaking GitLab work as you intend is a complex process.\n\nWe intend to let you automate things you do through now UI in a simple way. The Configuration as Code\nhas been designed to configure GitLab based on human-readable declarative configuration files written in Yaml.\nWriting such a file should be feasible without being a GitLab expert, just translating into code a configuration\nprocess one is used to executing in the web UI.\n\n_GCasC_ offers a functionality to configure:\n* [appearance](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration/appearance.html)\n* [application settings](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration/application_settings.html)\n* [features](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration/features.html)\n* [Instance CI/CD variables](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration/instance_variables.html)\n* [license](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration/license.html)\n* ... more coming soon!\n\nIt gives you also a way to:\n* include external files or other Yamls using `!include` directive\n* inject environment variables into configuration using `!env` directive\ninto your Yaml configuration.\n\nVisit [our documentation site](https://gitlab-configuration-as-code.readthedocs.io/) for detailed information on how to use it.\n\nConfiguring your GitLab instance is as simple as this:\n```yaml\nappearance:\n  title: \"Your GitLab instance title\"\n  logo: \"http://path-to-your-logo/logo.png\"\n\nsettings:\n  elasticsearch:\n    url: http://elasticsearch.mygitlab.com\n    username: !env ELASTICSEARCH_USERNAME\n    password: !env ELASTICSEARCH_PASSWORD\n  recaptcha_enabled: yes\n  terms: '# Terms of Service\\n\\n *GitLab rocks*!!'\n  plantuml:\n    enabled: true\n    url: 'http://plantuml.url'\n\ninstance_variables:\n  anotherVariable: 'another value'\n  MY_VARIABLE:\n    value: !env MY_VARIABLE\n    protected: false\n    masked: true\n\nfeatures:\n  - name: sourcegraph\n    value: true\n    groups:\n      - mygroup1\n    projects:\n      - mygroup2/myproject\n    users:\n      - myuser\n\nlicense:\n  starts_at: 2019-11-17\n  expires_at: 2019-12-17\n  plan: premium\n  user_limit: 30\n  data: !include gitlab.lic\n```\n\n**Note:** GCasC supports only Python 3+. Because Python 2.7 end of life is January 1st, 2020 we do not consider support\nfor Python 2.\n\n## Quick start\n\nHere you will learn how to quickly start with _GCasC_.\n\n**Important!** Any execution of _GCasC_ may override properties you define in your Yaml files. Don't try it directly\non your production environment.\n\nVisit [our documentation site](https://gitlab-configuration-as-code.readthedocs.io/) for detailed information on how to use it.\n\n### Configure client\n\nYou can configure client in two ways:\n\n* using configuration file:\n    ```\n    [global]\n    url = https://gitlab.yourdomain.com\n    ssl_verify = true\n    timeout = 5\n    private_token = \u003cpersonal_access_token\u003e\n    api_version = 4\n    ```\n    By default _GCasC_ is trying to find client configuration file in following paths:\n    ```\n    \"/etc/python-gitlab.cfg\",\n    \"/etc/gitlab.cfg\",\n    \"~/.python-gitlab.cfg\",\n    \"~/.gitlab.cfg\",\n    ```\nB \n    You can provide a path to your configuration file in `GITLAB_CLIENT_CONFIG_FILE` environment variable.\n\n* using environment variables:\n    ```bash\n    GITLAB_CLIENT_URL=\u003cgitlab_url\u003e # path to GitLab, default: https://gitlab.com\n    GITLAB_CLIENT_API_VERSION=\u003cgitlab_api_version\u003e # GitLab API version, default: 4\n    GITLAB_CLIENT_TOKEN=\u003cpersonal_access_token\u003e # GitLab personal access token\n    GITLAB_CLIENT_SSL_VERIFY=\u003cssl_verify\u003e # Flag if SSL certificate should be verified, default: true\n    ```\n\nYou can combine both methods and configuration settings will be searched in the following order:\n\n* configuration file\n* environment variables (due to limitations in `python-gitlab` if using configuration file only `GITLAB_CLIENT_TOKEN`\n  environment variable will be used)\n\nPersonal access token is mandatory in any client configuration approach and you can configure your it by following\n[these instructions](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html)\n\nAdditionally you can customize HTTP session to enable mutual TLS authentication. To configure this, you should\nprovide two additional environment variables:\n```bash\nGITLAB_CLIENT_CONFIG_FILE=\u003cpath_to_client_certificate\u003e\nGITLAB_CLIENT_KEY=\u003cpath_to_client_key\u003e\n```\n\n### Prepare GitLab configuration\n\nGitLab configuration must be defined in Yaml file. You can provide a configuration in a single file, or you can\nsplit it into multiple Yaml files and inject them.\n\nFor information how to prepare GitLab configuration Yaml file visit\n[our documentation site](https://gitlab-configuration-as-code.readthedocs.io/en/latest/configuration).\n\nFor `settings` configuration, which defines [Application Settings](https://docs.gitlab.com/12.7/ee/api/settings.html),\nthe structure is flexible. For example\n\n```yaml\nsettings:\n  elasticsearch:\n    url: http://elasticsearch.mygitlab.com\n    username: elastic_user\n    password: elastic_password\n```\n\nand\nB \n```yaml\nsettings:\n  elasticsearch_url: http://elasticsearch.mygitlab.com\n  elasticsearch_username: elastic_user\n  elasticsearch_password: elastic_password\n```\nare exactly the same and match `elasticsearch_url`, `elasticsearch_username` and `elasticsearch_password` settings.\nThis means you can flexibly structure your configuration Yaml, where a map child keys are prefixed by parent key (here\n`elasticsearch` parent key was a prefix for `url`, `username` and `password` keys). You only need to follow available\n[Application Settings](https://docs.gitlab.com/12.7/ee/api/settings.html).\n\nYou can adjust your Yamls by splitting them into multiple or injecting environment variables into certain values using\n`!include` or `!env` directives respectively. Example is shown below:\n\n```yaml\nsettings:\n  elasticsearch:\n    url: http://elasticsearch.mygitlab.com\n    username: !env ELASTICSEARCH_USERNAME\n    password: !env ELASTICSEARCH_PASSWORD\n  terms: !include tos.md\n\nlicense: !include license.yml\n```\n\nwhere:\n\n* `settings.elasticsearch.username` and `settings.elasticsearch.password` are injected from environment variables\n`ELASTICSEARCH_USERNAME` and `ELASTICSEARCH_PASSWORD` respectively\n\n* `settings.terms` and `license` are injected from `tos.md` plain text file and `license.yml` Yaml file respectively.\nIn this scenario, your `license.yml` may look like this:\n```yaml\nstarts_at: 2019-11-17\nexpires_at: 2019-12-17\nplan: premium\nuser_limit: 30\ndata: !include gitlab.lic\n```\n\n### Run GCasC\n\nTo run _GCasC_ you can leverage CLI or Docker image. _Docker image is a preferred way_, because it is simple\nand does not require from you installing any additional libraries. Also, Docker image was designed that it can be\neasily used in your CI/CD pipelines.\n\nWhen running locally, you may benefit from running _GCasC_ in TEST mode (default mode is `APPLY`), where no changes\nwill be applied, but validation will be performed and differences will be logged. Just set `GITLAB_MODE`\nenvironment variable to `TEST`.\n```bash\nexport GITLAB_MODE=TEST\n```\n\n#### CLI\n\n_GCasC_ library is available in [PyPI](https://pypi.org/project/gitlab-configuration-as-code/).\n\nTo install CLI run `pip install gitlab-configuration-as-code`. Then you can simply execute\n```bash\ngcasc\n```\n\n//TODO add more information on CLI usage\n\nCurrently, CLI is limited and does not support passing any arguments to it, but behavior can only be configured\nusing environment variables. Support for CLI arguments may appear in future releases.\n\n#### Docker image\n\nImage is available in [Docker Hub](https://hub.docker.com/r/hoffmannlaroche/gcasc).\n\n_GCasC_ Docker image working directory is `/workspace`. Thus you can quickly launch `gcasc` with:\n```bash\ndocker run -v $(pwd):/workspace hoffmannlaroche/gcasc\n```\nIt will try to find both GitLab client configuration and GitLab configuration in `/workspace` directory. You can modify\nthe behavior by passing environment variables:\n* `GITLAB_CLIENT_CONFIG_FILE` to provide path to GitLab client configuration file\n* `GITLAB_CONFIG_FILE` to provide a path to GitLab configuration file\n\n```bash\ndocker run -e GITLAB_CLIENT_CONFIG_FILE=/gitlab/client.cfg -e GITLAB_CONFIG_FILE=/gitlab/config.yml\n-v $(pwd):/gitlab hoffmannlaroche/gcasc\n```\n\nYou can also configure a GitLab client using environment variables. More details about the configuration of GitLab client\nare available [in this documentation](https://gitlab-configuration-as-code.readthedocs.io/en/latest/client.html).\n\n### Examples\n\nWe provide a few examples to give you a quick starting place to use _GCasC_. They can be found in [`examples`](examples) directory.\n1. [`gitlab.cfg`](examples/gitlab.cfg) is example GitLab client file configuration.\n2. [`basic`](examples/basic/gitlab.yml) is an example GitLab configuration using a single configuration file.\n3. [`environment_variables`](examples/environment_variables) shows how environment variables can be injected\ninto GitLab configuration file using `!env` directive.\n4. [`modularized`](examples/modularized) shows how you can split single GitLab configuration file into smaller\nand inject files containing static text using `!include` directive.\n\n## Building\n\n### Docker image\n\nUse `make` to build a basic Docker image quickly.\n```bash\nmake docker-build\n```\nWhen using `make` you can additionally pass `DOCKER_IMAGE_NAME` to change default `gcasc:latest` to another image name:\n```bash\nmake docker-build DOCKER_IMAGE_NAME=mygcasc:1.0\n```\n\nTo get more control over builds you can use `docker build` directly:\n```bash\ndocker builds -t gcasc[:TAG] .\n```\n\nDockerfile comes with two build arguments you may use to customize your image by providing `--build-arg` parameter\nto `docker build` command:\n* `GCASC_PATH` defines the path where _GCasC_ library will be copied. Defaults to `/opt/gcasc`.\n* `WORKSPACE` defines a working directory when you run _GCasC_ image. Defaults to `/workspace`.\n\n### Python package\n\nUse `make` to build source distribution (sdist), Wheel binary distribution and Sphinx documentation.\n```bash\nmake build\n```\nBoth source and Wheel distributions will be placed in `dist` directory. Documentation page will be placed\nin `build/docs` directory.\n\nRemember to run tests before building your distribution!\n\n## Testing\n\nBefore submitting a pull request make sure that the tests still succeed with your change.\nUnit tests run using Github Actions and passing tests are mandatory\nto get merge requests accepted.\n\nYou need to install `tox` to run unit tests locally:\n\n```bash\n# run the unit tests for python 3, python 2, and the flake8 tests:\ntox\n\n# run tests in one environment only:\ntox -e py37\n\n# run flake8 linter and black code formatter\ntox -e flake\n\n# run black code formatter\ntox -e black\n```\n\nInstead of using `tox` directly, it is recommended to use `make`:\n```bash\n# run tests\nmake test\n\n# run flake8 linter and black code formatter\nmake lint\n```\n\n## Contribution\n\nEveryone is warm welcome to contribute!\n\nPlease make sure to read the [Contributing Guide](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md)\nbefore making a pull request.\n\n### Contributors\n\n\u003c!-- readme: contributors -start --\u003e \n\u003ctable\u003e\n\u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://github.com/filipowm\"\u003e\n            \u003cimg src=\"https://avatars.githubusercontent.com/u/20795389?v=4\" width=\"80;\" alt=\"filipowm\"/\u003e\n            \u003cbr /\u003e\n            \u003csub\u003e\u003cb\u003eMateusz\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://github.com/randombenj\"\u003e\n            \u003cimg src=\"https://avatars.githubusercontent.com/u/5184499?v=4\" width=\"80;\" alt=\"randombenj\"/\u003e\n            \u003cbr /\u003e\n            \u003csub\u003e\u003cb\u003eBenj Fassbind\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://github.com/11mariom\"\u003e\n            \u003cimg src=\"https://avatars.githubusercontent.com/u/552506?v=4\" width=\"80;\" alt=\"11mariom\"/\u003e\n            \u003cbr /\u003e\n            \u003csub\u003e\u003cb\u003eMariusz Kozakowski\u003c/b\u003e\u003c/sub\u003e\n        \u003c/a\u003e\n    \u003c/td\u003e\u003c/tr\u003e\n\u003c/table\u003e\n\u003c!-- readme: contributors -end --\u003e\n\n## License\n\nProject is released under [Apache License, Version 2.0 license](LICENSE).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froche%2Fgitlab-configuration-as-code","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froche%2Fgitlab-configuration-as-code","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froche%2Fgitlab-configuration-as-code/lists"}