この記事はLinuxClub Advent Calendar 2020の12日目です.
今回は研究室の環境においてID管理サーバであるSTNSの設定を自動生成した取り組みを紹介します.
STNSとは
STNSの正式名称はSimple TOML Name Serviceです.
RESTful APIを実装したサーバによるユーザ管理を実現しています.
詳細は以下の公式サイトに書いてあります.
STNS: Simple TOML Name Service
STNSの設定ファイル
STNSではユーザやグループの情報はTOML形式で設定ファイルに記述します.
port = 1104
[users.koyama]
id = 2001
group_id = 2001
keys = ["ssh-rsa ZZZZZZZ"]
[groups.operators]
id = 2001
users = ["koyama"]
この設定ファイルはユーザ数が増えるにつれ,行数も増加することが考えられました.そこで設定ファイルをプログラムにより動的に生成することにしました.
STNSの設定ファイルを生成
設定ファイルの生成はPythonで作成したプログラムを使用しています.
import toml
import csv
def main():
my_groups = {}
result = {}
with open("groups.csv") as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='"', skipinitialspace=True)
next(spamreader)
for row in spamreader:
groupname, gid = row
my_groups[groupname] = {"id": int(gid)}
with open("users.csv") as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='"', skipinitialspace=True)
next(spamreader)
for row in spamreader:
user_id, ssh_key = row
if result.get(user_id):
result[user_id]["keys"] += [ssh_key]
else:
result[user_id] = {"keys": [ssh_key]}
with open("uid.csv") as csvfile:
spamreader = csv.reader(csvfile, delimiter=',', quotechar='"', skipinitialspace=True)
next(spamreader)
for row in spamreader:
user_id, uid, gid = row
if result.get(user_id):
result[user_id]["id"] = int(uid)
result[user_id]["group_id"] = int(gid)
else:
print("error:", user_id)
# for k,v in result.items():
# print(k, v)
toml.dump({"users": result, "groups": my_groups}, open('stns_generated.toml', mode='w'))
if __name__ == "__main__":
main()
設定内容(ユーザ,グループ)は以下の形式でCSVファイルとして保存します.
username, pubkey
koyama, "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA..."
userid, uid, gid
koyama, 2001, 2001
groupname, gid
koyama, 2001
gen.pyを実行するとstns_generated.tomlが生成されます.
これをstns.toml内でincludeすることで設定を利用することができます.
python gen.py
GitHub Actionsで実行
GitHub ActionsはGitHubが提供するCIプラットフォームです.GitHubへのPushやCommitを始めとする操作やスケジュールされた日時を起点にあらかじめ定義したジョブを実行できます.今回は.github/workflows/deploy.yamlとして以下の設定ファイルを作成しました.
name: Deploy base-x
# GitHubのmasterブランチへPushがあると起動
on:
push:
branches:
- master
jobs:
# self-hosted runner(オンプレミス)で動作するGitHub Actions Runnerで設定ファイルの生成と配置を行う
deploy:
runs-on: self-hosted
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Setup Python
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Generate config
run: |
python gen.py
- name: Copy config
run: |
cp cdsl.toml /share/stns/conf.d
# STNSの再起動を行う
restart-m:
runs-on: base-m
needs: deploy
steps:
- name: Restart STNS
run: |
sudo systemctl restart stns.service
# STNSの再起動を行う
restart-j:
runs-on: base-j
needs: deploy
steps:
- name: Restart STNS
run: |
sudo systemctl restart stns.service
# Slackへ変更したことを通知
slack_notification:
name: Slack Notification
runs-on: ubuntu-latest
needs: [restart-m, restart-j]
steps:
- uses: actions/checkout@v2
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: lab-env
SLACK_COLOR: '#3278BD'
SLACK_ICON: https://github.com/cdsl-research.png?size=48
SLACK_MESSAGE: 'STNS Config Update :rocket:'
SLACK_TITLE: Message
SLACK_USERNAME: STNS-Config-Updater
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
この設定では,設定ファイルのビルドと配置を行いSTNSを再起動しています.その後,変更が完了した通知をSlackにポストします.以下は実際に実行した結果です.
おわりに
GitHub Actionsを使うことで設定ファイルのバージョン管理と自動生成,自動デプロイを実現しました.これにより設定ファイルを誰がいつ変更したのか明確に残すことができます.また,コマンドによるサーバのオペレーションを排除することで属人化を防ぐことにつながりました.
今後はSTNSをコンテナ化して自動デプロイするCIをGitHub Actionsを通じて構築したいと思います.