見出し画像

Jamf Pro をコード管理してみたいので管理ツールを作ってみた

以前 GitHub Actions を使って GitHub -> Jamf Pro へ Script をデプロイする検証をしました。

このときは Jamf Pro の API や GitHub Actions ワークフローの動作検証が目的でしたが、実用に向けてその後コツコツと改修を進めまして、業務でも試せそうになりました。

主な変更点は以下のとおりです。

・デプロイ可能な Jamf Pro のオブジェクトを追加
 ・Policies
 ・Scripts
 ・Computer Groups (Smart / Static)
 ・Categories
・構成ファイルを YAML 形式で記述できるよう変更
・デプロイツールの言語を Go に変更
・Jamf Pro の API Client を作成

管理ツールの概要と、このツールを使うことで何がどう嬉しくなりそうか、を書いていきます。

管理ツールの概要

仕組みや挙動の概要です。 GitHub リポジトリの README にもいろいろ書いてあるので参照いただければ。

・構成ファイルにリソースの設定値を YAML で記述 
・構成ファイルを GitHub リポジトリの main ブランチにマージ
・GitHub Actions がキックされ、デプロイのワークフロー処理が走る
・構成ファイルで定義したリソースを Jamf Pro 上に作成 (or 更新)
・作成したリソースに割り当てられた ID を構成ファイルに上書き


### 構成ファイルの書き方の例
テスト用に作成した「DNS 設定を変更する Script を配布するための Policy の構成ファイル」です。要素名でなんとなく雰囲気は伝わるのではないかと。

# deployConifg.yml

policy:
  general:
    id: 0
    name: DNS Setteing
    enabled: true
    frequency: Ongoing
    offline: false
    category:
      id: 3
      name: Network
  scope:
    all_computers: true
  self_service:
    use_for_self_service: true
    self_service_display_name: DNS Setting
    install_button_text: Execute
    reinstall_button_text: Re Execute
    self_service_description: DNS 設定を Public DNS (Google), 1.1.1.1 (Cloudflare) に変更します。
  scripts:
    size: 1
    script:
    - id: 0
      name: set-wifi-dnsConfig.sh
      priority: After
script:
- id: 0
  name: set-dnsConfig.sh
  priority: AFTER
  categoryId: 3

スクリプトの実コードを構成ファイル内に記述するのは現実的でないため、構成ファイルと同一ディテクトリ内にスクリプト (set-dnsConfig.sh) を配置し、デプロイ時にファイルの中身を読み取る仕様としています。

また新規でリソースを作成する場合は `id: 0` で定義します。これは Jamf Pro の API 仕様にならったもので、ツール内で “0 -> 新規作成するリソース” と判定しています。

### 使い方
以下の環境変数で、デプロイ対象のテナントや API アクセス時に使用する認証情報を指定します。

JAMF_URL … デプロイ先の Jamf Pro テナントの URL
JAMF_USER … API アクセス時の認証で利用する Jamf Pro アカウント名
JAMF_USER_PASSWORD … Jamf Pro アカウントのパスワード

(参考)
TARGET_DIR … デプロイ対象の構成ファイルを配置しているディレクトリ

環境変数は .github/workflows/main.yml (GitHub Actions ワークフローの定義ファイル) やGitHub の Secrets で設定します。

- 環境変数 - GitHub Docs
- 暗号化されたシークレット - GitHub Docs

# .github/workflows/main.yml

on:
  push:
    branches:
      -  main
~
~
      - name: deploy
        env:
          JAMF_URL: "https://<your-tenant-name>.jamfcloud.com"
          JAMF_USER: "Account name"
          JAMF_USER_PASSWORD: ${{ secrets.JAMF_USER_PASSWORD }}
          TARGET_DIR: ""

TARGET_DIR の値は、ワークフローのなかで git diff コマンドを実行し、直近のコミットから差分のあるディレクトリを識別して自動設定しています。

ローカル環境でも上記の環境変数を指定 & deploy.go を手動実行することで Jamf Pro へのデプロイが可能です。


### 新規作成したリソースの ID を構成ファイルに自動反映
API 経由でリソースの設定を更新する場合、対象リソースを ID で指定します。よって、新規作成したリソースの ID を何らかの方法で確認する必要があります。
 
API でリソースを作成すると、当該リソースに割り当てられた ID を含む Response body が返ります。

- Creates a new Policy - The Classic API Reference

本ツールでは、この ID を取得して構成ファイルの `id: 0`の値を更新するようにしています。

さらに GitHub Actions のワークフローで自動コミット・マージして main ブランチで管理する構成ファイルへ ID の値を反映させています。

# .github/workflows/main.yml

~
      - name: git setting
        run: |
          git config --local user.email "dummy-address"
          git config --local user.name "jamf-pro-manager"
      - name: Commit deployConfig.yml
        run: |
          if (git diff --shortstat | grep '[0-9]'); then \
            git add `git diff --name-only | grep 'deployConfig.yml'` ;\
            git commit -m "auto-commit (update deployConfig.yml)" ;\
            git pull origin main ;\
            git push origin main ;\
          fi

嬉しみ①: 1 つの構成ファイルで関連リソースの設定を見通せる

このツールの作成は、もともとはこのツイートから始まったのでした。

Jamf Pro の [ Scripts ] 管理画面では、Script がどの Policy に紐付けられているかを把握できません。
また [ Policies ] 管理画面では Script の名称を指定する際に設定内容を確認できないので「この Script であってるっけ?」とそれぞれの管理画面を別ウィンドウで開いて見比べながら設定作業をすることが多いです。(私の場合。)

