<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://soundmacguy.org.uk/feed.xml" rel="self" type="application/atom+xml" /><link href="https://soundmacguy.org.uk/" rel="alternate" type="text/html" /><updated>2026-06-06T20:39:13+00:00</updated><id>https://soundmacguy.org.uk/feed.xml</id><title type="html">Sound Mac Guy</title><subtitle>I used to be a sound engineer. Now I manage Apple stuff.
</subtitle><author><name>Neil Martin</name></author><entry><title type="html">terraform-provider-axm v1.7.1 - Device Management Service gets full IaC lifecycle management</title><link href="https://soundmacguy.org.uk/2026/06/06/terraform-provider-axm-v1-7-0-device-management-service-gets-full-lifecycle-management.html" rel="alternate" type="text/html" title="terraform-provider-axm v1.7.1 - Device Management Service gets full IaC lifecycle management" /><published>2026-06-06T00:00:00+00:00</published><updated>2026-06-06T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2026/06/06/terraform-provider-axm-v1-7-0-device-management-service-gets-full-lifecycle-management</id><content type="html" xml:base="https://soundmacguy.org.uk/2026/06/06/terraform-provider-axm-v1-7-0-device-management-service-gets-full-lifecycle-management.html"><![CDATA[<p>Yo Terraform massive! <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">v1.7.1</a> is here and it’s a big one. Device Management Service creation, deletion, and a brand new resource for managing which service each device family enrols into by default. This marks a significant milestone; full Infrastructure as Code (IaC) lifecycle management for Device Management Services.</p>

<h2 id="axm_device_management_service---now-with-a-full-lifecycle"><a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/resources/device_management_service">axm_device_management_service</a> - now with a full lifecycle</h2>

<p>Previously, <code class="language-plaintext highlighter-rouge">axm_device_management_service</code> was limited. You had to supply the server ID yourself (i.e. it already had to exist), it couldn’t create or delete anything, and it just managed device serial number assignments against an existing server. From provider release 1.7.1, it’s a proper resource backed by the <a href="https://developer.apple.com/documentation/applebusinessapi">Apple Business API v2.1 API</a> endpoints.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">data</span> <span class="s2">"jamfpro_device_enrollments_public_key"</span> <span class="s2">"current"</span> <span class="p">{}</span>

<span class="nx">resource</span> <span class="s2">"axm_device_management_service"</span> <span class="s2">"prod"</span> <span class="p">{</span>
  <span class="nx">name</span> <span class="o">=</span> <span class="s2">"Jamf Pro - Production"</span>

  <span class="nx">server_certificate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span> <span class="o">=</span> <span class="s2">"PublicKey.pem"</span>
    <span class="nx">data</span> <span class="o">=</span> <span class="nx">base64encode</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">jamfpro_device_enrollments_public_key</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">public_key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="nx">allow_release</span> <span class="o">=</span> <span class="kc">false</span>

  <span class="nx">device_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"SERIALNUM1"</span><span class="p">,</span>
    <span class="s2">"SERIALNUM2"</span><span class="p">,</span>
  <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">server_certificate</code> takes the base64-encoded public key you’d normally upload in the Apple Business web UI. This example demonstrates sourcing and base64-encoding the public key using the <a href="https://registry.terraform.io/providers/deploymenttheory/jamfpro/latest/docs/data-sources/device_enrollments_public_key">Deployment Theory jamfpro Provider</a>. You could use <code class="language-plaintext highlighter-rouge">filebase64("${path.module}/PublicKey.pem")</code> if you want to read it from a local file in the same module instead.</p>

<p><code class="language-plaintext highlighter-rouge">allow_release</code> controls whether this service can release devices. <code class="language-plaintext highlighter-rouge">device_ids</code> is optional - leave it out if you’d rather not manage assignments through Terraform.</p>

<p>The gory gotchas:</p>

<ul>
  <li><strong>Business scope only for create, update, and delete.</strong> If you’re running against Apple School Manager, the resource will refuse and tell you why. Import still works in either scope.</li>
  <li><strong>Destroy pre-flight.</strong> Before deleting a server, the provider automatically clears any default product family assignments and unassigns all devices. Apple will return a 409 if you try to delete a server with either still attached, so both steps happen unconditionally on destroy.</li>
  <li><strong>Certificates aren’t returned by the API.</strong> Apple doesn’t send the cert data back in GET responses, so what you write to config is what lives in state. Rotate the cert by updating <code class="language-plaintext highlighter-rouge">data</code> in config and applying.</li>
</ul>

<h2 id="axm_default_device_assignment"><a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/resources/default_device_assignment">axm_default_device_assignment</a></h2>

<p>This is a new singleton resource representing the org-wide default device assignment page - what you set in Apple Business Manager under <em>Devices &gt; Management Services &gt; Default Device Assignment</em> to control which Device Management Service newly enrolled devices go to, by device family. The example below sets the <code class="language-plaintext highlighter-rouge">prod</code> Device Management Service as the default for all device families.</p>

<p>Note that <code class="language-plaintext highlighter-rouge">watch</code> is available here (as the API implements it) but it is not shown in the Apple Business web UI for me at the time of writing.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">data</span> <span class="s2">"jamfpro_device_enrollments_public_key"</span> <span class="s2">"current"</span> <span class="p">{}</span>

<span class="nx">resource</span> <span class="s2">"axm_device_management_service"</span> <span class="s2">"prod"</span> <span class="p">{</span>
  <span class="nx">name</span> <span class="o">=</span> <span class="s2">"Jamf Pro - Production"</span>

  <span class="nx">server_certificate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">name</span> <span class="o">=</span> <span class="s2">"PublicKey.pem"</span>
    <span class="nx">data</span> <span class="o">=</span> <span class="nx">base64encode</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">jamfpro_device_enrollments_public_key</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">public_key</span><span class="p">)</span>
  <span class="p">}</span>

  <span class="nx">allow_release</span> <span class="o">=</span> <span class="kc">false</span>

  <span class="nx">device_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"SERIALNUM1"</span><span class="p">,</span>
    <span class="s2">"SERIALNUM2"</span><span class="p">,</span>
  <span class="p">]</span>
<span class="p">}</span>

