DEV Community

Ken Moini
Ken Moini

Posted on

Automate GitLab with Ansible - kinda

So there I was, automatin' and integratin' again. What can I say, it does get the best of me at times...

My task was to provide a way to automate the clean up of GitLab user namespaces, and import in a fresh repo from GitHub for NN student workshop users. Doesn't sound too hard eh?

So come to find out the GitLab module in Ansible is SUPER old and not really maintained. No problem, I'll just ping the GitHub API with Ansible.

Why do that instead of using something like Bash to perform cURL requests? Because the rest of the deployment already uses Ansible and it's much easier to just toss in a few extra tasks instead of bringing along an extra script and dropping into a different execution context.

1. Create the main Ansible Playbook

There's two Ansible files, and you'll see why shortly. First, let's create the configure_users.yaml file with the following content:

--- - name: Configure GitLab Workshop User Instances hosts: localhost gather_facts: false vars: - student_count: 50 - github_personal_access_token: your_github_pat - github_repo: kenmoini/s2f-tasks-app - gitlab_endpoint: https://gitlab.example.com tasks: - name: Get GitHub Repo Import Repo ID uri: url: "https://api.github.com/repos/{{ github_repo }}" method: GET validate_certs: no status_code: - 200 - 201 - 409 register: github_repo_info - name: Configure Per User GitLab Environment include_tasks: actual_user_config.yaml with_sequence: start=0 end="{{ student_count }}" 
  1. A few variables to keep an eye on, you need to pass in your GitHub Personal Access Token in order to import the repo, as well as the actual repo. We're also provisioning for 50 student user seats.
  2. GitLab imports GitHub repos by their Repo ID, the numeric value, not the string. So our first task is to get that Repo ID
  3. Next, we loop through an external tasks file - Blocks don't support loops.

2. Per-seat tasks

Let's create that external actual_user_config.yaml file:

--- - name: GitLab Post | Obtain Access Token uri: url: "{{ gitlab_endpoint }}/oauth/token" method: POST validate_certs: no status_code: 200 body_format: json headers: Content-Type: application/json body: > { "grant_type": "password", "username": "student{{ item }}", "password": "user_password_here" } register: gitlab_access_token tags: - always - name: GitLab Get | Get All User projects uri: url: "{{ gitlab_endpoint }}/api/v4/users/student{{ item }}/projects" method: GET validate_certs: no status_code: - 200 - 201 - 409 headers: Content-Type: application/json Authorization: Bearer {{ gitlab_access_token.json.access_token }} register: user_projects tags: - destroy - name: GitLab Post | Delete Projects via API uri: url: "{{ gitlab_endpoint }}/api/v4/projects/{{ project.id }}" method: DELETE validate_certs: no status_code: - 200 - 201 - 202 - 409 headers: Content-Type: application/json Authorization: Bearer {{ gitlab_access_token.json.access_token }} loop: "{{ user_projects.json }}" loop_control: loop_var: project tags: - destroy - name: GitLab Post | Import Project from GitHub uri: url: "{{ gitlab_endpoint }}/api/v4/import/github" method: POST validate_certs: no status_code: - 200 - 201 - 409 - 400 body_format: json headers: Content-Type: application/json Authorization: Bearer {{ gitlab_access_token.json.access_token }} body: > { "personal_access_token": "{{ github_personal_access_token }}", "repo_id": "{{ github_repo_info.json.id }}", "target_namespace": "student{{ item }}" } tags: - import 
  1. This external set of tasks is executed top-to-bottom per-student.
  2. First, we get an authentication token to use for the following tasks
  3. Next, there are tagged tasks to get all the repos a user has access to
  4. We can then destroy all the repos under the user
  5. Once it's all cleaned up, we'll import a new repo fresh into each student namespace

3. Rolllll it

Now you can simply run one of the following commands:

ansible-playbook configure_users.yaml --tags destroy # or ansible-playbook configure_users.yaml --tags import # OR OR ansible-playbook configure_users.yaml --tags "destroy,import" 

Hopefully, this helps in case you're looking to automate GitLab with Ansible. If there's not a particular Ansible module, or if it's not up to snuff then don't be afraid to use APIs if there's one available!

Top comments (0)