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 }}"
- 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.
- GitLab imports GitHub repos by their Repo ID, the numeric value, not the string. So our first task is to get that Repo ID
- 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
- This external set of tasks is executed top-to-bottom per-student.
- First, we get an authentication token to use for the following tasks
- Next, there are tagged tasks to get all the repos a user has access to
- We can then destroy all the repos under the user
- 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)