enroll-ec2-mac is an AppleScript made to automatically enroll Amazon Web Services Elastic Compute Cloud (EC2) Mac instances into a mobile device management (MDM) solution. enroll-ec2-mac is made to ensure the MDM “pairing“ relationship isn't broken for MDM enrollment. Without that pairing, an EC2 Mac instance isn’t able to ”listen“ for new or updated profiles from the MDM server. enroll-ec2-mac performs all of this without any user interaction after AMI configuration (as per the instructions below). Included is a subroutine to automate the issuance and retrieval of Jamf enrollment profiles.
Learn more about Amazon EC2 Mac instances here!
Included are AWS CloudFormation and HashiCorp Terraform templates to get these set up. Either of these will automate creating the AWS Secrets Manager secret, Identity and Access Management policy, role, and instance profile needed for enroll-ec2-mac to retrieve credentials. Alternatively, if using AWS Systems Manager Parameter Store instead, templates are also included, and a setting must be changed to match (see the section Settings below). Manual instructions to set up the secret are also included at the bottom of this page.
- Gather the appropriate credentials and store them in AWS Secrets Manager. If you're using one of the templates, you'll be prompted for each of these. The default secret ID in the script is
jamfSecret
, and requires 5 values for the following keys (with sample values below):jamfServerDomain
("jamfurl.jamfcloud.com")
jamfEnrollmentUser
("enrollmentUserExampleName")
jamfEnrollmentPassword
("enrollment3x4mplep455w0rd")
- This holds a Jamf API
client_id
andclient_secret
created in the Jamf console, and its role only requires Create permission for Computer Enrollment Invitations. - Jamf API Client Credentials are required. The
jamfEnrollmentUser
field holds the Client ID andjamfEnrollmentPassword
holds the Client Secret. -
- As of March 31st, 2024, Jamf Pro has deactivated Basic authentication, deprecating the use of Jamf Pro Standard Accounts for communicating with the API. API calls must now be performed with API roles and clients.
- Additional permissions for Jamf API are required for other features, such as preloading information and removing device records.
- This holds a Jamf API
localAdmin
("ec2-user")
- The default is
ec2-user
unless a change is made outside of these instructions. Must be an administrator account.
- The default is
localAdminPassword
("l0c4l3x4mplep455w0rd")
- Password for
localAdmin
administrator account. - These credentials may be reset/cleared programmatically after enrollment completes.
- Password for
- Create AWS Identity and Access Management (IAM) assets to enable access to the above secret. The IAM policy, role, and instance profile (noted here as ㊙️🪪) are all automatically created with either template. See near the end for a sample manual policy.
- Attach this ㊙️🪪 IAM Instance Profile to the instance you're starting.
- Start an EC2 Mac instance on a Mac dedicated host from an Amazon-vended macOS AMI.
- Attach the above ㊙️🪪 IAM Instance Profile to the instance.
- Connect via SSH, enable Screen Sharing/VNC, and set the admin password to match the one saved in the Secret.
- In a single line:
sudo /usr/bin/dscl . -passwd /Users/ec2-user 'l0c4l3x4mplep455w0rd' ; sudo launchctl enable system/com.apple.screensharing ; sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.screensharing.plist
- In a single line:
- Connect to the Mac GUI (via VNC or Screen Sharing) and log in with the above password.
- Enable Automatically log in as for the current user in System Settings -> Users & Groups.
- Place
enroll-ec2-mac.scpt
in/Users/Shared
.- IMPORTANT: Set the secret ID (either by name or with the complete ARN) by manually setting
MMSecret
in the script, or writing the ID to a plist with the below command.defaults write /Library/Preferences/com.amazon.dsx.ec2.enrollment.automation MMSecret "jamfSecret-YOUR-SECRET-ID"
, replacing what's in quotes with the ID or ARN of your secret.- This secret is the one your ㊙️🪪 IAM Instance Profile can access.
- Unable to use Secrets Manager? Options for using Parameter Store (with CloudFormation and Terraform templates) or statically setting the variables are commented in the script runtime.
- IMPORTANT: Set the secret ID (either by name or with the complete ARN) by manually setting
- In Terminal, type the following command:
osascript /Users/Shared/enroll-ec2-mac.scpt --setup
- Note: if you would like to use DEPNotify (see below for why), add the
--with-screen
flag to activate. - e.g.osascript /Users/Shared/enroll-ec2-mac.scpt --setup --with-screen
- In the event the Jamf server credentials are incorrect, an error will appear halting this process. Correct these credentials to continue.
- Follow the prompts to enable System Events, Accessibility, and App Management (if using DEPNotify) permissions as needed. These will be enabled for the
osascript
process and may be reverted programmatically, included in the cleanup routines ifprodFlag
is set to1
.- After a short delay, enroll-ec2-mac will try to access all the permissions that it will need to during actual enrollment, but not performing all of the enrollment actions.
- During this process, it is normal for the screen to flash a few times.
- Optional: if
useDEPNotify
is set totrue
, or the--with-screen
flag is used, prompts for App Management will appear and the screen will flash. DEPNotify is used to keep users from interfering in the enrollment process, but is optional if automatic login is set, since enrollment can transparently occur before a user logs in.
- In the event of an error, click Re-run and respond to the prompts again.
- If a final prompt or error does not appear after some time (over 2 minutes), run the following command to reload the LaunchAgent and re-run the task:
launchctl unload -w /Library/LaunchAgents/com.amazon.dsx.ec2.enrollment.automation.startup.plist ; launchctl load -w /Library/LaunchAgents/com.amazon.dsx.ec2.enrollment.automation.startup.plist
- After a short delay, enroll-ec2-mac will try to access all the permissions that it will need to during actual enrollment, but not performing all of the enrollment actions.
- Once you receive the below message, click OK and close Screen Sharing/VNC. - Make sure to click OK before creating your image. If not, enroll-ec2-mac will re-attempt setup (and not enrollment) on subsequent runs until it's clicked.
- Optional: disable screen sharing via the command line.
sudo launchctl disable system/com.apple.screensharing ; sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.screensharing.plist
- After clicking OK, Create an image from the running instance.
- Follow the linked instructions to Create a Linux AMI from an instance (instructions also cover macOS instances).
- Workflow was tested with “No reboot” enabled.
- Note: if the instance is rebooted or logged out after clicking OK, enrollment will occur.
- “Delete on termination” is recommended to be unchecked to keep the AMI after terminating the template instance.
- When AMI moves from Pending to Available, launch a new instance with the AMI.
- This process may take an hour or more depending on storage class and data volume.
- When new instance is launched using this AMI, it will enroll automatically, and without any further intervention.
- IMPORTANT: Ensure that any new instance launched from this AMI has an appropriate ㊙️🪪 IAM instance profile that can retrieve the credentials.
- Cleanup (
prodFlag
) is available to revoke permissions and remove files. - Code in
enroll-ec2-mac
can auto-enable Screen Sharing when enrollment is complete.
- Important: if testing a manual enrollment without this script, a preference key must be set for Jamf before enrollment, otherwise MDM profiles will not properly deploy to the cloud instance. This key is set automatically as part of the enroll-ec2-mac script. The command below will set the preference key manually.
sudo defaults write /Library/Preferences/com.jamfsoftware.jamf is_virtual_machine 0
- The first spot to check during a script failure is the ㊙️🪪 IAM Instance Profile: if the script hangs or crashes (any error regarding
“{{ }},{{ }}")
, it may not have access to the secrets it needs, or isn’t parsing them correctly.- To test, in Terminal, manually check the secret (changing
jamfSecret
to the name or ARN of your secret):aws secretsmanager get-secret-value --secret-id jamfSecret --query SecretString
- To test, in Terminal, manually check the secret (changing
- If using an HTTP/HTTPS proxy and only basic profiles appear (i.e. no Self Service or pushed apps, additional profiles assigned are not in System Settings), the proxy needs to be set for the
appstore
process itself. Use the code below to make the change, replacing "proxy.server.address.here:8080" with your proxy server and port (inside the quotes):PROXY_ADDRESS="proxy.server.address.here:8080" cat <<EOF | sudo tee /var/db/appstore/.curlrc proxy = $PROXY_ADDRESS EOF sudo chown -R _appstore:_appstore /var/db/appstore/.curlrc ```
- If pushing a System Extension profile with "Allow users to approve system extensions" set to false (unchecked), note that EC2 Mac instances use a System Extension for its network driver, which is critical to the cloud instance communicating with any external infrastructure. In the event that a profile of this type is pushed, the instance will become out-of-contact and fail a Status Check on the AWS EC2 console, and will be entirely disconnected from network. Allowlisting the EC2 Mac ENA extension will ensure consistent network connectivity.
- A profile allowing the team identifier,
R8K7E88CP3
or explicitly the extensioncom.amazon.DriverKit.AmazonENAEthernet
would need to be pushed to enrolling EC2 Mac instances before other System Extension profile.
- A profile allowing the team identifier,
enroll-ec2-mac has some options to customize to suit your deployment. To set any of these preferences, type defaults write com.amazon.dsx.ec2.enrollment.automation
, the key, and the value. For example, to set your secret ID (the only required setting), the full command would be:
defaults write com.amazon.dsx.ec2.enrollment.automation MMSecret "jamfSecretID-GoesHere"
(replacing "jamfSecretID-GoesHere"
with your secret ID or ARN)
MMSecret
is the ID of the secret for enroll-ec2-mac to read from. (defaultjamfSecret
)invitationID
is a value for the Jamf invitation ID (numeric string). By default this is read/generated via Jamf API, but can be manually set.-
- Note: If an invitation ID is set, the Jamf API will not be called.
retrievalType
changes how the secret is read. By default, this is set toSecretsManager
(AWS Secrets Manager), but may be set toParameterStore
(AWS Systems Manager Parameter Store). (defaultSecretsManager
)useDEPNotify
activates (if set totrue
) a DEPNotify UI that enroll-ec2-mac uses to shield the display from a user during enrollment. This is set totrue
when the--with-screen
flag is used, and explicitlyfalse
with the--no-screen
flag. (defaultfalse
, Note: changed fromtrue
in earlier versions)autoLogin
enables/disables automatic login of the stored user. Note: it is recommended to use a User Data script during setup to automate this setting, as some versions of macOS require additional commands. (defaulttrue
)invPreload
enables inventory preload via Jamf API. Default setting in code is to set Vendor to AWS when enabled. (defaultfalse
)prodFlag
enables cleanup routines to reset the TCC databases, delete the script, and remove associated files. Some optional commands are included and commented out, including to remove the active instance profile. Set to1
to enable. (default0
, Note: changed fromtestFlag
in earlier versions, which was only available to set inline.)
enroll-ec2-mac uses a single secret that contains 5 key/value pair entries: the Jamf URL (jamfServerDomain
), API credentials (jamfEnrollmentUser
& jamfEnrollmentPassword
), and local admin credentials (localAdmin
& localAdminPassword
). The first three are required to generate the profile, and the final two to apply them to the Mac. Example values are in Credential Setup at the top of the page. The EC2 instance needs an appropriate ㊙️🪪 IAM instance profile applied to itself to read these secrets, as well.
The Jamf API permissions for enroll-ec2-mac only requires the client have Create permission for Computer Enrollment Invitations, and none else. See below for an example of an ㊙️🪪 IAM instance profile including the appropriate access.
Please ensure that you have replaced the ARN next to "Resource" with the full ARN of your secret. If editing manually:
- replace
⚠️⇢region-name
with the appropriate AWS region (e.g.us-east-1
). - replace
1111222233333
with the appropriate AWS account ID. - replace
jamfSecret
with your applicable Secret ID.
{
"Version": "2012-10-17"
"Statement": [
{
"Action": [
"secretsmanager:ListSecrets",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:GetSecretValue",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetRandomPassword",
"secretsmanager:DescribeSecret"
],
"Effect": "Allow",
"Resource": "arn:aws:secretsmanager:⚠️⇢region-name:111122223333:secret:jamfSecret",
"Sid": ""
}
]
}
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
"There's no step 13!"