Dans notre article précédent, Gérer la configuration Jamf avec Terraform : Une introduction, nous avons parcouru les principes fondamentaux de l'Infrastructure as Code et comment démarrer avec Terraform et Jamf Pro. Si vous ne l'avez pas encore lu, nous vous recommandons de commencer par là, car il couvre les principes fondamentaux de Terraform, l'installation, la structure des projets et la gestion de l'état.
Cette fois, nous nous concentrons sur Jamf Protect. Nous avons développé un fournisseur Terraform dédié qui vous permet de gérer votre configuration de produit Jamf Protect en tant que code - plans, configurations d'actions, ensembles d'exceptions, et bien plus encore.
Pourquoi un fournisseur dédié pour Jamf Protect ?
Tout comme Jamf Pro, Jamf Protect est un produit à part entière et fait partie de la famille de la plateforme Jamf. Il dispose de sa propre surface API (basée sur GraphQL) et de son propre ensemble de ressources distinctes de Jamf Pro et des autres microservices de la plateforme Jamf (par exemple, Blueprints et Compliance Benchmarks). Des éléments comme les plans de sécurité des points de terminaison, les configurations de télémétrie et les politiques de stockage amovible résident tous dans Jamf Protect et nécessitent leur propre fournisseur pour être gérés correctement.
Si vous gérez votre configuration Jamf Protect par le biais de la console, vous saurez que recréer une configuration sur plusieurs locataires ou annuler une modification signifie beaucoup de travail manuel. Avec ce fournisseur, l'intégralité de votre configuration Jamf Protect peut résider dans Git, passer par une révision de code et être appliquée de manière cohérente dans tous les environnements.
Qu'est-ce qu'il couvre ?
Le fournisseur est livré avec 16 ressources et 18 sources de données. Voici certains des domaines clés qu'il couvre :
Détection et prévention des menaces
- Listes de prévention personnalisées - listes d'autorisation/blocage par ID d'équipe, hachage de fichier, CDHash ou ID de signature.
- Ensembles d'exceptions - exceptions pour les analyses et les contrôles de sécurité des points de terminaison.
Configuration des points de terminaison
- Plans - configurations complètes de sécurité des points de terminaison, y compris les modes de prévention des menaces, les protocoles de communication, les intervalles de rapports et la collecte d'informations sur les appareils.
- Configurations d'actions - enrichissement des données d'alerte et points de terminaison de rapports (HTTP, Kafka, cloud).
- Télémétrie - collecte d'événements et de journaux : événements de sécurité, authentification, surveillance d'intégrité des fichiers, métriques de performances, et plus.
Contrôle des appareils
- Ensembles de contrôle de stockage amovible - politiques d'appareils USB avec remplacements par ID de fournisseur, ID de produit ou numéro de série.
Paramètres opérationnels
- Transfert de données - diriger les données vers Amazon S3, Microsoft Sentinel ou les points de terminaison du cloud.
- Rétention des données - politiques de rétention à l'échelle du locataire.
- Gestion des modifications - gels de configuration.
- Filtres de journalisation unifiée - collecte de journaux unifiés macOS utilisant des filtres NSPredicate.
Contrôle d'accès
- Utilisateurs, groupes, rôles et clients API - gérer l'accès et les autorisations en tant que code.
Toutes les ressources prennent en charge les opérations CRUD complètes et terraform import.
Il est à noter que jamfprotect_change_management, jamfprotect_data_forwarding et jamfprotect_data_retention sont des ressources singleton - elles gèrent les paramètres à l'échelle du locataire plutôt que les objets individuellement identifiables.
Démarrage
Si vous avez suivi l'article d'introduction, vous devriez déjà avoir Terraform installé et une compréhension de base de la structure des projets. Les étapes ici sont similaires.
1. Créer un client API dans Jamf Protect
Rendez-vous sur Administration > API Clients dans votre console Jamf Protect et créez un nouveau client API avec les autorisations dont vous avez besoin pour les ressources que vous souhaitez gérer.
2. Configurer le fournisseur
Ajoutez le fournisseur à votre configuration 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
}
Vous pouvez également utiliser des variables d'environnement si vous préférez garder le bloc de fournisseur propre :
export JAMFPROTECT_URL="https://your-tenant.protect.jamfcloud.com"
export JAMFPROTECT_CLIENT_ID="your-client-id"
export JAMFPROTECT_CLIENT_SECRET="your-client-secret"
Comme pour le fournisseur Jamf Pro, assurez-vous que ces identifiants ne se retrouvent pas dans votre référentiel Git. Utilisez un fichier terraform.tfvars et ajoutez-le à votre .gitignore.
3. Définir vos ressources
Voici un exemple d'une configuration d'action qui définit quelles données sont collectées et où les alertes sont envoyées :
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"]
}
}
Une politique de stockage amovible qui bloque tout stockage USB sauf les lecteurs chiffrés approuvés :
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"
},
]
}
Un ensemble d'exceptions pour exclure les outils d'administration informatique connus de la prévention des menaces :
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"
},
]
},
]
}
Vous pouvez également utiliser des sources de données pour référencer les ressources existantes plutôt que de les créer. Ici, nous recherchons l'ensemble d'exceptions par défaut géré par Jamf qui existe déjà dans le locataire :
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]
}
Ces ressources peuvent ensuite être liées ensemble dans un plan, qui est la configuration qui est déployée sur les points de terminaison :
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
}
Le plan référence d'autres ressources par leurs ID, donc Terraform comprend le graphique de dépendances et crée tout dans le bon ordre.
4. Appliquer votre configuration
Les mêmes commandes que vous avez apprises dans l'introduction s'appliquent ici :
terraform init # Initialize and download the provider
terraform plan # Review what will be created, changed, or destroyed
terraform apply # Apply the changes (you'll be asked to confirm)
Placer un locataire existant sous gestion
Si vous avez déjà un locataire Jamf Protect avec une configuration existante, vous n'avez pas besoin de recommencer à zéro. Chaque ressource du fournisseur prend en charge terraform import, vous pouvez donc placer les ressources existantes sous gestion Terraform sans les recréer.
Découvrir les ressources existantes avec Terraform query
Si vous exécutez Terraform 1.14+, le fournisseur prend en charge les ressources de liste - une nouvelle fonctionnalité qui vous permet d'interroger votre infrastructure existante directement à partir de Terraform. Ceci est utile pour découvrir ce qui existe déjà dans votre locataire avant de l'importer.
Créez un fichier de requête (par exemple, discover.tfquery.hcl) :
list "jamfprotect_plan" "all" {
provider = jamfprotect
include_resource = true
}
list "jamfprotect_exception_set" "custom" {
provider = jamfprotect
config {
name_prefix = "Custom"
}
}
Puis exécutez :
terraform query -generate-config-out=generated.tf
Terraform interrogera votre locataire Jamf Protect, retournera les ressources correspondantes avec leurs ID et générera les blocs de ressources et les blocs d'importation dans generated.tf. Chaque ressource de liste du fournisseur prend en charge un filtre name_prefix dans le bloc config (ou email_prefix pour les utilisateurs) pour que vous puissiez réduire les résultats à ce que vous recherchez.
Tous les types de ressources prennent en charge les requêtes de liste, à l'exception des ressources singleton suivantes :
jamfprotect_change_managementjamfprotect_data_forwardingjamfprotect_data_retention
Importer des ressources
Une fois que vous avez les ID dont vous avez besoin, vous pouvez utiliser les blocs d'importation pour les placer sous gestion. Avec Terraform 1.5+ :
import {
to = jamfprotect_plan.endpoint_security
id = "your-plan-uuid"
}
Exécutez terraform plan pour générer la configuration de la ressource importée, affinez-la au besoin, et à partir de ce moment, elle est gérée en tant que code. Pour plus d'informations sur l'importation en masse de ressources, consultez la documentation d'importation en masse de HashiCorp.
Utilisation avec d'autres fournisseurs Jamf
Ce fournisseur est conçu pour fonctionner aux côtés des autres fournisseurs Terraform de l'écosystème Jamf. Vous pouvez l'utiliser avec :
- Jamf Platform Provider - pour gérer les ressources de la plateforme Jamf (par exemple, Blueprints et Compliance Benchmarks) via les API Jamf Platform.
- Deployment Theory Jamf Pro Provider - pour gérer les ressources du produit Jamf Pro via ses API classiques et Pro.
Entre ces fournisseurs, vous pouvez gérer votre environnement Jamf complet en tant que code à partir d'un seul projet Terraform.
Contexte
Ce fournisseur a été créé à l'origine par James Smith (@smithjw), qui a généreusement donné le code source à Jamf Concepts. Merci à James pour le travail fondamental qui a rendu cela possible.
Le fournisseur est open source sous la licence MPL 2.0 et construit sur Terraform Plugin Framework de HashiCorp (Protocol v6). Il comprend des tests unitaires et d'acceptation dans tous les domaines, et nous accueillons les contributions - rapports de bogues, demandes de fonctionnalités et demandes d'extraction.
Prochaines étapes
Il s'agit d'une version v0.1.x et nous collectons activement des commentaires. Si vous l'essayez, nous aimerions savoir ce qui fonctionne et ce qui ne fonctionne pas. Ouvrez un problème sur le référentiel GitHub ou contactez-nous sur Jamf Nation.