mirror of
https://gitlab.archlinux.org/archlinux/infrastructure.git
synced 2024-05-07 17:26:04 +02:00
Merge wip-keyclaok into master
This commit is contained in:
parent
a9a6e58c07
commit
f42fd92b83
42
README.md
42
README.md
|
@ -9,6 +9,7 @@ It also contains git submodules so you have to run `git submodule update --init
|
|||
|
||||
Install these packages:
|
||||
- terraform
|
||||
- terraform-provider-keycloak
|
||||
|
||||
### Instructions
|
||||
|
||||
|
@ -58,13 +59,24 @@ This will take some time after which a new snapshot will have been created on th
|
|||
|
||||
#### Note about terraform
|
||||
|
||||
We use terraform to provision a part of the infrastructure on hcloud.
|
||||
We use terraform in two ways:
|
||||
|
||||
1) To provision a part of the infrastructure on hcloud (and possibly other service providers in the future)
|
||||
2) To declaratively configure applications
|
||||
|
||||
For both of these, we have set up a separate terraform script. The reason for that is that sadly terraform can't have
|
||||
providers depend on other providers so we can't declaratively state that we want to configure software on a server which
|
||||
itself needs to be provisioned first. Therefore, we use a two-stage process. Generally speaking, scenario 1) is configured in
|
||||
`tf-stage1` and 2) is in `tf-stage2`. Maybe in the future, we can just have a single terraform script for everything
|
||||
but for the time being, this is what we're stuck with.
|
||||
|
||||
The very first time you run terraform on your system, you'll have to init it:
|
||||
|
||||
terraform init -backend-config="conn_str=postgres://terraform:$(misc/get_key.py group_vars/all/vault_terraform.yml vault_terraform_db_password)@state.archlinux.org"
|
||||
terraform init -backend-config="conn_str=postgres://terraform:$(../misc/get_key.py group_vars/all/vault_terraform.yml vault_terraform_db_password)@state.archlinux.org"
|
||||
|
||||
After making changes to the infrastructure in `archlinux.fg`, run
|
||||
After making changes to the infrastructure in `tf-stage1/archlinux.fg`, run
|
||||
|
||||
cd tf-stage1
|
||||
terraform plan
|
||||
|
||||
This will show you planned changes between the current infrastructure and the desired infrastructure.
|
||||
|
@ -74,6 +86,9 @@ You can then run
|
|||
|
||||
to actually apply your changes.
|
||||
|
||||
The same applies to changed application configuration in which case you'd run
|
||||
it inside of `tf-stage2` instead of `tf-stage1`.
|
||||
|
||||
We store terraform state on a special server that is the only hcloud server NOT
|
||||
managed by terraform so that we do not run into a chicken-egg problem. The
|
||||
state server is assumed to just exist so in an unlikely case where we have to
|
||||
|
@ -193,10 +208,24 @@ The following steps should be used to update our managed servers:
|
|||
#### Services:
|
||||
- quassel core
|
||||
|
||||
## homedir.archlinux.org
|
||||
### homedir.archlinux.org
|
||||
|
||||
#### Services:
|
||||
- ~/user/ webhost
|
||||
|
||||
### accounts.archlinux.org
|
||||
|
||||
This server is /special/. It runs keycloak and is central to our unified Arch Linux account management world.
|
||||
It has an Ansible playbook for the keycloak service but that only installs the package and starts it but it's configured via a secondary Terraform file only for keycloak `keycloak.tf`.
|
||||
The reason for doing it this way is that Terraform support for Keycloak is much superior and it's declarative too which is great for making sure that no old config remains in the case of config changes.
|
||||
|
||||
So to set up this server from scratch, run:
|
||||
|
||||
- `terraform apply tf-first-stage`
|
||||
- `terraform apply tf-second-stage`
|
||||
|
||||
#### Services:
|
||||
- keycloak
|
||||
|
||||
## mirror.pkgbuild.com
|
||||
|
||||
|
@ -252,3 +281,8 @@ Example
|
|||
Example
|
||||
|
||||
borg list borg@vostok.archlinux.org:/backup/homedir.archlinux.org::20191127-084357
|
||||
|
||||
## One-shots
|
||||
|
||||
A bunch of once-only admin task scripts can be found in `one-shots/`.
|
||||
We try to minimize the amount of manual one-shot admin work we have to do but sometimes for some migrations it might be necessary to have such scripts.
|
||||
|
|
|
@ -13,3 +13,4 @@ callback_whitelist = profile_tasks
|
|||
[ssh_connection]
|
||||
pipelining = True
|
||||
scp_if_ssh = True
|
||||
retries = 5
|
||||
|
|
|
@ -14,6 +14,9 @@ arch_users:
|
|||
ssh_key: aaron.pub
|
||||
groups:
|
||||
- dev
|
||||
accounts:
|
||||
name: ""
|
||||
groups: []
|
||||
aginiewicz:
|
||||
name: "Andrzej Giniewicz"
|
||||
ssh_key: aginiewicz.pub
|
||||
|
@ -227,6 +230,7 @@ arch_users:
|
|||
- name: foutrelis_buildhost.pub
|
||||
hosts:
|
||||
- dragon.archlinux.org
|
||||
- sgp.mirror.pkgbuild.com
|
||||
groups:
|
||||
- dev
|
||||
- tu
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
$ANSIBLE_VAULT;1.1;AES256
|
||||
38386666643233373639363835396530396162636562393531373566623531346131613739386637
|
||||
3238633664333561343139663665663537336633303036610a386436626330646262333130626539
|
||||
35323033316530616437326630393632646630363664303765636362353063653232373233353862
|
||||
6135346434373562350a376133626564643138386631366331333261376239636236343630303762
|
||||
64633431326164386332396238363332303965363666663636373465626563373535343534633232
|
||||
64313366623238656663383066613030633861333239623964633830323535363666303637663864
|
||||
35366131663337663534393863313634376433303935363733366234326639613034363465366538
|
||||
37343866306439336165666266323034666331616365333839343436306632643339386532623566
|
||||
34373165323664663365663237323361643137616165666130333537653862633730646637656635
|
||||
30656434366431353863333961353232653538616663313331343932363163353833633332383735
|
||||
35313531333839366132343038326230643235663133373334393562393435333136363534383134
|
||||
37643431666631666564383533366235313563636438666464343738376431643463373134346530
|
||||
61613461326137333162346330323232333562306638353332386538386465396238
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
filesystem: btrfs
|
||||
zabbix_agent_templates:
|
||||
- Template OS Linux
|
||||
- Template App Borg Backup
|
||||
- Template App HTTP Service
|
||||
- Template App HTTPS Service
|
||||
- Template App Nginx
|
||||
- Template App SSH Service
|
||||
- Template App PostgreSQL
|
3
hosts
3
hosts
|
@ -38,6 +38,8 @@ bbs.archlinux.org
|
|||
homedir.archlinux.org
|
||||
bugs.archlinux.org
|
||||
aur-dev.archlinux.org
|
||||
gitlab.archlinux.org
|
||||
accounts.archlinux.org
|
||||
|
||||
[borg_hosts]
|
||||
vostok.archlinux.org
|
||||
|
@ -66,6 +68,7 @@ bugs.archlinux.org
|
|||
|
||||
[buildservers]
|
||||
dragon.archlinux.org
|
||||
sgp.mirror.pkgbuild.com
|
||||
|
||||
[gitlab_runners]
|
||||
runner1.archlinux.org
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
This directory contains a bunch of one-off scripts which might be modified ad-hoc in some ways.
|
||||
|
||||
We keep them around for documentation reasons.
|
|
@ -0,0 +1,508 @@
|
|||
---
|
||||
|
||||
arch_groups:
|
||||
- dev
|
||||
- tu
|
||||
- devops
|
||||
- fellows
|
||||
- multilib
|
||||
- archboxes-sudo
|
||||
- docker-image-sudo
|
||||
|
||||
arch_users:
|
||||
# aaron:
|
||||
# name: "Aaron Griffin"
|
||||
# ssh_key: aaron.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# aginiewicz:
|
||||
# name: "Andrzej Giniewicz"
|
||||
# ssh_key: aginiewicz.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# ainola:
|
||||
# name: "Brett Cornwall"
|
||||
# ssh_key: ainola.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# alad:
|
||||
# name: "Alad Wenter"
|
||||
# ssh_key: alad.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# allan:
|
||||
# name: "Allan McRae"
|
||||
# ssh_key: allan.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# alucryd:
|
||||
# name: "Maxime Gauduin"
|
||||
# ssh_key: alucryd.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# anatolik:
|
||||
# name: "Anatol Pomozov"
|
||||
# ssh_key: anatolik.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# andrea:
|
||||
# name: "Andrea Scarpino"
|
||||
# ssh_key: andrea.pub
|
||||
# groups: []
|
||||
# andrew:
|
||||
# name: "Andrew Gregory"
|
||||
# ssh_key: andrew.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# andrewsc:
|
||||
# name: "Andrew Crerar"
|
||||
# ssh_key: andrewsc.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# anthraxx:
|
||||
# name: "Levente Polyak"
|
||||
# ssh_key: anthraxx.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# andyrtr:
|
||||
# name: "Andreas Radke"
|
||||
# ssh_key: andyrtr.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# arcanis:
|
||||
# name: "Evgeniy Alekseev"
|
||||
# ssh_key: arcanis.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# archange:
|
||||
# name: "Bruno Pagani"
|
||||
# ssh_key: archange.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# arodseth:
|
||||
# name: "Alexander Rødseth"
|
||||
# ssh_key: arodseth.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# arojas:
|
||||
# name: "Antonio Rojas"
|
||||
# ssh_key: arojas.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# aur-notify:
|
||||
# name: ""
|
||||
# groups: []
|
||||
# bgyorgy:
|
||||
# name: "Balló György"
|
||||
# ssh_key: bgyorgy.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# bisson:
|
||||
# name: "Gaëtan Bisson"
|
||||
# ssh_key: bisson.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# bluewind:
|
||||
# name: "Florian Pritz"
|
||||
# ssh_key: bluewind.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# bpiotrowski:
|
||||
# name: "Bartłomiej Piotrowski"
|
||||
# ssh_key: bpiotrowski.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# cbehan:
|
||||
# name: "Connor Behan"
|
||||
# ssh_key: cbehan.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# cesura:
|
||||
# name: "Brad Fanella"
|
||||
# ssh_key: cesura.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# coderobe:
|
||||
# name: "Robin Broda"
|
||||
# ssh_key: coderobe.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# daurnimator:
|
||||
# name: "Daurnimator"
|
||||
# ssh_key: daurnimator.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# dbermond:
|
||||
# name: "Daniel Bermond"
|
||||
# ssh_key: dbermond.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# demize:
|
||||
# name: "Johannes Löthberg"
|
||||
# ssh_key: demize.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# diabonas:
|
||||
# name: "Jonas Witschel"
|
||||
# ssh_key: diabonas.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# donate:
|
||||
# name: ""
|
||||
# groups: []
|
||||
# dreisner:
|
||||
# name: "Dave Reisner"
|
||||
# ssh_key: dreisner.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# dvzrv:
|
||||
# name: "David Runge"
|
||||
# ssh_key: dvzrv.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# eschwartz:
|
||||
# name: "Eli Schwartz"
|
||||
# ssh_key: eschwartz.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# escondida:
|
||||
# name: "Ivy Foster"
|
||||
# ssh_key: escondida.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# eworm:
|
||||
# name: "Christian Hesse"
|
||||
# ssh_key: eworm.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# farseerfc:
|
||||
# name: "Jiachen Yang"
|
||||
# ssh_key: farseerfc.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# felixonmars:
|
||||
# name: "Felix Yan"
|
||||
# ssh_key: felixonmars.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# ffy00:
|
||||
# name: "Filipe Laíns"
|
||||
# ssh_key: ffy00.pub
|
||||
# shell: /bin/bash
|
||||
# groups:
|
||||
# - tu
|
||||
# foutrelis:
|
||||
# name: "Evangelos Foutras"
|
||||
# ssh_key: foutrelis.pub
|
||||
# additional_ssh_keys:
|
||||
# - name: foutrelis_buildhost.pub
|
||||
# hosts:
|
||||
# - dragon.archlinux.org
|
||||
# - sgp.mirror.pkgbuild.com
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# foxboron:
|
||||
# name: "Morten Linderud"
|
||||
# ssh_key: foxboron.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# foxxx0:
|
||||
# name: "Thore Bödecker"
|
||||
# ssh_key: foxxx0.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - tu
|
||||
# fukawi2:
|
||||
# name: "Phillip Smith"
|
||||
# ssh_key: fukawi2.pub
|
||||
# groups:
|
||||
# - devops
|
||||
# giovanni:
|
||||
# name: ""
|
||||
# ssh_key: giovanni.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# gitlab:
|
||||
# name: ""
|
||||
# groups: []
|
||||
# grazzolini:
|
||||
# name: "Giancarlo Razzolini"
|
||||
# ssh_key: grazzolini.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - multilib
|
||||
# - tu
|
||||
# heftig:
|
||||
# name: "Jan Steffens"
|
||||
# ssh_key: heftig.pub
|
||||
# additional_ssh_keys:
|
||||
# - name: heftig_work.pub
|
||||
# hosts:
|
||||
# - dragon.archlinux.org
|
||||
# - name: heftig_dragon.pub
|
||||
# hosts:
|
||||
# - homedir.archlinux.org
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# idevolder:
|
||||
# name: "Ike Devolder"
|
||||
# ssh_key: idevolder.pub
|
||||
# groups:
|
||||
# - tu
|
||||
jelle:
|
||||
name: "Jelle van der Waa"
|
||||
ssh_key: jelle.pub
|
||||
groups:
|
||||
- dev
|
||||
- devops
|
||||
- tu
|
||||
- multilib
|
||||
# jgc:
|
||||
# name: "Jan de Groot"
|
||||
# ssh_key: jgc.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# jleclanche:
|
||||
# name: "Jerome Leclanche"
|
||||
# ssh_key: jleclanche.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - tu
|
||||
# jlichtblau:
|
||||
# name: "Jaroslav Lichtblau"
|
||||
# ssh_key: jlichtblau.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# jouke:
|
||||
# name: "Jouke Witteveen"
|
||||
# ssh_key: jouke.pub
|
||||
# groups:
|
||||
# - ""
|
||||
# jsteel:
|
||||
# name: "Jonathan Steel"
|
||||
# ssh_key: jsteel.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# juergen:
|
||||
# name: "Jürgen Hötzel"
|
||||
# ssh_key: juergen.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# kgizdov:
|
||||
# name: "Konstantin Gizdov"
|
||||
# ssh_key: kgizdov.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# kkeen:
|
||||
# name: "Kyle Keen"
|
||||
# ssh_key: kkeen.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# lcarlier:
|
||||
# name: "Laurent Carlier"
|
||||
# ssh_key: lcarlier.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# lfleischer:
|
||||
# name: "Lukas Fleischer"
|
||||
# ssh_key: lfleischer.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# maximbaz:
|
||||
# name: "Maxim Baz"
|
||||
# ssh_key: maximbaz.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# mtorromeo:
|
||||
# name: "Massimiliano Torromeo"
|
||||
# ssh_key: mtorromeo.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# muflone:
|
||||
# name: "Fabio Castelli"
|
||||
# ssh_key: muflone.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# nicohood:
|
||||
# name: "NicoHood"
|
||||
# ssh_key: nicohood.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# pierre:
|
||||
# name: "Pierre Schmitz"
|
||||
# ssh_key: pierre.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# polyzen:
|
||||
# name: "Daniel M. Capella"
|
||||
# ssh_key: polyzen.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# remy:
|
||||
# name: "Rémy Oudompheng"
|
||||
# ssh_key: remy.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# ronald:
|
||||
# name: "Ronald van Haren"
|
||||
# ssh_key: ronald.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# sangy:
|
||||
# name: "Santiago Torres-Arias"
|
||||
# ssh_key: sangy.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - docker-image-sudo
|
||||
# schiv:
|
||||
# name: "Ray Rashif"
|
||||
# ssh_key: schiv.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# schuay:
|
||||
# name: "Jakob Gruber"
|
||||
# ssh_key: schuay.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# scimmia:
|
||||
# name: "Doug Newgard"
|
||||
# ssh_key: scimmia.pub
|
||||
# groups: []
|
||||
# morganamilo:
|
||||
# name: "Morgan Adamiec"
|
||||
# ssh_key: morganamilo.pub
|
||||
# groups: []
|
||||
# seblu:
|
||||
# name: "Sébastien Luttringer"
|
||||
# ssh_key: seblu.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - dev
|
||||
# - tu
|
||||
# - multilib
|
||||
# shibumi:
|
||||
# name: "Christian Rebischke"
|
||||
# ssh_key: shibumi.pub
|
||||
# shell: /bin/zsh
|
||||
# groups:
|
||||
# - tu
|
||||
# - archboxes-sudo
|
||||
# kpcyrd:
|
||||
# name: "Kpcyrd"
|
||||
# ssh_key: kpcyrd.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# spupykin:
|
||||
# name: "Sergej Pupykin"
|
||||
# ssh_key: spupykin.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# - multilib
|
||||
# svenstaro:
|
||||
# name: "Sven-Hendrik Haase"
|
||||
# ssh_key: svenstaro.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - devops
|
||||
# - tu
|
||||
# - multilib
|
||||
# tensor5:
|
||||
# name: "Nicola Squartini"
|
||||
# ssh_key: tensor5.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# thomas:
|
||||
# name: "Thomas Bächler"
|
||||
# ssh_key: thomas.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# tpowa:
|
||||
# name: "Tobias Powalowski"
|
||||
# ssh_key: tpowa.pub
|
||||
# groups:
|
||||
# - dev
|
||||
# - multilib
|
||||
# - tu
|
||||
# wild:
|
||||
# name: "Dan Printzell"
|
||||
# ssh_key: wild.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# xyne:
|
||||
# name: "Xyne"
|
||||
# ssh_key: xyne.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# yan12125:
|
||||
# name: "Chih-Hsuan Yen"
|
||||
# ssh_key: yan12125.pub
|
||||
# groups:
|
||||
# - tu
|
||||
# zorun:
|
||||
# name: "Baptiste Jonglez"
|
||||
# ssh_key: zorun.pub
|
||||
# groups:
|
||||
# - tu
|
|
@ -0,0 +1,167 @@
|
|||
#!/usr/bin/env python
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import webbrowser
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
IMPORT_GROUPS = {
|
||||
"dev": "Developers",
|
||||
"devops": "DevOps",
|
||||
"tu": "Trusted Users",
|
||||
}
|
||||
|
||||
|
||||
CLIENT_ID = "admin-cli"
|
||||
KEYCLOAK_ADMIN_USERNAME = os.environ["KEYCLOAK_ADMIN_USERNAME"]
|
||||
KEYCLOAK_ADMIN_PASSWORD = os.environ["KEYCLOAK_ADMIN_PASSWORD"]
|
||||
KEYCLOAK_URL = "https://accounts.archlinux.org/auth"
|
||||
KEYCLOAK_REALM = "master"
|
||||
|
||||
REALM_URL = f"{KEYCLOAK_URL}/realms/{KEYCLOAK_REALM}"
|
||||
FETCH_TOKEN_URL = f"{REALM_URL}/protocol/openid-connect/token"
|
||||
API_BASE_URL = f"{KEYCLOAK_URL}/admin/realms/{KEYCLOAK_REALM}"
|
||||
|
||||
_token_expire = 0
|
||||
_token_cache = ""
|
||||
|
||||
|
||||
def get_token():
|
||||
global _token_cache
|
||||
global _token_expire
|
||||
|
||||
if _token_expire < datetime.now().timestamp():
|
||||
r = requests.post(
|
||||
FETCH_TOKEN_URL,
|
||||
data={
|
||||
"username": KEYCLOAK_ADMIN_USERNAME,
|
||||
"password": KEYCLOAK_ADMIN_PASSWORD,
|
||||
"grant_type": "password",
|
||||
"client_id": CLIENT_ID,
|
||||
},
|
||||
)
|
||||
data = r.json()
|
||||
|
||||
if "error" in data:
|
||||
sys.stderr.write(
|
||||
f"Error requesting token: {data.get('error_description', data['error'])}\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
_token_expire = datetime.now().timestamp() + data["expires_in"]
|
||||
_token_cache = data["access_token"]
|
||||
|
||||
return _token_cache
|
||||
|
||||
|
||||
def get_auth_headers():
|
||||
token = get_token()
|
||||
return {"Authorization": f"Bearer {token}"}
|
||||
|
||||
|
||||
def is_valid_file(parser, arg):
|
||||
if not os.path.exists(arg):
|
||||
parser.error(f"File {arg!r} does not exist")
|
||||
return open(arg, "r")
|
||||
|
||||
|
||||
def add_user_to_group(user_id: str, group_id: str):
|
||||
r = requests.put(
|
||||
f"{API_BASE_URL}/users/{user_id}/groups/{group_id}",
|
||||
data={"realm": KEYCLOAK_REALM, "userId": user_id, "groupId": group_id},
|
||||
headers=get_auth_headers(),
|
||||
)
|
||||
|
||||
if r.status_code in (200, 204):
|
||||
# Success, empty response
|
||||
return
|
||||
else:
|
||||
data = r.json()
|
||||
if "error" in data:
|
||||
sys.stderr.write(
|
||||
f"Error adding user to group: {data.get('error_description', data['error'])}\n"
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_all_users():
|
||||
all_users = requests.get(
|
||||
f"{API_BASE_URL}/users",
|
||||
{"briefRepresentation": "true", "first": "0", "max": "200"},
|
||||
headers=get_auth_headers(),
|
||||
).json()
|
||||
return {u["username"]: u["id"] for u in all_users}
|
||||
|
||||
|
||||
def get_all_groups():
|
||||
all_groups = requests.get(
|
||||
f"{API_BASE_URL}/groups",
|
||||
{"first": "0", "max": "200"},
|
||||
headers=get_auth_headers(),
|
||||
).json()
|
||||
return {g["name"]: g["id"] for g in all_groups}
|
||||
|
||||
|
||||
def main():
|
||||
if not KEYCLOAK_ADMIN_USERNAME or not KEYCLOAK_ADMIN_PASSWORD:
|
||||
sys.stderr.write(
|
||||
"Environment variables KEYCLOAK_ADMIN_USERNAME and KEYCLOAK_ADMIN_PASSWORD must be set\n"
|
||||
)
|
||||
exit(1)
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument("file", type=lambda x: is_valid_file(p, x))
|
||||
args = p.parse_args(sys.argv[1:])
|
||||
|
||||
users_yml = yaml.load(args.file, Loader=yaml.SafeLoader)
|
||||
users = users_yml["arch_users"]
|
||||
|
||||
user_ids = get_all_users()
|
||||
group_ids = get_all_groups()
|
||||
|
||||
print(user_ids)
|
||||
|
||||
for username, user in users.items():
|
||||
if username not in user_ids:
|
||||
# Check if the user has a significant role
|
||||
for group in user["groups"]:
|
||||
if group in IMPORT_GROUPS:
|
||||
break
|
||||
else:
|
||||
# Otherwise, skip creating it
|
||||
continue
|
||||
print(f"Creating {username!r}")
|
||||
name = user.get("name", "")
|
||||
first_name, last_name = "", ""
|
||||
if name:
|
||||
_names = name.split()
|
||||
if _names:
|
||||
first_name = _names[0]
|
||||
if len(_names) > 1:
|
||||
last_name = " ".join(_names[1:])
|
||||
response = requests.post(
|
||||
f"{API_BASE_URL}/users",
|
||||
json={
|
||||
"username": username,
|
||||
"email": user.get("email", ""),
|
||||
"firstName": first_name,
|
||||
"lastName": last_name,
|
||||
"enabled": True,
|
||||
},
|
||||
headers=get_auth_headers(),
|
||||
)
|
||||
|
||||
user_ids = get_all_users()
|
||||
for username, user in users.items():
|
||||
for group in user["groups"]:
|
||||
if group in IMPORT_GROUPS:
|
||||
import_group = IMPORT_GROUPS[group]
|
||||
print(f"Adding {username!r} to {import_group!r}")
|
||||
add_user_to_group(user_ids[username], group_ids[import_group])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
curl -s https://accounts.archlinux.org/auth/realms/master/protocol/saml/descriptor | xmllint --xpath '//*[local-name()="X509Certificate"]/text()' - | base64 -d | sha1sum | cut -d ' ' -f1 | sed -e 's/.\{2\}/&:/g' | sed 's/:$//' | tr '[:lower:]' '[:upper:]'
|
|
@ -8,3 +8,12 @@
|
|||
- { role: firewalld }
|
||||
- { role: sshd }
|
||||
- { role: root_ssh }
|
||||
- { role: certbot }
|
||||
- { role: nginx }
|
||||
- role: postgres
|
||||
postgres_shared_buffers: 500MB
|
||||
postgres_work_mem: 32MB
|
||||
postgres_maintenance_work_mem: 1GB
|
||||
postgres_effective_cache_size: 1GB
|
||||
- { role: keycloak }
|
||||
- { role: borg-client, tags: ["borg"] }
|
||||
|
|
|
@ -10,3 +10,4 @@
|
|||
- { role: sshd }
|
||||
- { role: root_ssh }
|
||||
- { role: gitlab, gitlab_domain: "gitlab.archlinux.org" }
|
||||
- { role: borg-client, tags: ["borg"] }
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
restart_policy: always
|
||||
env:
|
||||
# See https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template
|
||||
# 1. In order to figure out what needs to go into 'idp_cert_fingerprint', run
|
||||
# one-shots/keycloak-keyfetcher/get_fingerprint.sh and copy the resulting SHA1 fingerprint into that field.
|
||||
# 2. In order to logout properly we need to configure the "After sign out path" and set it to
|
||||
# https://accounts.archlinux.org/auth/realms/master/protocol/openid-connect/logout?redirect_uri=https%3A//gitlab.archlinux.org
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/14414
|
||||
GITLAB_OMNIBUS_CONFIG: |
|
||||
external_url 'https://{{ gitlab_domain }}'
|
||||
letsencrypt['enable'] = true
|
||||
|
@ -38,6 +43,32 @@
|
|||
gitlab_rails['gitlab_email_display_name'] = 'GitLab'
|
||||
gitlab_rails['gitlab_email_reply_to'] = 'noreply@archlinux.org'
|
||||
gitlab_rails['gitlab_default_theme'] = 2
|
||||
gitlab_rails['omniauth_allow_single_sign_on'] = ['saml']
|
||||
gitlab_rails['omniauth_block_auto_created_users'] = false
|
||||
gitlab_rails['omniauth_auto_link_saml_user'] = true
|
||||
gitlab_rails['omniauth_providers'] = [
|
||||
{
|
||||
name: 'saml',
|
||||
label: 'Arch Linux SSO',
|
||||
groups_attribute: 'Role',
|
||||
admin_groups: ['DevOps'],
|
||||
args: {
|
||||
assertion_consumer_service_url: 'https://gitlab.archlinux.org/users/auth/saml/callback',
|
||||
idp_cert_fingerprint: '83:AB:61:8E:8C:8A:78:F6:D9:A6:8E:25:6F:DA:04:4D:77:0E:CD:B2',
|
||||
idp_sso_target_url: 'https://accounts.archlinux.org/auth/realms/master/protocol/saml/clients/saml_gitlab',
|
||||
idp_slo_target_url: 'https://accounts.archlinux.org/auth/realms/master/protocol/saml',
|
||||
issuer: 'saml_gitlab',
|
||||
attribute_statements: {
|
||||
first_name: ['first_name'],
|
||||
last_name: ['last_name'],
|
||||
name: ['name'],
|
||||
username: ['username'],
|
||||
email: ['email'],
|
||||
},
|
||||
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent'
|
||||
}
|
||||
}
|
||||
]
|
||||
volumes:
|
||||
- "/srv/gitlab/config:/etc/gitlab"
|
||||
- "/srv/gitlab/logs:/var/log/gitlab"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
keycloak_db_name: keycloak
|
||||
keycloak_db_user: keycloak
|
||||
keycloak_db_password: keycloak
|
||||
keycloak_domain: accounts.archlinux.org
|
||||
keycloak_home_dir: /opt/keycloak
|
||||
keycloak_port: "8443"
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
|
||||
- name: restart keycloak
|
||||
service: name=keycloak state=restarted
|
|
@ -3,16 +3,46 @@
|
|||
- name: install keycloak
|
||||
pacman: name=keycloak state=present
|
||||
|
||||
# - name: start dirsrv service
|
||||
# service: name=dirsrv
|
||||
# Levente TODO
|
||||
- name: template keycloak config
|
||||
template: src=standalone.xml.j2 dest=/etc/keycloak/standalone.xml owner=keycloak group=keycloak mode=600
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
||||
# - name: open firewall hole
|
||||
# firewalld: port={{ item }} permanent=true state=enabled immediate=yes
|
||||
# when: configure_firewall
|
||||
# with_items:
|
||||
# Levente TODO
|
||||
# - 389
|
||||
# - 636
|
||||
# tags:
|
||||
# - firewall
|
||||
- name: create an admin user
|
||||
command: /opt/keycloak/bin/add-user-keycloak.sh -u "{{ vault_keycloak_admin_user }}" -p "{{ vault_keycloak_admin_password }}"
|
||||
args:
|
||||
creates: /opt/keycloak/standalone/configuration/keycloak-add-user.json
|
||||
|
||||
- name: start and enable keycloak
|
||||
service: name=keycloak enabled=yes state=started
|
||||
|
||||
- name: open firewall hole
|
||||
firewalld: port={{ item }} permanent=true state=enabled immediate=yes
|
||||
when: configure_firewall
|
||||
with_items:
|
||||
- 80/tcp
|
||||
- 443/tcp
|
||||
tags:
|
||||
- firewall
|
||||
|
||||
- name: create postgres keycloak user
|
||||
postgresql_user: name="{{ keycloak_db_user }}" password="{{ keycloak_db_password }}"
|
||||
become: yes
|
||||
become_user: postgres
|
||||
become_method: su
|
||||
no_log: True
|
||||
|
||||
- name: create keycloak db
|
||||
postgresql_db: name=keycloak owner="{{ keycloak_db_user }}"
|
||||
become: yes
|
||||
become_user: postgres
|
||||
become_method: su
|
||||
|
||||
- name: make nginx log dir
|
||||
file: path="/var/log/nginx/{{ keycloak_domain }}" state=directory owner=root mode=0755
|
||||
|
||||
- name: set up nginx
|
||||
template: src=nginx.d.conf.j2 dest=/etc/nginx/nginx.d/keycloak.conf owner=root group=root mode=0644
|
||||
notify:
|
||||
- reload nginx
|
||||
tags: ['nginx']
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
[general]
|
||||
config_version = 2
|
||||
full_machine_name = {{ inventory_hostname}}
|
||||
selinux = False
|
||||
start = False
|
||||
strict_host_checking = True
|
||||
systemd = True
|
||||
|
||||
[slapd]
|
||||
instance_name = archlinux
|
||||
root_dn = cn=Administrator
|
||||
root_password = {{ vault_ldap_dir_manager_password }}
|
||||
port = 389
|
||||
secure_port = 636
|
||||
self_sign_cert = True
|
||||
self_sign_cert_valid_months = 24
|
||||
backup_dir = /var/lib/dirsrv/slapd-{instance_name}/bak
|
||||
cert_dir = /etc/dirsrv/slapd-{instance_name}
|
||||
config_dir = /etc/dirsrv/slapd-{instance_name}
|
||||
db_dir = /var/lib/dirsrv/slapd-{instance_name}/db
|
||||
inst_dir = /usr/lib/dirsrv/slapd-{instance_name}
|
||||
ldif_dir = /var/lib/dirsrv/slapd-{instance_name}/ldif
|
||||
lock_dir = /var/lock/dirsrv/slapd-{instance_name}
|
||||
log_dir = /var/log/dirsrv/slapd-{instance_name}
|
||||
schema_dir = /etc/dirsrv/slapd-{instance_name}/schema
|
||||
|
||||
[backend-userroot]
|
||||
suffix = dc=archlinux,dc=org
|
|
@ -0,0 +1,37 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{ keycloak_domain }};
|
||||
|
||||
access_log /var/log/nginx/{{ keycloak_domain }}/access.log reduced;
|
||||
error_log /var/log/nginx/{{ keycloak_domain }}/error.log;
|
||||
|
||||
include snippets/letsencrypt.conf;
|
||||
|
||||
location / {
|
||||
access_log off;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name {{ keycloak_domain }};
|
||||
|
||||
access_log /var/log/nginx/{{ keycloak_domain }}/access.log reduced;
|
||||
error_log /var/log/nginx/{{ keycloak_domain }}/error.log;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/{{ keycloak_domain }}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/{{ keycloak_domain }}/privkey.pem;
|
||||
ssl_trusted_certificate /etc/letsencrypt/live/{{ keycloak_domain }}/chain.pem;
|
||||
|
||||
root {{ keycloak_domain }};
|
||||
|
||||
location / {
|
||||
access_log /var/log/nginx/{{ keycloak_domain }}/access.log main;
|
||||
proxy_pass https://localhost:{{ keycloak_port }};
|
||||
proxy_set_header Host $host;
|
||||
proxy_ssl_verify off;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,591 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<server xmlns="urn:jboss:domain:10.0">
|
||||
<extensions>
|
||||
<extension module="org.jboss.as.clustering.infinispan"/>
|
||||
<extension module="org.jboss.as.connector"/>
|
||||
<extension module="org.jboss.as.deployment-scanner"/>
|
||||
<extension module="org.jboss.as.ee"/>
|
||||
<extension module="org.jboss.as.ejb3"/>
|
||||
<extension module="org.jboss.as.jaxrs"/>
|
||||
<extension module="org.jboss.as.jmx"/>
|
||||
<extension module="org.jboss.as.jpa"/>
|
||||
<extension module="org.jboss.as.logging"/>
|
||||
<extension module="org.jboss.as.mail"/>
|
||||
<extension module="org.jboss.as.naming"/>
|
||||
<extension module="org.jboss.as.remoting"/>
|
||||
<extension module="org.jboss.as.security"/>
|
||||
<extension module="org.jboss.as.transactions"/>
|
||||
<extension module="org.jboss.as.weld"/>
|
||||
<extension module="org.keycloak.keycloak-server-subsystem"/>
|
||||
<extension module="org.wildfly.extension.bean-validation"/>
|
||||
<extension module="org.wildfly.extension.core-management"/>
|
||||
<extension module="org.wildfly.extension.elytron"/>
|
||||
<extension module="org.wildfly.extension.io"/>
|
||||
<extension module="org.wildfly.extension.microprofile.config-smallrye"/>
|
||||
<extension module="org.wildfly.extension.microprofile.health-smallrye"/>
|
||||
<extension module="org.wildfly.extension.microprofile.metrics-smallrye"/>
|
||||
<extension module="org.wildfly.extension.request-controller"/>
|
||||
<extension module="org.wildfly.extension.security.manager"/>
|
||||
<extension module="org.wildfly.extension.undertow"/>
|
||||
</extensions>
|
||||
<management>
|
||||
<security-realms>
|
||||
<security-realm name="ManagementRealm">
|
||||
<authentication>
|
||||
<local default-user="$local" skip-group-loading="true"/>
|
||||
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization map-groups-to-roles="false">
|
||||
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
<security-realm name="ApplicationRealm">
|
||||
<server-identities>
|
||||
<ssl>
|
||||
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
|
||||
</ssl>
|
||||
</server-identities>
|
||||
<authentication>
|
||||
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
|
||||
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authentication>
|
||||
<authorization>
|
||||
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</authorization>
|
||||
</security-realm>
|
||||
</security-realms>
|
||||
<audit-log>
|
||||
<formatters>
|
||||
<json-formatter name="json-formatter"/>
|
||||
</formatters>
|
||||
<handlers>
|
||||
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
|
||||
</handlers>
|
||||
<logger log-boot="true" log-read-only="false" enabled="false">
|
||||
<handlers>
|
||||
<handler name="file"/>
|
||||
</handlers>
|
||||
</logger>
|
||||
</audit-log>
|
||||
<management-interfaces>
|
||||
<http-interface security-realm="ManagementRealm">
|
||||
<http-upgrade enabled="true"/>
|
||||
<socket-binding http="management-http"/>
|
||||
</http-interface>
|
||||
</management-interfaces>
|
||||
<access-control provider="simple">
|
||||
<role-mapping>
|
||||
<role name="SuperUser">
|
||||
<include>
|
||||
<user name="$local"/>
|
||||
</include>
|
||||
</role>
|
||||
</role-mapping>
|
||||
</access-control>
|
||||
</management>
|
||||
<profile>
|
||||
<subsystem xmlns="urn:jboss:domain:logging:8.0">
|
||||
<console-handler name="CONSOLE">
|
||||
<level name="INFO"/>
|
||||
<formatter>
|
||||
<named-formatter name="COLOR-PATTERN"/>
|
||||
</formatter>
|
||||
</console-handler>
|
||||
<periodic-rotating-file-handler name="FILE" autoflush="true">
|
||||
<formatter>
|
||||
<named-formatter name="PATTERN"/>
|
||||
</formatter>
|
||||
<file relative-to="jboss.server.log.dir" path="server.log"/>
|
||||
<suffix value=".yyyy-MM-dd"/>
|
||||
<append value="true"/>
|
||||
</periodic-rotating-file-handler>
|
||||
<logger category="com.arjuna">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="io.jaegertracing.Configuration">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<logger category="org.jboss.as.config">
|
||||
<level name="DEBUG"/>
|
||||
</logger>
|
||||
<logger category="sun.rmi">
|
||||
<level name="WARN"/>
|
||||
</logger>
|
||||
<root-logger>
|
||||
<level name="INFO"/>
|
||||
<handlers>
|
||||
<handler name="CONSOLE"/>
|
||||
<handler name="FILE"/>
|
||||
</handlers>
|
||||
</root-logger>
|
||||
<formatter name="PATTERN">
|
||||
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
<formatter name="COLOR-PATTERN">
|
||||
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
|
||||
</formatter>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
|
||||
<datasources>
|
||||
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<connection-url>jdbc:postgresql://localhost:5432/keycloak</connection-url>
|
||||
<driver>postgresql</driver>
|
||||
<security>
|
||||
<user-name>keycloak</user-name>
|
||||
<password>keycloak</password>
|
||||
</security>
|
||||
</datasource>
|
||||
<drivers>
|
||||
<driver name="postgresql" module="org.postgresql">
|
||||
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
|
||||
</driver>
|
||||
<driver name="h2" module="com.h2database.h2">
|
||||
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
|
||||
</driver>
|
||||
</drivers>
|
||||
</datasources>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
|
||||
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ee:4.0">
|
||||
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
|
||||
<concurrent>
|
||||
<context-services>
|
||||
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
|
||||
</context-services>
|
||||
<managed-thread-factories>
|
||||
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
|
||||
</managed-thread-factories>
|
||||
<managed-executor-services>
|
||||
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
|
||||
</managed-executor-services>
|
||||
<managed-scheduled-executor-services>
|
||||
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
|
||||
</managed-scheduled-executor-services>
|
||||
</concurrent>
|
||||
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/KeycloakDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:ejb3:6.0">
|
||||
<session-bean>
|
||||
<stateless>
|
||||
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
|
||||
</stateless>
|
||||
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
|
||||
<singleton default-access-timeout="5000"/>
|
||||
</session-bean>
|
||||
<pools>
|
||||
<bean-instance-pools>
|
||||
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
|
||||
</bean-instance-pools>
|
||||
</pools>
|
||||
<caches>
|
||||
<cache name="simple"/>
|
||||
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
|
||||
</caches>
|
||||
<passivation-stores>
|
||||
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
|
||||
</passivation-stores>
|
||||
<async thread-pool-name="default"/>
|
||||
<timer-service thread-pool-name="default" default-data-store="default-file-store">
|
||||
<data-stores>
|
||||
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
|
||||
</data-stores>
|
||||
</timer-service>
|
||||
<remote connector-ref="http-remoting-connector" thread-pool-name="default">
|
||||
<channel-creation-options>
|
||||
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
|
||||
</channel-creation-options>
|
||||
</remote>
|
||||
<thread-pools>
|
||||
<thread-pool name="default">
|
||||
<max-threads count="10"/>
|
||||
<keepalive-time time="60" unit="seconds"/>
|
||||
</thread-pool>
|
||||
</thread-pools>
|
||||
<default-security-domain value="other"/>
|
||||
<default-missing-method-permissions-deny-access value="true"/>
|
||||
<statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<log-system-exceptions value="true"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:io:3.0">
|
||||
<worker name="default"/>
|
||||
<buffer-pool name="default"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:infinispan:9.0">
|
||||
<cache-container name="keycloak">
|
||||
<local-cache name="realms">
|
||||
<object-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users">
|
||||
<object-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="sessions"/>
|
||||
<local-cache name="authenticationSessions"/>
|
||||
<local-cache name="offlineSessions"/>
|
||||
<local-cache name="clientSessions"/>
|
||||
<local-cache name="offlineClientSessions"/>
|
||||
<local-cache name="loginFailures"/>
|
||||
<local-cache name="work"/>
|
||||
<local-cache name="authorization">
|
||||
<object-memory size="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="keys">
|
||||
<object-memory size="1000"/>
|
||||
<expiration max-idle="3600000"/>
|
||||
</local-cache>
|
||||
<local-cache name="actionTokens">
|
||||
<object-memory size="-1"/>
|
||||
<expiration max-idle="-1" interval="300000"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
|
||||
<local-cache name="default">
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
<local-cache name="sso">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
</local-cache>
|
||||
<local-cache name="routing"/>
|
||||
</cache-container>
|
||||
<cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan">
|
||||
<local-cache name="passivation">
|
||||
<locking isolation="REPEATABLE_READ"/>
|
||||
<transaction mode="BATCH"/>
|
||||
<file-store passivation="true" purge="false"/>
|
||||
</local-cache>
|
||||
</cache-container>
|
||||
<cache-container name="hibernate" module="org.infinispan.hibernate-cache">
|
||||
<local-cache name="entity">
|
||||
<object-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="local-query">
|
||||
<object-memory size="10000"/>
|
||||
<expiration max-idle="100000"/>
|
||||
</local-cache>
|
||||
<local-cache name="timestamps"/>
|
||||
</cache-container>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:jca:5.0">
|
||||
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
|
||||
<bean-validation enabled="true"/>
|
||||
<default-workmanager>
|
||||
<short-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</short-running-threads>
|
||||
<long-running-threads>
|
||||
<core-threads count="50"/>
|
||||
<queue-length count="50"/>
|
||||
<max-threads count="50"/>
|
||||
<keepalive-time time="10" unit="seconds"/>
|
||||
</long-running-threads>
|
||||
</default-workmanager>
|
||||
<cached-connection-manager/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
|
||||
<expose-resolved-model/>
|
||||
<expose-expression-model/>
|
||||
<remoting-connector/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
|
||||
<jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:mail:3.0">
|
||||
<mail-session name="default" jndi-name="java:jboss/mail/Default">
|
||||
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
|
||||
</mail-session>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:naming:2.0">
|
||||
<remote-naming/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
|
||||
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
|
||||
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
|
||||
<deployment-permissions>
|
||||
<maximum-set>
|
||||
<permission class="java.security.AllPermission"/>
|
||||
</maximum-set>
|
||||
</deployment-permissions>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:wildfly:elytron:8.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
|
||||
<providers>
|
||||
<aggregate-providers name="combined-providers">
|
||||
<providers name="elytron"/>
|
||||
<providers name="openssl"/>
|
||||
</aggregate-providers>
|
||||
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
|
||||
<provider-loader name="openssl" module="org.wildfly.openssl"/>
|
||||
</providers>
|
||||
<audit-logging>
|
||||
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
|
||||
</audit-logging>
|
||||
<security-domains>
|
||||
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local"/>
|
||||
</security-domain>
|
||||
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
|
||||
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
|
||||
<realm name="local" role-mapper="super-user-mapper"/>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
<security-realms>
|
||||
<identity-realm name="local" identity="$local"/>
|
||||
<properties-realm name="ApplicationRealm">
|
||||
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
|
||||
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
<properties-realm name="ManagementRealm">
|
||||
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
|
||||
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
|
||||
</properties-realm>
|
||||
</security-realms>
|
||||
<mappers>
|
||||
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
|
||||
<permission-mapping>
|
||||
<principal name="anonymous"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
<permission-mapping match-all="true">
|
||||
<permission-set name="login-permission"/>
|
||||
<permission-set name="default-permissions"/>
|
||||
</permission-mapping>
|
||||
</simple-permission-mapper>
|
||||
<constant-realm-mapper name="local" realm-name="local"/>
|
||||
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
|
||||
<constant-role-mapper name="super-user-mapper">
|
||||
<role name="SuperUser"/>
|
||||
</constant-role-mapper>
|
||||
</mappers>
|
||||
<permission-sets>
|
||||
<permission-set name="login-permission">
|
||||
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
|
||||
</permission-set>
|
||||
<permission-set name="default-permissions">
|
||||
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
|
||||
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
|
||||
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
|
||||
</permission-set>
|
||||
</permission-sets>
|
||||
<http>
|
||||
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="DIGEST">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</http-authentication-factory>
|
||||
<provider-http-server-mechanism-factory name="global"/>
|
||||
</http>
|
||||
<sasl>
|
||||
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ApplicationRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
|
||||
<mechanism-configuration>
|
||||
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
|
||||
<mechanism mechanism-name="DIGEST-MD5">
|
||||
<mechanism-realm realm-name="ManagementRealm"/>
|
||||
</mechanism>
|
||||
</mechanism-configuration>
|
||||
</sasl-authentication-factory>
|
||||
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
|
||||
<properties>
|
||||
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
|
||||
</properties>
|
||||
</configurable-sasl-server-factory>
|
||||
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
|
||||
<filters>
|
||||
<filter provider-name="WildFlyElytron"/>
|
||||
</filters>
|
||||
</mechanism-provider-filtering-sasl-server-factory>
|
||||
<provider-sasl-server-factory name="global"/>
|
||||
</sasl>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:security:2.0">
|
||||
<security-domains>
|
||||
<security-domain name="other" cache-type="default">
|
||||
<authentication>
|
||||
<login-module code="Remoting" flag="optional">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
<login-module code="RealmDirect" flag="required">
|
||||
<module-option name="password-stacking" value="useFirstPass"/>
|
||||
</login-module>
|
||||
</authentication>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-web-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
<security-domain name="jaspitest" cache-type="default">
|
||||
<authentication-jaspi>
|
||||
<login-module-stack name="dummy">
|
||||
<login-module code="Dummy" flag="optional"/>
|
||||
</login-module-stack>
|
||||
<auth-module code="Dummy"/>
|
||||
</authentication-jaspi>
|
||||
</security-domain>
|
||||
<security-domain name="jboss-ejb-policy" cache-type="default">
|
||||
<authorization>
|
||||
<policy-module code="Delegating" flag="required"/>
|
||||
</authorization>
|
||||
</security-domain>
|
||||
</security-domains>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:transactions:5.0">
|
||||
<core-environment node-identifier="${jboss.tx.node.id:1}">
|
||||
<process-id>
|
||||
<uuid/>
|
||||
</process-id>
|
||||
</core-environment>
|
||||
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
|
||||
<coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
|
||||
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
|
||||
<subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/>
|
||||
<subsystem xmlns="urn:wildfly:microprofile-health-smallrye:2.0" security-enabled="false" empty-liveness-checks-status="${env.MP_HEALTH_EMPTY_LIVENESS_CHECKS_STATUS:UP}" empty-readiness-checks-status="${env.MP_HEALTH_EMPTY_READINESS_CHECKS_STATUS:UP}"/>
|
||||
<subsystem xmlns="urn:wildfly:microprofile-metrics-smallrye:2.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:wildfly}"/>
|
||||
<subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
|
||||
<buffer-cache name="default"/>
|
||||
<server name="default-server">
|
||||
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
|
||||
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
|
||||
<host name="default-host" alias="localhost">
|
||||
<location name="/" handler="welcome-content"/>
|
||||
<http-invoker security-realm="ApplicationRealm"/>
|
||||
</host>
|
||||
</server>
|
||||
<servlet-container name="default">
|
||||
<jsp-config/>
|
||||
<websockets/>
|
||||
</servlet-container>
|
||||
<handlers>
|
||||
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
|
||||
</handlers>
|
||||
</subsystem>
|
||||
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
|
||||
<web-context>auth</web-context>
|
||||
<providers>
|
||||
<provider>classpath:${jboss.home.dir}/providers/*</provider>
|
||||
</providers>
|
||||
<master-realm-name>master</master-realm-name>
|
||||
<scheduled-task-interval>900</scheduled-task-interval>
|
||||
<theme>
|
||||
<staticMaxAge>2592000</staticMaxAge>
|
||||
<cacheThemes>true</cacheThemes>
|
||||
<cacheTemplates>true</cacheTemplates>
|
||||
<dir>${jboss.home.dir}/themes</dir>
|
||||
</theme>
|
||||
<spi name="eventsStore">
|
||||
<provider name="jpa" enabled="true">
|
||||
<properties>
|
||||
<property name="exclude-events" value="["REFRESH_TOKEN"]"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="userCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="userSessionPersister">
|
||||
<default-provider>jpa</default-provider>
|
||||
</spi>
|
||||
<spi name="timer">
|
||||
<default-provider>basic</default-provider>
|
||||
</spi>
|
||||
<spi name="connectionsHttpClient">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsJpa">
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="dataSource" value="java:jboss/datasources/KeycloakDS"/>
|
||||
<property name="initializeEmpty" value="true"/>
|
||||
<property name="migrationStrategy" value="update"/>
|
||||
<property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="realmCache">
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="connectionsInfinispan">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="jta-lookup">
|
||||
<default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider>
|
||||
<provider name="jboss" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="publicKeyStorage">
|
||||
<provider name="infinispan" enabled="true">
|
||||
<properties>
|
||||
<property name="minTimeBetweenRequests" value="10"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
<spi name="x509cert-lookup">
|
||||
<default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider>
|
||||
<provider name="default" enabled="true"/>
|
||||
</spi>
|
||||
<spi name="hostname">
|
||||
<default-provider>default</default-provider>
|
||||
<provider name="default" enabled="true">
|
||||
<properties>
|
||||
<property name="frontendUrl" value="${keycloak.frontendUrl:}"/>
|
||||
<property name="forceBackendUrlToFrontendUrl" value="false"/>
|
||||
</properties>
|
||||
</provider>
|
||||
</spi>
|
||||
</subsystem>
|
||||
</profile>
|
||||
<interfaces>
|
||||
<interface name="management">
|
||||
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
|
||||
</interface>
|
||||
<interface name="public">
|
||||
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
|
||||
</interface>
|
||||
</interfaces>
|
||||
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
|
||||
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
|
||||
<socket-binding name="http" port="${jboss.http.port:8080}"/>
|
||||
<socket-binding name="https" port="${jboss.https.port:8443}"/>
|
||||
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
|
||||
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
|
||||
<socket-binding name="txn-recovery-environment" port="4712"/>
|
||||
<socket-binding name="txn-status-manager" port="4713"/>
|
||||
<outbound-socket-binding name="mail-smtp">
|
||||
<remote-destination host="localhost" port="25"/>
|
||||
</outbound-socket-binding>
|
||||
</socket-binding-group>
|
||||
</server>
|
|
@ -1,10 +1,11 @@
|
|||
terraform {
|
||||
backend "pg" {
|
||||
schema_name = "terraform_remote_state_stage1"
|
||||
}
|
||||
}
|
||||
|
||||
data "external" "hetzner_cloud_api_key" {
|
||||
program = ["${path.module}/misc/get_key.py", "misc/vault_hetzner.yml", "hetzner_cloud_api_key", "json"]
|
||||
program = ["${path.module}/../misc/get_key.py", "misc/vault_hetzner.yml", "hetzner_cloud_api_key", "json"]
|
||||
}
|
||||
|
||||
data "hcloud_image" "archlinux" {
|
||||
|
@ -71,7 +72,7 @@ resource "hcloud_rdns" "gitlab" {
|
|||
resource "hcloud_server" "gitlab" {
|
||||
name = "gitlab.archlinux.org"
|
||||
image = data.hcloud_image.archlinux.id
|
||||
server_type = "cx21"
|
||||
server_type = "cx31"
|
||||
lifecycle {
|
||||
ignore_changes = [image]
|
||||
}
|
||||
|
@ -117,6 +118,10 @@ resource "hcloud_server" "accounts" {
|
|||
name = "accounts.archlinux.org"
|
||||
image = data.hcloud_image.archlinux.id
|
||||
server_type = "cx11"
|
||||
provisioner "local-exec" {
|
||||
working_dir = ".."
|
||||
command = "ansible-playbook --ssh-extra-args '-o StrictHostKeyChecking=no' playbooks/accounts.archlinux.org.yml"
|
||||
}
|
||||
lifecycle {
|
||||
ignore_changes = [image]
|
||||
}
|
||||
|
@ -187,3 +192,33 @@ resource "hcloud_server" "aur-dev" {
|
|||
ignore_changes = [image]
|
||||
}
|
||||
}
|
||||
|
||||
resource "hcloud_rdns" "mailman3" {
|
||||
server_id = hcloud_server.mailman3.id
|
||||
ip_address = hcloud_server.mailman3.ipv4_address
|
||||
dns_ptr = "mailman3.archlinux.org"
|
||||
}
|
||||
|
||||
resource "hcloud_server" "mailman3" {
|
||||
name = "mailman3.archlinux.org"
|
||||
image = data.hcloud_image.archlinux.id
|
||||
server_type = "cx11"
|
||||
lifecycle {
|
||||
ignore_changes = [image]
|
||||
}
|
||||
}
|
||||
|
||||
resource "hcloud_rdns" "reproducible" {
|
||||
server_id = hcloud_server.reproducible.id
|
||||
ip_address = hcloud_server.reproducible.ipv4_address
|
||||
dns_ptr = "reproducible.archlinux.org"
|
||||
}
|
||||
|
||||
resource "hcloud_server" "reproducible" {
|
||||
name = "reproducible.archlinux.org"
|
||||
image = data.hcloud_image.archlinux.id
|
||||
server_type = "cx11"
|
||||
lifecycle {
|
||||
ignore_changes = [image]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
terraform {
|
||||
backend "pg" {
|
||||
schema_name = "terraform_remote_state_stage2"
|
||||
}
|
||||
}
|
||||
|
||||
data "external" "keycloak_admin_user" {
|
||||
program = ["${path.module}/../misc/get_key.py", "group_vars/all/vault_keycloak.yml", "vault_keycloak_admin_user", "json"]
|
||||
}
|
||||
|
||||
data "external" "keycloak_admin_password" {
|
||||
program = ["${path.module}/../misc/get_key.py", "group_vars/all/vault_keycloak.yml", "vault_keycloak_admin_password", "json"]
|
||||
}
|
||||
|
||||
data "external" "keycloak_smtp_user" {
|
||||
program = ["${path.module}/../misc/get_key.py", "group_vars/all/vault_keycloak.yml", "vault_keycloak_smtp_user", "json"]
|
||||
}
|
||||
|
||||
data "external" "keycloak_smtp_password" {
|
||||
program = ["${path.module}/../misc/get_key.py", "group_vars/all/vault_keycloak.yml", "vault_keycloak_smtp_password", "json"]
|
||||
}
|
||||
|
||||
provider "keycloak" {
|
||||
client_id = "admin-cli"
|
||||
username = data.external.keycloak_admin_user.result.vault_keycloak_admin_user
|
||||
password = data.external.keycloak_admin_password.result.vault_keycloak_admin_password
|
||||
url = "https://accounts.archlinux.org"
|
||||
}
|
||||
|
||||
variable "gitlab_instance" {
|
||||
default = {
|
||||
root_url = "https://gitlab.archlinux.org"
|
||||
saml_redirect_url = "https://gitlab.archlinux.org/users/auth/saml/callback"
|
||||
}
|
||||
}
|
||||
|
||||
resource "keycloak_realm" "master" {
|
||||
realm = "master"
|
||||
enabled = true
|
||||
remember_me = true
|
||||
display_name = "Arch Linux"
|
||||
|
||||
reset_password_allowed = true
|
||||
verify_email = true
|
||||
|
||||
smtp_server {
|
||||
host = "mail.archlinux.org"
|
||||
from = "accounts@archlinux.org"
|
||||
port = "587"
|
||||
from_display_name = "Arch Linux Accounts"
|
||||
ssl = false
|
||||
starttls = true
|
||||
|
||||
auth {
|
||||
username = data.external.keycloak_smtp_user.result.vault_keycloak_smtp_user
|
||||
password = data.external.keycloak_smtp_password.result.vault_keycloak_smtp_password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "keycloak_saml_client" "saml_gitlab" {
|
||||
realm_id = "master" // "${keycloak_realm.realm.id}"
|
||||
client_id = "saml_gitlab"
|
||||
|
||||
name = "Arch Linux Accounts"
|
||||
enabled = true
|
||||
|
||||
sign_documents = true
|
||||
sign_assertions = true
|
||||
|
||||
// access_type = "CONFIDENTIAL"
|
||||
valid_redirect_uris = [
|
||||
var.gitlab_instance.saml_redirect_url
|
||||
]
|
||||
|
||||
root_url = var.gitlab_instance.root_url
|
||||
base_url = "/" // needed?
|
||||
master_saml_processing_url = var.gitlab_instance.saml_redirect_url // needed?
|
||||
// idp_initiated_sso_url_name = self.client_id
|
||||
idp_initiated_sso_url_name = "saml_gitlab"
|
||||
|
||||
assertion_consumer_post_url = var.gitlab_instance.saml_redirect_url
|
||||
}
|
||||
|
||||
|
||||
resource "keycloak_saml_user_property_protocol_mapper" "gitlab_saml_email" {
|
||||
realm_id = "master"
|
||||
client_id = keycloak_saml_client.saml_gitlab.id
|
||||
|
||||
name = "email"
|
||||
user_property = "Email"
|
||||
friendly_name = "Email"
|
||||
saml_attribute_name = "email"
|
||||
saml_attribute_name_format = "Basic"
|
||||
}
|
||||
|
||||
|
||||
resource "keycloak_saml_user_property_protocol_mapper" "gitlab_saml_name" {
|
||||
realm_id = "master"
|
||||
client_id = keycloak_saml_client.saml_gitlab.id
|
||||
|
||||
name = "name"
|
||||
user_property = "Username"
|
||||
friendly_name = "Username"
|
||||
saml_attribute_name = "name"
|
||||
saml_attribute_name_format = "Basic"
|
||||
}
|
||||
|
||||
|
||||
resource "keycloak_saml_user_property_protocol_mapper" "gitlab_saml_first_name" {
|
||||
realm_id = "master"
|
||||
client_id = keycloak_saml_client.saml_gitlab.id
|
||||
|
||||
name = "first_name"
|
||||
user_property = "FirstName"
|
||||
friendly_name = "First Name"
|
||||
saml_attribute_name = "first_name"
|
||||
saml_attribute_name_format = "Basic"
|
||||
}
|
||||
|
||||
|
||||
resource "keycloak_saml_user_property_protocol_mapper" "gitlab_saml_last_name" {
|
||||
realm_id = "master"
|
||||
client_id = keycloak_saml_client.saml_gitlab.id
|
||||
|
||||
name = "last_name"
|
||||
user_property = "LastName"
|
||||
friendly_name = "Last Name"
|
||||
saml_attribute_name = "last_name" // maybe just name
|
||||
saml_attribute_name_format = "Basic"
|
||||
}
|
||||
|
||||
variable "arch_groups" {
|
||||
type = set(string)
|
||||
default = ["DevOps", "Developers", "Trusted Users"]
|
||||
}
|
||||
|
||||
resource "keycloak_group" "arch_groups" {
|
||||
for_each = var.arch_groups
|
||||
|
||||
realm_id = "master"
|
||||
name = each.value
|
||||
}
|
||||
|
||||
resource "keycloak_role" "devops" {
|
||||
realm_id = "master"
|
||||
name = "DevOps"
|
||||
description = "DevOps role"
|
||||
}
|
||||
|
||||
resource "keycloak_group_roles" "group_roles" {
|
||||
realm_id = "master"
|
||||
group_id = keycloak_group.arch_groups["DevOps"].id
|
||||
role_ids = [
|
||||
keycloak_role.devops.id
|
||||
]
|
||||
}
|
||||
|
||||
output "gitlab_saml_configuration" {
|
||||
value = {
|
||||
issuer = keycloak_saml_client.saml_gitlab.client_id
|
||||
assertion_consumer_service_url = var.gitlab_instance.saml_redirect_url
|
||||
admin_groups = [keycloak_role.devops.name]
|
||||
idp_sso_target_url = "https://accounts.archlinux.org/auth/realms/master/protocol/saml/clients/${keycloak_saml_client.saml_gitlab.client_id}"
|
||||
signing_certificate_fingerprint = keycloak_saml_client.saml_gitlab.signing_certificate
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
|
||||
terraform {
|
||||
required_version = ">= 0.12"
|
||||
}
|
Loading…
Reference in New Issue