<span class="nx">resource</span> <span class="s2">"axm_default_device_assignment"</span> <span class="s2">"org"</span> <span class="p">{</span>
  <span class="nx">apple_tv</span>         <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">apple_vision_pro</span> <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">ipad</span>             <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">iphone</span>           <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">mac</span>              <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
  <span class="nx">watch</span>            <span class="o">=</span> <span class="nx">axm_device_management_service</span><span class="p">.</span><span class="nx">prod</span><span class="p">.</span><span class="nx">id</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Each attribute takes a Device Management Service ID. Set it to a server ID to assign that family, set it to <code class="language-plaintext highlighter-rouge">""</code> to ensure it’s unassigned (from the server tracked in state), or omit it entirely to leave it unmanaged by Terraform.</p>

<p>A couple of things to know before you deploy this:</p>

<p><strong>If you already have defaults configured in Apple Business Manager</strong>, set the attributes to match the current state on first apply rather than jumping straight to your desired end state. Terraform needs to know where a family is coming from before it can move it cleanly. Going in with an empty state and trying to move a family that’s already assigned to an untracked server will earn you a 409 from Apple.</p>

<p><strong>Moving a family between servers</strong> requires two API calls in the right order - Apple won’t let you claim a family that’s already assigned elsewhere. The provider handles this automatically: it clears the server losing the family first, then sets the server gaining it. You don’t need to think about it.</p>

<h2 id="upgrading">Upgrading</h2>

<p>If you have existing <code class="language-plaintext highlighter-rouge">axm_device_management_service</code> resources, <code class="language-plaintext highlighter-rouge">id</code> is now Computed-only and <code class="language-plaintext highlighter-rouge">name</code> is Required. Run <code class="language-plaintext highlighter-rouge">terraform import axm_device_management_service.&lt;name&gt; &lt;server-id&gt;</code> to bring existing servers under management, then update your configs accordingly.</p>

<p>Full docs on the <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">Terraform Registry</a> and source on <a href="https://github.com/neilmartin83/terraform-provider-axm">GitHub</a>. As always, feedback, berating, issues and PRs are very welcome.</p>

<p>Still holding out for Device Management Service token creation and VPP token management in the API. The Business API keeps growing though, so I remain increasingly optimistic. One day (hopefully soon)… 🤞</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Yo Terraform massive! v1.7.1 is here and it’s a big one. Device Management Service creation, deletion, and a brand new resource for managing which service each device family enrols into by default. This marks a significant milestone; full Infrastructure as Code (IaC) lifecycle management for Device Management Services.]]></summary></entry><entry><title type="html">terraform-provider-axm v1.6.0 - It’s time for Business</title><link href="https://soundmacguy.org.uk/2026/04/15/terraform-provider-axm-v1-6-0-its-time-for-business.html" rel="alternate" type="text/html" title="terraform-provider-axm v1.6.0 - It’s time for Business" /><published>2026-04-15T00:00:00+00:00</published><updated>2026-04-15T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2026/04/15/terraform-provider-axm-v1-6-0-its-time-for-business</id><content type="html" xml:base="https://soundmacguy.org.uk/2026/04/15/terraform-provider-axm-v1-6-0-its-time-for-business.html"><![CDATA[<p>Hello Terraformers! It’s been a while since the last update on <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">terraform-provider-axm</a>. Version 1.6.0 is a bit chunkier than usual and it brings a few new resources and data sources, thanks to Apple releasing the <a href="https://developer.apple.com/documentation/apple-school-and-business-manager-api/apple-school-manager-and-apple-business-api-changelog">Business API</a>.</p>

<p>Let’s peruse!</p>

<h2 id="blueprints">Blueprints</h2>

<p>You can now create, update and delete Blueprints directly from Terraform. If you’ve been managing these by hand in the Apple Business web UI, those days (and it’s only been 2 since Apple released Business… hehe) are over.</p>

<p>A Blueprint ties together apps, configurations, packages, devices, users and user groups. The <code class="language-plaintext highlighter-rouge">axm_blueprint</code> <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/resources/blueprint">resource</a> lets you declare all of that in one block:</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">resource</span> <span class="s2">"axm_blueprint"</span> <span class="s2">"onboarding"</span> <span class="p">{</span>
  <span class="nx">name</span>        <span class="o">=</span> <span class="s2">"New Hire Onboarding"</span>
  <span class="nx">description</span> <span class="o">=</span> <span class="s2">"Standard setup for new starters"</span>

  <span class="nx">app_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"app-id-1"</span><span class="p">,</span>
    <span class="s2">"app-id-2"</span><span class="p">,</span>
  <span class="p">]</span>

  <span class="nx">configuration_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"config-id-1"</span><span class="p">,</span>
  <span class="p">]</span>

  <span class="nx">device_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"SERIALNUM1"</span><span class="p">,</span>
    <span class="s2">"SERIALNUM2"</span><span class="p">,</span>
  <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>All six relationship types are supported - <code class="language-plaintext highlighter-rouge">app_ids</code>, <code class="language-plaintext highlighter-rouge">configuration_ids</code>, <code class="language-plaintext highlighter-rouge">package_ids</code>, <code class="language-plaintext highlighter-rouge">device_ids</code>, <code class="language-plaintext highlighter-rouge">user_ids</code> and <code class="language-plaintext highlighter-rouge">user_group_ids</code>. Terraform will diff your desired state against what’s in Apple Business and add or remove relationships accordingly. Drift detection works too, so if someone sneaks in a change via the UI, your next <code class="language-plaintext highlighter-rouge">plan</code> will see it.</p>

<p>There are also data sources for looking stuff up:</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">axm_blueprint</code></strong> - fetch a single Blueprint by ID, including all its relationships</li>
  <li><strong><code class="language-plaintext highlighter-rouge">axm_blueprints</code></strong> - list every Blueprint in your organisation</li>
</ul>

<p>And of course, the <code class="language-plaintext highlighter-rouge">list</code> resource is there for those of us who partake in <a href="https://developer.hashicorp.com/terraform/language/query">Query</a>, with filters for <code class="language-plaintext highlighter-rouge">name</code>, <code class="language-plaintext highlighter-rouge">name_contains</code> and <code class="language-plaintext highlighter-rouge">status</code>.</p>

<h2 id="configurations">Configurations</h2>

<p>The <strong><code class="language-plaintext highlighter-rouge">axm_configuration</code></strong> <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/resources/configuration">resource</a> lets you manage Configuration Profiles; specifically the <code class="language-plaintext highlighter-rouge">CUSTOM_SETTING</code> type, which is the one you can create via the API.</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">resource</span> <span class="s2">"axm_configuration"</span> <span class="s2">"wifi"</span> <span class="p">{</span>
  <span class="nx">name</span>                     <span class="o">=</span> <span class="s2">"Corporate Wi-Fi"</span>
  <span class="nx">configured_for_platforms</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PLATFORM_IOS"</span><span class="p">,</span> <span class="s2">"PLATFORM_MACOS"</span><span class="p">]</span>
  <span class="nx">configuration_profile</span>    <span class="o">=</span> <span class="nx">file</span><span class="p">(</span><span class="s2">"wifi.mobileconfig"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>For all other configuration types (the ones Apple manages), there are read-only data sources:</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">axm_configuration</code></strong> - fetch a single configuration by ID (includes the profile payload for <code class="language-plaintext highlighter-rouge">CUSTOM_SETTING</code> types)</li>
  <li><strong><code class="language-plaintext highlighter-rouge">axm_configurations</code></strong> - list all configurations</li>
</ul>

<p>The <code class="language-plaintext highlighter-rouge">list</code> resource supports filtering too - <code class="language-plaintext highlighter-rouge">name</code>, <code class="language-plaintext highlighter-rouge">name_contains</code> and <code class="language-plaintext highlighter-rouge">configuration_type</code>.</p>

<h2 id="new-data-sources">New data sources</h2>

<p>Beyond Blueprints and Configurations, we also have data sources:</p>

<table>
  <thead>
    <tr>
      <th>Data Source</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">axm_app</code> / <code class="language-plaintext highlighter-rouge">axm_apps</code></td>
      <td>Look up apps (VPP/Apps and Books)</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">axm_package</code> / <code class="language-plaintext highlighter-rouge">axm_packages</code></td>
      <td>Look up packages</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">axm_user</code> / <code class="language-plaintext highlighter-rouge">axm_users</code></td>
      <td>Look up managed Apple Account users</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">axm_user_group</code> / <code class="language-plaintext highlighter-rouge">axm_user_groups</code></td>
      <td>Look up user groups</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">axm_audit_events</code></td>
      <td>Query the audit log with date range filters</td>
    </tr>
  </tbody>
</table>

<p>The singular variants fetch by ID; the plural ones grab the lot. Having all this data accessible in Terraform opens up some interesting possibilities - cross-referencing users with devices, auditing changes, building reports, that kind of endeavour.</p>

<h2 id="go-forth-and-grab-it">Go forth and grab it</h2>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">terraform</span> <span class="p">{</span>
  <span class="nx">required_providers</span> <span class="p">{</span>
    <span class="nx">axm</span> <span class="o">=</span> <span class="p">{</span>
      <span class="nx">source</span>  <span class="o">=</span> <span class="s2">"neilmartin83/axm"</span>
      <span class="nx">version</span> <span class="o">=</span> <span class="s2">"~&gt; 1.6.0"</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Full docs are on the <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">Terraform Registry</a> and source is on <a href="https://github.com/neilmartin83/terraform-provider-axm">GitHub</a>. This is really just a little hobby that satisfies my interest in working with APIs. It scratches an itch, but perhaps someone out there will find it interesting or even useful. As always, feedback, berating, issues and PRs are welcome!</p>

<p>I really hope the glorious fruit company keeps expanding this API - I’ve still got my fingers crossed for MDM server token creation and VPP token management. One day… 🤞</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Hello Terraformers! It’s been a while since the last update on terraform-provider-axm. Version 1.6.0 is a bit chunkier than usual and it brings a few new resources and data sources, thanks to Apple releasing the Business API.]]></summary></entry><entry><title type="html">Graham made me do it</title><link href="https://soundmacguy.org.uk/2026/02/08/graham-made-me-do-it.html" rel="alternate" type="text/html" title="Graham made me do it" /><published>2026-02-08T00:00:00+00:00</published><updated>2026-02-08T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2026/02/08/graham-made-me-do-it</id><content type="html" xml:base="https://soundmacguy.org.uk/2026/02/08/graham-made-me-do-it.html"><![CDATA[<p><img src="/assets/2026/02/08/removal.png" alt="" /></p>

<p>Back in 2017 a <a href="/2017/03/26/daz-made-me-do-it.html">nudge from Daz</a> got me started on this whole blogging adventure, and up it went on Wordpress. It’s what I was familiar with at the time and it got me up and running quickly.</p>

<p>Now, almost 10 years later, I’ve decided to join the cool kids, moving the whole lot to GitHub Pages and Jekyll. I even bought a domain!</p>

<p>Thanks <a href="https://grahamrpugh.com">Graham</a> for giving me a push in the right direction; I couldn’t take Wordpress’s ads or glacial performance anymore either.</p>

<p>All the posts are moved over and I’ll be tweaking over the coming weeks as I get more in depth with Jekyll. Thanks for bearing with it as things are a little rough around the edges.</p>

<p>I think I need a comments thingy next…</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Suppress the upgrade dialog for Keynote, Numbers and Pages</title><link href="https://soundmacguy.org.uk/2026/01/29/suppress-the-upgrade-dialog-for-keynote-numbers-and-pages.html" rel="alternate" type="text/html" title="Suppress the upgrade dialog for Keynote, Numbers and Pages" /><published>2026-01-29T00:00:00+00:00</published><updated>2026-01-29T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2026/01/29/suppress-the-upgrade-dialog-for-keynote-numbers-and-pages</id><content type="html" xml:base="https://soundmacguy.org.uk/2026/01/29/suppress-the-upgrade-dialog-for-keynote-numbers-and-pages.html"><![CDATA[<p>Following <a href="https://soundmacguy.wordpress.com/2026/01/28/keynote-numbers-and-pages-15-1-now-unified-across-all-apple-operating-systems/">Apple’s release of new versions of these apps</a>, users will be presented with the following dialog upon opening the previous versions:</p>

<p><img src="/assets/2026/01/29/image-5.png" alt="" /></p>

<p>To see this dialog, the following conditions apply:</p>

<ul>
  <li>
    <p>The previous version has updated to its latest release (14.5)</p>
  </li>
  <li>
    <p>The new 15.1 version has not been installed</p>
  </li>
</ul>

<p>If the user clicks “Not Now” the dialog does not reappear on subsequent relaunches. However, it may reappear in future as the preferences that control it are time/counter based.</p>

<!--more-->

<p>Administrators may wish to suppress this dialog in some scenarios, for example:</p>

<ul>
  <li>
    <p>Shared computers that must retain the previous versions for consistency/experience</p>
  </li>
  <li>
    <p>Environments where users cannot use the App Store to install new versions by themselves</p>
  </li>
  <li>
    <p>Situations where administrators will be managing the migration to the new versions and wish to avoid this user-facing dialog</p>
  </li>
</ul>

<p><strong>The following configuration profile will prevent this dialog from appearing:</strong></p>

<noscript><pre>400: Invalid request</pre></noscript>
<script src="https://gist.github.com/0e8b320cf9f95f89260292dd8a6b66f1.js"> </script>

<p>Please be aware - users will still see prompts regarding collaboration not working in the old versions if they try to use this feature. In these cases, I would argue that they need to be aware and be upgraded as soon as possible.</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Following Apple’s release of new versions of these apps, users will be presented with the following dialog upon opening the previous versions:]]></summary></entry><entry><title type="html">Keynote, Numbers and Pages 15.1 now unified across all Apple operating systems</title><link href="https://soundmacguy.org.uk/2026/01/28/keynote-numbers-and-pages-15-1-now-unified-across-all-apple-operating-systems.html" rel="alternate" type="text/html" title="Keynote, Numbers and Pages 15.1 now unified across all Apple operating systems" /><published>2026-01-28T00:00:00+00:00</published><updated>2026-01-28T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2026/01/28/keynote-numbers-and-pages-15-1-now-unified-across-all-apple-operating-systems</id><content type="html" xml:base="https://soundmacguy.org.uk/2026/01/28/keynote-numbers-and-pages-15-1-now-unified-across-all-apple-operating-systems.html"><![CDATA[<p>Today, Apple have released updated versions of their popular productivity apps as part of their <a href="https://www.apple.com/uk/apple-creator-studio/">Creator Studio</a> subscription offering. These are now unified offerings, with a single app version for all operating systems. This has significant impact for Mac users as well as admins who deploy them from Apple School or Business Manager.</p>

<p>Edit (2025-01-30): Apple have provided some guidance around iOS/iPadOS updates and AppConfig settings for the new versions <a href="https://support.apple.com/en-ca/guide/deployment/dep575bfed86/web#dep0e56c04e5">in this article</a> (under the heading <strong>Update Apple Creator Studio Keynote, Numbers, and Pages apps</strong>).</p>

<p>They have user-facing information <a href="https://support.apple.com/en-us/126151">in this article</a>.</p>

<h2 id="what-happened">What happened?</h2>

<p>The new apps are updates to the previous iOS/iPadOS only versions. I.e. with these bundle identifiers which match the old versions for those platforms:</p>

<ul>
  <li>
    <p>com.apple.Pages</p>
  </li>
  <li>
    <p>com.apple.Numbers</p>
  </li>
  <li>
    <p>com.apple.Keynote</p>
  </li>
</ul>

<p>Now they support macOS as well. The apps are free to install but some Premium content and features now require a paid subscription. At this time, the subscription is available to users signed into a personal Apple Account on the Mac. It is not available for purchase in Apple School/Business Manager or from Managed Apple Accounts directly.</p>

<p>The previous macOS versions look to have been removed from the App Store/Apple School and Business Manager briefly disappeared for some Apple School and Business manager before receiving a final version bump, and their bundle IDs are:</p>

<ul>
  <li>
    <p>com.apple.iWork.Pages</p>
  </li>
  <li>
    <p>com.apple.iWork.Numbers</p>
  </li>
  <li>
    <p>com.apple.iWork.Keynote</p>
  </li>
</ul>

<p>So they’re essentially separate, different apps now…</p>

<p>The new unified Apps also have different paths on disk but the <em>display name is the same in Finder</em>.</p>

<p><img src="/assets/2026/01/28/pages.png" alt="" /></p>

<p><img src="/assets/2026/01/28/keynote.png" alt="" /></p>

<p><img src="/assets/2026/01/28/numbers.png" alt="" /></p>

<table>
  <thead>
    <tr>
      <th><strong>Old path</strong></th>
      <th><strong>New path</strong></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>/Applications/Keynote.app</td>
      <td>/Applications/Keynote Creator Studio.app</td>
    </tr>
    <tr>
      <td>/Applications/Numbers.app</td>
      <td>/Applications/Numbers Creator Studio.app</td>
    </tr>
    <tr>
      <td>/Applications/Pages.app</td>
      <td>/Applications/Pages Creator Studio.app</td>
    </tr>
  </tbody>
</table>

<!--more-->

<h2 id="what-does-this-mean-for-mac-users">What does this mean for Mac users?</h2>

<ul>
  <li>
    <p>They may see <strong>New Version of Keynote/Numbers/Pages Available</strong> warnings if they open a previous version</p>
  </li>
  <li>
    <p>They may see <strong>Update to Collaborate</strong> warnings if they open a shared project in the previous version</p>
  </li>
  <li>
    <p>They might need to manually install the new versions from the App Store themselves (if allowed) because they are technically new apps and not updates</p>
  </li>
  <li>
    <p>After installation, they will see duplicate entries for the same app in their Applications folder if the previous one was present</p>
  </li>
  <li>
    <p>They may try to use Premium content such as a template and see dialogs asking them to subscribe</p>
  </li>
  <li>
    <p>They may not be able to use AI features, especially if they’re disabled by a device management service</p>
  </li>
  <li>
    <p>They may not receive automatic updates from device management services without admins intervening</p>
  </li>
</ul>

<h2 id="what-does-this-mean-for-admins">What does this mean for admins?</h2>

<ul>
  <li>
    <p>You may need to purchase licenses for the “new” version and deploy them to your Macs as a separate, new deployment</p>
  </li>
  <li>
    <p>You might need to take action and delete the old versions from user’s Macs</p>
  </li>
</ul>

<p>Tracking down/deleting the previous iWork apps should be straightforward now we know their true paths and bundle identifiers.</p>

<p>As an example, if you’re working with Jamf Pro, a Mac Apps record for Keynote (15.1) now looks like this after searching for and adding it:</p>

<p><img src="/assets/2026/01/28/image-3.png" alt="" /></p>

<p>Compared to the previous version (13.2):</p>

<p><img src="/assets/2026/01/28/image-4.png" alt="" /></p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Today, Apple have released updated versions of their popular productivity apps as part of their Creator Studio subscription offering. These are now unified offerings, with a single app version for all operating systems. This has significant impact for Mac users as well as admins who deploy them from Apple School or Business Manager.]]></summary></entry><entry><title type="html">JNUC 2025 - Automating Apple Endpoints Management</title><link href="https://soundmacguy.org.uk/2025/11/11/jnuc-2025-automating-apple-endpoints-management.html" rel="alternate" type="text/html" title="JNUC 2025 - Automating Apple Endpoints Management" /><published>2025-11-11T00:00:00+00:00</published><updated>2025-11-11T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2025/11/11/jnuc-2025-automating-apple-endpoints-management</id><content type="html" xml:base="https://soundmacguy.org.uk/2025/11/11/jnuc-2025-automating-apple-endpoints-management.html"><![CDATA[<p>Session videos from this year’s Jamf Nation User Conference are available on <a href="https://www.youtube.com/@JAMFMedia/videos">YouTube</a>. I was there(!) and had the honour and pleasure of presenting alongside <a href="https://fr.linkedin.com/in/tristan-valente-49628990">Tristan Valente</a> of <a href="https://netopie.com/">Netopie</a>.</p>

<p>Our session explored the novel approach of managing your Jamf Pro instance using <a href="https://en.wikipedia.org/wiki/Infrastructure_as_code">Infrastructure as Code</a> methodologies. We introduced the concepts of <a href="https://about.gitlab.com/topics/gitops/">GitOps</a> for version control and change management/review as well as taking a deeper look at <a href="https://developer.hashicorp.com/terraform">Terraform</a> and the <a href="https://github.com/deploymenttheory">Deployment Theory</a> <a href="https://github.com/deploymenttheory/terraform-provider-jamfpro">jamfpro</a> provider, the tools that make the magic happen.</p>

<p>Watch the video here:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/ldq9-iLuu3U?si=w2IPEMj4No8rYCFJ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>The Jamf Blog also published <a href="https://www.jamf.com/blog/automate-apple-endpoints-terraform-gitlab-cicd-jamf-pro">this article</a> about the session.</p>

<h2 id="hands-on-resources">Hands-on Resources</h2>

<p>Explore these repositories to get stuck in and start to practice with managing your own Jamf environment!</p>

<ul>
  <li>
    <p><strong>Jamf Platform Provider Examples</strong> repo (focuses on what Jamf’s new provider can do): <a href="https://github.com/neilmartin83/terraform-jamfplatform-examples">https://github.com/neilmartin83/terraform-jamfplatform-examples</a></p>
  </li>
  <li>
    <p><strong>Terraform Jamf Pro Starter</strong> repo (real-world instance model with example configurations and promoted dev → test → prod workflows): <a href="https://github.com/neilmartin83/terraform-jamfpro-starter/">https://github.com/neilmartin83/terraform-jamfpro-starter/</a></p>
  </li>
</ul>

<p>Join the discussion on the <a href="https://www.macadmins.org/">MacAdmins Slack</a>:</p>

<p><a href="https://macadmins.slack.com/archives/C06R172PUV6">#terraform-provider-jamfpro</a></p>

<p><a href="https://macadmins.slack.com/archives/C09HP9V1K5H">#terraform-provider-jamfplatform</a></p>

<p>Have fun!</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Session videos from this year’s Jamf Nation User Conference are available on YouTube. I was there(!) and had the honour and pleasure of presenting alongside Tristan Valente of Netopie.]]></summary></entry><entry><title type="html">What’s new with terraform-provider-axm (AppleCare, that’s what)</title><link href="https://soundmacguy.org.uk/2025/11/06/whats-new-with-terraform-provider-axm-applecare-thats-what.html" rel="alternate" type="text/html" title="What’s new with terraform-provider-axm (AppleCare, that’s what)" /><published>2025-11-06T00:00:00+00:00</published><updated>2025-11-06T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2025/11/06/whats-new-with-terraform-provider-axm-applecare-thats-what</id><content type="html" xml:base="https://soundmacguy.org.uk/2025/11/06/whats-new-with-terraform-provider-axm-applecare-thats-what.html"><![CDATA[<p>Hello Terraformers! Apple recently, and quietly bumped their <a href="https://developer.apple.com/documentation/apple-school-and-business-manager-api">Apple School and Business Manager API</a> to 1.3+. Along came a <a href="https://developer.apple.com/documentation/applebusinessmanagerapi/get-all-apple-care-coverage-for-an-orgdevice">new endpoint</a> for querying AppleCare coverage details for individual devices.</p>

<p>With that, <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">terraform-provider-axm</a> has a shiny new data source; <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/data-sources/organization_device_applecare_coverage">axm_organization_device_applecare_coverage</a>. It gives you a list of every AppleCare agreement (resource) a device has (they can indeed have more than zero). Perhaps not a typical use case for Terraform, but maybe it’ll come in handy. If you’re working with Go, you can import the client and use the <a href="https://github.com/neilmartin83/terraform-provider-axm/blob/main/examples/client/GetOrgDeviceAppleCareCoverage/GetOrgDeviceAppleCareCoverage.go">GetOrgDeviceAppleCareCoverage</a> function in your own projects.</p>

<!--more-->

<p>Back to Terraform; if you were to declare the data source and an output for it, like this:</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">data</span> <span class="s2">"axm_organization_device_applecare_coverage"</span> <span class="s2">"example"</span> <span class="p">{</span>
  <span class="nx">id</span> <span class="o">=</span> <span class="s2">"FAKE123456"</span>
<span class="p">}</span>
<span class="nx">output</span> <span class="s2">"applecare_coverage"</span> <span class="p">{</span>
  <span class="nx">value</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">axm_organization_device_applecare_coverage</span><span class="p">.</span><span class="nx">example</span>
<span class="p">}</span>
</code></pre></div></div>

<p>You’d see a result like that:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>data.axm_organization_device_applecare_coverage.example: Reading...
data.axm_organization_device_applecare_coverage.example: Read complete after 1s [id=FAKE123456]
Changes to Outputs:
  + applecare_coverage = {
      + applecare_coverage_resources = [
          + {
              + agreement_number          = ""
              + contract_cancel_date_time = ""
              + description               = "Limited Warranty"
              + end_date_time             = "2020-10-20T00:00:00Z"
              + id                        = "FAKE123456"
              + is_canceled               = false
              + is_renewable              = false
              + payment_type              = "NONE"
              + start_date_time           = "2019-10-21T00:00:00Z"
              + status                    = "INACTIVE"
            },
        ]
      + id                           = "FAKE123456"
    }
</code></pre></div></div>

<p>This poor old device only has one AppleCare agreement that’s long-expired… so no hope of a warranty for me! Ho hum.</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Hello Terraformers! Apple recently, and quietly bumped their Apple School and Business Manager API to 1.3+. Along came a new endpoint for querying AppleCare coverage details for individual devices.]]></summary></entry><entry><title type="html">Infrastructure as Code @ Jamf - Highlights and resources from JNUC 2025</title><link href="https://soundmacguy.org.uk/2025/10/11/infrastructure-as-code-jamf-highlights-and-resources-from-jnuc-2025.html" rel="alternate" type="text/html" title="Infrastructure as Code @ Jamf - Highlights and resources from JNUC 2025" /><published>2025-10-11T00:00:00+00:00</published><updated>2025-10-11T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2025/10/11/infrastructure-as-code-jamf-highlights-and-resources-from-jnuc-2025</id><content type="html" xml:base="https://soundmacguy.org.uk/2025/10/11/infrastructure-as-code-jamf-highlights-and-resources-from-jnuc-2025.html"><![CDATA[<p>This year’s JNUC saw a lot of excitement around IaC and its place in managing and orchestrating the Jamf Platform. This was my first time attending and presenting at JNUC and I’m still buzzing from the experience… Here are some of the takeaways!</p>

<!--more-->

<h2 id="the-jamf-platform-terraform-provider">The Jamf Platform Terraform Provider</h2>

<p>With the announcement of the Jamf Platform APIs, Jamf published its very own Terraform provider: <a href="https://github.com/Jamf-Concepts/terraform-provider-jamfplatform">terraform-provider-jamfplatform</a>. I’m proud to have played a part in building it, and even prouder to watch it garner a spot in the opening keynote:</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/ij4kLJsGAe8?si=ZqkBuKSFZsqDDTGn&amp;start=3001" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Jamf also reinforced its commitment to continue contributions to, and endorsement of the fantastic and well-established community <a href="https://github.com/deploymenttheory/terraform-provider-jamfpro">Jamf Pro provider</a> from friends at Deployment Theory/Lloyds Banking Group. Use both providers together to leverage the full suite of API capabilities that are available:</p>

<ul>
  <li>
    <p>Use <strong>terraform-provider-jamfpro</strong> for comprehensive management of objects in a Jamf Pro instance backed by the Classic and Jamf Pro APIs. Policies, profiles, groups, apps, everything including the kitchen sink!</p>
  </li>
  <li>
    <p>Use <strong>terraform-provider-jamfplatform</strong> to manage microservices backed by the Platform API; resources for Blueprints and Compliance Benchmarks and plus data sources for Unified Inventory.</p>
  </li>
  <li>
    <p>More! Use <a href="https://github.com/Jamf-Concepts/terraform-provider-jsctfprovider"><strong>terraform-provider-jsctfprovider</strong></a> to manage resources in Jamf Security Cloud!</p>
  </li>
</ul>

<p>I’ve put together <a href="https://github.com/neilmartin83/terraform-jamfplatform-examples">a GitHub repository</a> with a few practical examples so you can get stuck in right now. It shows how the Platform and Pro providers work together. I hope it provides a little inspiration for your projects.</p>

<h2 id="session-automating-apple-endpoints-management-git-cicd-and-terraform-for-an-efficient-jamf-pro-administration">Session: Automating Apple Endpoints Management. Git, CI/CD and Terraform for an Efficient Jamf Pro Administration</h2>

<p>It was a great privilege to share the stage with <a href="https://www.linkedin.com/in/tristan-valente-49628990">Tristan Valente</a> from Jamf partner <a href="https://www.linkedin.com/in/tristan-valente-49628990">Netopie</a>. Together, we explored Netopie’s journey with GitOps/IaC and Tristan shared their experiences and best-practices. This was followed with a comprehensive introduction into Terraform, highlighting specific configuration examples using the Jamf Pro provider.</p>

<p><img src="/assets/2025/10/11/img_5435.png" alt="" /></p>

<p><img src="/assets/2025/10/11/img_0055.png" alt="" /></p>

<p><img src="/assets/2025/10/11/image-from-ios.png" alt="" /></p>

<p>The session video is <a href="https://reg.jnuc.jamf.com/flow/jamf/jnuc2025/home25/page/sessioncatalogphase2/session/1744962492146001SJxI">available here</a> for attendees to view and I’ll update this post when it’s made public.</p>

<p>Grab the slides and presenter notes below:</p>

<p><a href="https://soundmacguy.wordpress.com/wp-content/uploads/2025/10/final-1221-automating-apple-endpoints-management-git-cicd-and-terraform-for-an-efficient-jamf-pro-administration.pdf">Download</a></p>

<h2 id="session-infrastructure-as-code-with-jamf">Session: Infrastructure as Code with Jamf</h2>

<p><a href="https://reg.jnuc.jamf.com/flow/jamf/jnuc2025/home25/page/sessioncatalogphase2/session/1743101994075001oK2x">This session</a> was delivered by colleagues <a href="https://www.linkedin.com/in/rlegg">Ryan Legg</a> and <a href="https://www.linkedin.com/in/sbrown01">Shane Brown</a> in the Sales Engineering team, alongside <a href="https://www.linkedin.com/in/roblesjavier/">Javier Robles</a> and <a href="https://www.linkedin.com/in/anthony-telljohann">Anthony Telljohann</a> from Jamf partner <a href="https://www.vanguard.com">Vanguard</a>.</p>

<p>It explored Vanguard’s journey and how they leverage IaC to bring together powerful, repeatable automations in a Jamf environment. Attendees learned how these tools saved time, reduced errors, and delivered consistency across their organisation’s management and security operations.</p>

<p>The SE team provides <a href="https://github.com/Jamf-Concepts/terraform-jamf-platform">these Terraform modules</a> for inspiration on starting your own Terraform projects that manage your Jamf infrastructure.</p>

<p><img src="/assets/2025/10/11/img_0048.jpg" alt="" /></p>

<p><img src="/assets/2025/10/11/img_0050.png" alt="" /></p>

<h2 id="session-automating-jamf-security-platform-configuration">Session: Automating Jamf Security Platform Configuration</h2>

<p><a href="https://reg.jnuc.jamf.com/flow/jamf/jnuc2025/home25/page/sessioncatalogphase2/session/1744817837989001fqg3">This session</a>, delivered by colleagues <a href="https://www.linkedin.com/in/cuddeford">Dan Cuddeford</a> and <a href="https://www.linkedin.com/in/rlegg">Ryan Legg</a> examined various approaches organisations could take toward managing an API-based SaaS tool, with a focus on automating the configuration of Jamf Security platforms.</p>

<p>It centered on Terraform as the chosen Infrastructure as Code (IaC) platform for the team’s implementation and explored the process of building a Terraform provider to support those platforms.</p>

<p>The <a href="https://github.com/Jamf-Concepts/terraform-provider-jsctfprovider">Jamf Security Cloud provider</a> is the result!</p>

<h2 id="community-resources">Community Resources</h2>

<p>A vibrant community is growing around IaC with Jamf - get involved!</p>

<ul>
  <li>
    <p>Join <a href="https://macadmins.slack.com/archives/C09HP9V1K5H">#terraform-provider-jamfplatform</a> in the MacAdmins Slack to discuss the new Jamf Platform provider and related workflows</p>
  </li>
  <li>
    <p>Join <a href="https://macadmins.slack.com/archives/C06R172PUV6">#terraform-provider-jamfpro</a> to discuss the well-established community Jamf Pro provider and related workflows</p>
  </li>
</ul>

<p>Thank you to everyone who has played a part in this journey so far - all the open source maintainers, session attendees and colleagues. This looks to become something quite special and I can’t wait to see what happens next. ❤️</p>]]></content><author><name>Neil Martin</name></author><category term="ai" /><category term="cloud" /><category term="devops" /><category term="technology" /><category term="terraform" /><summary type="html"><![CDATA[This year’s JNUC saw a lot of excitement around IaC and its place in managing and orchestrating the Jamf Platform. This was my first time attending and presenting at JNUC and I’m still buzzing from the experience… Here are some of the takeaways!]]></summary></entry><entry><title type="html">Explore the Apple School &amp;amp; Business Manager API with My Postman Collection</title><link href="https://soundmacguy.org.uk/2025/07/20/explore-the-apple-school-business-manager-api-with-my-postman-collection.html" rel="alternate" type="text/html" title="Explore the Apple School &amp;amp; Business Manager API with My Postman Collection" /><published>2025-07-20T00:00:00+00:00</published><updated>2025-07-20T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2025/07/20/explore-the-apple-school-business-manager-api-with-my-postman-collection</id><content type="html" xml:base="https://soundmacguy.org.uk/2025/07/20/explore-the-apple-school-business-manager-api-with-my-postman-collection.html"><![CDATA[<p>If you’re working with the Apple School and Business Manager APIs, you know how powerful, but also how complex, they can be to get started with. To make life easier, I’ve put together a public Postman collection that gives you a head start.</p>

<p><a href="https://www.postman.com/neilmartin-6501015/apple-school-and-business-manager-api/collection/tss0hiz/apple-school-and-business-manager-api?action=share&amp;source=copy-link&amp;creator=44709244">Click here to grab it!</a></p>

<p><img src="/assets/2025/07/20/image-2.png" alt="" /></p>

<p>You’ll need an Access Token to authenticate any live requests you want to make. Learn how to generate one here: <a href="https://developer.apple.com/documentation/apple-school-and-business-manager-api/implementing-oauth-for-the-apple-school-and-business-manager-api">https://developer.apple.com/documentation/apple-school-and-business-manager-api/implementing-oauth-for-the-apple-school-and-business-manager-api</a></p>

<p>Use Bart’s handy ZSH script: <a href="https://bartreardon.github.io/2025/06/11/using-the-new-api-for-apple-business-school-manager.html">https://bartreardon.github.io/2025/06/11/using-the-new-api-for-apple-business-school-manager.html</a></p>

<p>Or go further with Anthony’s workflow: <a href="https://cantscript.com/posts/automating-token-generation-for-apple-school-managers-new-api/">https://cantscript.com/posts/automating-token-generation-for-apple-school-managers-new-api/</a></p>

<p>I’ll continue to expand it as Apple updates the API. If you find it useful or have suggestions, feel free to fork, contribute, or reach out.</p>

<p>Happy building!</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[If you’re working with the Apple School and Business Manager APIs, you know how powerful, but also how complex, they can be to get started with. To make life easier, I’ve put together a public Postman collection that gives you a head start.]]></summary></entry><entry><title type="html">Manage Device Assignments to MDM Services with Terraform</title><link href="https://soundmacguy.org.uk/2025/06/18/manage-device-assignments-to-mdm-servers-with-terraform.html" rel="alternate" type="text/html" title="Manage Device Assignments to MDM Services with Terraform" /><published>2025-06-18T00:00:00+00:00</published><updated>2025-06-18T00:00:00+00:00</updated><id>https://soundmacguy.org.uk/2025/06/18/manage-device-assignments-to-mdm-servers-with-terraform</id><content type="html" xml:base="https://soundmacguy.org.uk/2025/06/18/manage-device-assignments-to-mdm-servers-with-terraform.html"><![CDATA[<p>Just a quick one - the <a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs">latest release of the axm provider</a> can now manage device assignments to MDM Servers (or Services as Apple calls them now)!</p>

<p>Add a resource block for <code class="language-plaintext highlighter-rouge">axm_device_management_service</code> and off you go.</p>

<p><a href="https://registry.terraform.io/providers/neilmartin83/axm/latest/docs/resources/device_management_service">Read the docs for more details and enjoy!</a></p>

<p><strong>Top tip:</strong> to get the MDM Service ID you want, navigate to it via Apple Business/School Manager -&gt; Preferences and it will be visible in the address bar at the end of the URL (e.g. <code class="language-plaintext highlighter-rouge">FAKE0000111122223333444444444444</code>)</p>

<p>It works, with an example like this enforcing a state of 3 devices being assigned to a chosen MDM Service:</p>

<div class="language-hcl highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">resource</span> <span class="s2">"axm_device_management_service"</span> <span class="s2">"example"</span> <span class="p">{</span>
  <span class="nx">id</span> <span class="o">=</span> <span class="s2">"FAKE0000111122223333444444444444"</span>
  <span class="nx">device_ids</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">"FAKE000ABC123"</span><span class="p">,</span>
    <span class="s2">"FAKE111DEF456"</span><span class="p">,</span>
    <span class="s2">"FAKE222GHI789"</span>
  <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p><img src="/assets/2025/06/18/image-1.png" alt="" /></p>

<p>One example could be to use this in conjunction with the awesome <a href="https://registry.terraform.io/providers/deploymenttheory/jamfpro/latest/docs">jamfpro</a> provider. You can enforce device assignments to the MDM Service(s) your Jamf Pro instance is using in the Apple Business/School Manager end itself.</p>

<p>Use the <a href="https://registry.terraform.io/providers/deploymenttheory/jamfpro/latest/docs/data-sources/device_enrollments">jamfpro_device_enrollments</a> data source to get the MDM Server ID (<code class="language-plaintext highlighter-rouge">server_uuid</code>) from Jamf Pro and pass it to <code class="language-plaintext highlighter-rouge">id</code> in this provider’s <code class="language-plaintext highlighter-rouge">axm_device_management_service</code> resource block.</p>

<p>A word of warning - you might hit weird rate limit/token authentication issues if you run this very often (e.g. when testing). Just give it a few minutes and try again. This API is new and we’re still learning a lot about it…</p>

<p>Voila!</p>]]></content><author><name>Neil Martin</name></author><summary type="html"><![CDATA[Just a quick one - the latest release of the axm provider can now manage device assignments to MDM Servers (or Services as Apple calls them now)!]]></summary></entry></feed>