「 1 つの構成ファイルで関連リソースを定義すれば関係を把握しやすくなるのでは?」と思い、Jamf Pro のリソースを IaC (Infrastructure as Code) の考え方でコード管理できるか検証を始めました。

設定が単純な Policy の場合はメリットは薄いかもしれませんが、複数の Script と紐付けたり、Smart Computer Group の Criteria の条件まで見えるようになってくると、コード管理のありがたみを感じるようになるのかなと思っています。

嬉しみ②: バージョン管理ができる

Jamf Pro は管理画面上 (Web エディタ) で Script Contents を記述できて便利です。ただ、変更履歴を保持する仕組みありません。History というスナップショットのような機能が用意されていますが、Script Contents は対象外のようです。

また History は「そのときの設定値の状態」が表示されるのみで「どの項目を、何から何に変更したのか」という差分を把握しづらいです。CSV ファイルにエクスポートして比較することもできはますが、あまり楽しい手段ではありません。。

(ご参考) Scripts - History


コード管理を GitHub で行う
ことで、バージョン管理をはじめとした GitHub の各種機能を利用できます。変更の差分が把握しやすくなるのはメリットですね。以下の画面は、Policy の scope を検証用端末から全台適用に変更したときの差分です。

嬉しみ③: 変更管理のフローがつくれる

変更管理において、以下のニーズはあるあるだと思います。

・本番環境の設定変更時にはメンバーのレビューや変更承認を受けたい
・変更の理由や意思決定のプロセスを記録しておきたい
・メンバーに変更点を共有したい(認識しておいてもらいたい)

上記を実現するために GitHub 側では以下の運用をする予定です。

・ブランチを切って作成(更新)するリソース用の構成ファイルを作成
・メンバーをレビュワーに指定して main ブランチへの Pull Request を出す
・レビュー完了後にマージする (Jamf Pro へ自動デプロイされる)

GitHub のブランチ保護機能を使えば「マージ前に第三者による Pull Request レビューを必須とする」ことができ、より厳密にフローを構築することができます。

※ ブランチ保護を有効にすると、前述した「作成したリソースの ID を構成ファイルに上書きして自動マージ 」がコケてしまうので対応を検討中。

嬉しみ④: 構成ファイルがあるので横展開しやすそう

組織をまたいでこんなことができたらいいな〜というお話です。

構成ファイルがあることで、同一の設定を複数の Jamf Pro 環境へ横展開しやすくなります。デプロイ先の Jamf Pro 環境 (URL 等) の設定を変更するだけで、同一の設定が容易に展開できます。

「ウチの会社のこの Policy や Script, けっこうイケてるからみんなにも使ってほしい」を持ち寄って、みんなの Jamf Pro レシピがつくれたらおもしろそうだなー、と妄想しています。

Jamf Pro に登録済みリソースの設定を取得・構成ファイルを生成する自動化ツールも用意したので、手間は省けるんじゃないかなと思います。
・ツール: https://github.com/pirox07/jamf-pro-manager/tree/main/utilities
・ツールの実行には Go の実行環境が必要
・現在は Policies, Scripts, Computer Groups, Categories をサポート

今回作成したデプロイツールは GitHub Actions で動かす想定のものですが、ローカル実行への転用は容易なので、もし興味ある方がいらっしゃれば一緒にどうでしょうか〜??という募集でした。

カイゼンしたいこと

いくつかカイゼンしたい機能があります。

### 不要な更新操作をスキップしたい 
現状の仕様では、構成ファイル内で定義したリソースに対して一律で作成 or 更新の処理がかかります。たとえば Policy の名前のみを変更するため以下のように記述してデプロイすると、変更が発生していない Script に対しても更新処理を行ってしまいます。

# deployConfig.yml

policy:
  id: 1
  name: sample policy  # <- sample-policy から変更
  ~
  script
script:
  id: 3
  name: sample-policy.sh
  ~

同一の値で更新するので変更はされないのですが、History には Edited と記録されますし、思わぬ事故が起きてしまいそうでなんとかしたい。。
Terraform がこの辺りをどう実現しているのか確認したいです。


### 管理可能なオブジェクトを増やしたい
 
構成ファイルで管理できるオブジェクトが増えると「セキュリティに関するポリシーや構成プロファイルの設定一式は、すべてこの構成ファイルで定義して適切に変更管理しています」と言える状態になると良いなーと想像しています。

### とにもかくにも使用実績を積みたい
Policy の設定項目が多岐にわたりすぎて、使用頻度の低い項目は動作テストができていません。。 API リファレンスの情報をもとに作成はしていますが、実利用を待っている設定項目が多くあります。

今後の予定

社内で使っていくことで Jamf Pro におけるコード管理の落とし所を探りたいです。全てに対してコード管理のアプローチをとるのは  ”手段の目的化” でツラくなるという話をよく目にします。どのオブジェクトが向いているのか、それともカテゴリ (性質) の切り口で管理対象を決めたほうがいいのか、やっぱり原則すべてをコード管理した方がいいのか、といったスコープが気になっています。

というわけで、Jamf Pro をコード管理するメリデメを検証していければと思いますーー!!

*************** 追記 ***************

Community ベースではあるものの Teraform Provider があって何だか使えそう!!

いただいたサポートは記事を書くためのエネルギー(珈琲、甘いもの)に変えさせていただきます!