前回の記事「Terraform を使用した Jamf 構成の管理: 入門編」では、Infrastructure as Code の基礎と Terraform および Jamf Pro の使い始め方について説明しました。まだお読みになっていない場合は、Terraform の基礎、インストール、プロジェクト構造、状態管理について扱っているため、そちらから始めることをお勧めします。
今回は、Jamf Protect に焦点を当てています。Jamf Protect 製品の構成をコードで管理できる専用 Terraform プロバイダーを構築しました。プラン、アクション構成、例外セットなど、さらに多くのリソースを管理できます。
Jamf Protect 専用プロバイダーが必要な理由
Jamf Pro と同様に、Jamf Protect は独立した製品であり、Jamf Platform ファミリーの一部です。独自の API サーフェス (GraphQL ベース) と、Jamf Pro および他の Jamf Platform マイクロサービス (例: Blueprints と Compliance Benchmarks) とは異なる独自のリソースセットを備えています。エンドポイント セキュリティ プラン、テレメトリ構成、リムーバブル ストレージ ポリシーなど、これらはすべて Jamf Protect に存在し、適切に管理するための専用プロバイダーが必要です。
Jamf Protect コンソールを通じて構成を管理している場合、テナント間でセットアップを再作成したり、変更をロールバックしたりすることは多くの手作業を伴うことをご存知でしょう。このプロバイダーを使用すれば、Jamf Protect の構成全体を Git に置き、コード レビューを経由し、環境全体で一貫性を持って適用できます。
どのようなものをカバーしていますか?
このプロバイダーは 16 個のリソース と 18 個のデータ ソース を備えています。主な対象範囲を以下に示します:
脅威検出と防止
- カスタム防止リスト - Team ID、ファイル ハッシュ、CDHash、または署名 ID による許可/ブロック リスト。
- 例外セット - 分析とエンドポイント セキュリティ コントロールの例外。
エンドポイント構成
- プラン - 脅威防止モード、通信プロトコル、レポート間隔、デバイス情報収集を含む完全なエンドポイント セキュリティ構成。
- アクション構成 - アラート データ エンリッチメント とレポート エンドポイント (HTTP、Kafka、クラウド)。
- テレメトリ - イベント とログ収集: セキュリティ イベント、認証、ファイル整合性監視、パフォーマンス メトリックスなど。
デバイス制御
- リムーバブル ストレージ コントロール セット - ベンダー ID、製品 ID、またはシリアル番号によるオーバーライドを含む USB デバイス ポリシー。
運用設定
- データ転送 - Amazon S3、Microsoft Sentinel、またはクラウド エンドポイントへのデータ ルーティング。
- データ保持 - テナント全体の保持ポリシー。
- 変更管理 - 構成フリーズ。
- 統合ログ フィルター - NSPredicate フィルターを使用した macOS 統合ログ収集。
アクセス制御
- ユーザー、グループ、ロール、API クライアント - コードでアクセスと権限を管理。
すべてのリソースは完全な CRUD 操作と terraform import をサポートしています。
jamfprotect_change_management、jamfprotect_data_forwarding、jamfprotect_data_retention はシングルトン リソースであることに注意してください。これらは個別に識別可能なオブジェクトではなく、テナント全体の設定を管理します。
はじめに
導入記事に従った場合、Terraform がインストールされており、プロジェクトの構成方法について基本的な理解があるはずです。ここでの手順は似ています。
1. Jamf Protect で API クライアントを作成する
Jamf Protect コンソールで [管理] > [API クライアント] に移動し、管理するリソースに必要な権限を持つ新しい API クライアントを作成します。
2. プロバイダーを構成する
Terraform 構成にプロバイダーを追加します:
terraform {
required_providers {
jamfprotect = {
source = "Jamf-Concepts/jamfprotect"
version = "~> 0.1.0"
}
}
}
provider "jamfprotect" {
url = "https://your-tenant.protect.jamfcloud.com"
client_id = var.jamfprotect_client_id
client_secret = var.jamfprotect_client_secret
}
プロバイダー ブロックをシンプルに保ちたい場合は、環境変数を使用することもできます:
export JAMFPROTECT_URL="https://your-tenant.protect.jamfcloud.com"
export JAMFPROTECT_CLIENT_ID="your-client-id"
export JAMFPROTECT_CLIENT_SECRET="your-client-secret"
Jamf Pro プロバイダーと同様に、これらの資格情報が Git リポジトリに入らないようにしてください。terraform.tfvars ファイルを使用し、.gitignore に追加します。
3. リソースを定義する
収集するデータとアラート送信先を定義するアクション構成の例を次に示します:
resource "jamfprotect_action_configuration" "default" {
name = "Default Action Config"
alert_data_collection = {
binary_included_data_attributes = ["Sha256", "Signing Information"]
download_event_included_data_attributes = ["File"]
file_included_data_attributes = ["Sha256", "Signing Information"]
file_system_event_included_data_attributes = ["File", "Process"]
gatekeeper_event_included_data_attributes = ["Blocked Process"]
group_included_data_attributes = ["Name"]
keylog_register_event_included_data_attributes = ["Source Process"]
process_included_data_attributes = ["Args", "Signing Information", "Binary", "User", "Parent"]
process_event_included_data_attributes = ["Process"]
screenshot_event_included_data_attributes = ["File"]
synthetic_click_event_included_data_attributes = ["Process"]
user_included_data_attributes = ["Name"]
}
jamf_protect_cloud_endpoint = {
collect_alerts = ["low", "medium", "high"]
collect_logs = ["telemetry"]
}
}
承認された暗号化ドライブを除くすべての USB ストレージをブロックするリムーバブル ストレージ ポリシー:
resource "jamfprotect_removable_storage_control_set" "strict" {
name = "Strict USB Policy"
description = "Block all removable storage except encrypted devices."
default_permission = "Prevent"
default_local_notification_message = "Removable storage devices are not permitted."
override_encrypted_devices = [
{
permission = "Read and Write"
},
]
}
既知の IT 管理ツールを脅威防止から除外する例外セット:
resource "jamfprotect_exception_set" "it_admin_tools" {
name = "IT Admin Tools"
description = "Exceptions for trusted IT administration software."
exceptions = [
{
type = "Override Endpoint Threat Prevention"
sub_type = "Process"
rules = [
{
rule_type = "Team ID"
value = "EQHXZ8M8AV"
},
]
},
]
}
リソースを作成する代わりにデータ ソースを使用して既存のリソースを参照することもできます。ここでは、テナントに既に存在する Jamf Managed Default Exceptions セットを検索します:
data "jamfprotect_exception_sets" "all" {}
locals {
jamf_managed_default_exceptions = [
for es in data.jamfprotect_exception_sets.all.exception_sets :
es if es.name == "Jamf Managed Default Exceptions"
][0]
}
これらのリソースはプランで結合でき、これがエンドポイントにデプロイされる構成です:
resource "jamfprotect_plan" "endpoint_security" {
name = "Endpoint Security Plan"
description = "Standard endpoint security plan with threat prevention."
action_configuration = jamfprotect_action_configuration.default.id
removable_storage_control_set = jamfprotect_removable_storage_control_set.strict.id
exception_sets = [
jamfprotect_exception_set.it_admin_tools.id,
local.jamf_managed_default_exceptions.uuid,
]
endpoint_threat_prevention = "Block and report"
advanced_threat_controls = "Block and report"
tamper_prevention = "Block and report"
reporting_interval = 1440
compliance_baseline_reporting = true
auto_update = true
communications_protocol = "MQTT:443"
log_level = "Error"
report_architecture = true
report_hostname = true
report_serial_number = true
report_model_name = true
report_os_version = true
}
プランは他のリソースを ID で参照するため、Terraform は依存関係グラフを理解し、正しい順序ですべてを作成します。
4. 構成を適用する
導入編で学んだ同じコマンドがここで適用されます:
terraform init # プロバイダーを初期化してダウンロード
terraform plan # 作成、変更、または削除される内容をレビュー
terraform apply # 変更を適用 (確認を求められます)
既存のテナントを管理下に置く
既に既存の構成を持つ Jamf Protect テナントがある場合、ゼロから始める必要はありません。プロバイダーのすべてのリソースは terraform import をサポートしているため、既存のリソースを再作成せずに Terraform 管理下に置くことができます。
Terraform クエリを使用した既存リソースの発見
Terraform 1.14+ を実行している場合、プロバイダーはリスト リソースをサポートしています。これは Terraform から直接既存のインフラストラクチャをクエリできる新機能です。テナントに既に何があるかを確認してからインポートする場合に便利です。
クエリ ファイル (例: discover.tfquery.hcl) を作成します:
list "jamfprotect_plan" "all" {
provider = jamfprotect
include_resource = true
}
list "jamfprotect_exception_set" "custom" {
provider = jamfprotect
config {
name_prefix = "Custom"
}
}
その後、以下を実行します:
terraform query -generate-config-out=generated.tf
Terraform は Jamf Protect テナントをクエリし、一致するリソースとその ID を返し、リソース ブロックとインポート ブロックの両方を generated.tf に生成します。プロバイダーのすべてのリスト リソースは config ブロック内の name_prefix フィルター (またはユーザーの場合は email_prefix) をサポートしているため、結果を探しているものに絞り込むことができます。
以下のシングルトン リソースを除くすべてのリソース タイプがリスト クエリをサポートしています:
jamfprotect_change_managementjamfprotect_data_forwardingjamfprotect_data_retention
リソースをインポートする
必要な ID を取得したら、インポート ブロックを使用して管理下に置くことができます。Terraform 1.5+ の場合:
import {
to = jamfprotect_plan.endpoint_security
id = "your-plan-uuid"
}
terraform plan を実行してインポートされたリソースの構成を生成し、必要に応じてリファインして、その時点からコードとして管理されます。リソースの一括インポートの詳細については、HashiCorp の一括インポート ドキュメントを参照してください。
他の Jamf プロバイダーと併用する
このプロバイダーは Jamf エコシステムの他の Terraform プロバイダーと一緒に動作するように設計されています。以下と一緒に使用できます:
- Jamf Platform プロバイダー - Jamf Platform API 経由で Jamf Platform のリソース (例: Blueprints と Compliance Benchmarks) を管理します。
- Deployment Theory Jamf Pro プロバイダー - Classic API と Pro API 経由で Jamf Pro 製品のリソースを管理します。
これらのプロバイダー間で、単一の Terraform プロジェクトから Jamf 環境全体をコードとして管理できます。
背景
このプロバイダーはもともと James Smith (@smithjw) によって作成され、寛大にも Jamf Concepts にソース コードを寄付してくれました。この実現を可能にしてくださった James の基礎的な仕事に感謝します。
このプロバイダーは MPL 2.0 ライセンスの下でオープンソース化され、HashiCorp の Terraform Plugin Framework (Protocol v6) 上に構築されています。全体にわたってユニット テストと受け入れテストが含まれており、バグ レポート、機能リクエスト、プル リクエストなど、貢献を歓迎します。
次のステップ
これは v0.1.x リリースであり、積極的にフィードバックを収集しています。試してみた場合は、動作することと動作しないことについて聞きたいと思っています。GitHub リポジトリで issue を開くか、Jamf Nation で連絡してください。