AWS EC2 Mac Instances With Terraform

Setting up latest Mac instances on AWS


This is another story to test out the latest release of EC2 instances to see how it can be deployed in a managed way. For this purpose I used AWS CLI and Terraform.


Dedicated host

First, we need to create a Dedicated Host with following setup:

  • Instance family: mac1
aws ec2 allocate-hosts \
--instance-type mac1.metal \
--availability-zone eu-west-1b --auto-placement on \
--quantity 1 --region eu-west-1

AMI for Mac instance

Just like any other EC2 instance, we need an AMI to spin up a Mac instance. To source one using Terraform, you can use the following:

data "aws_ami" "mac" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = [
filter {
name = "owner-alias"
values = [


Final step requires some networking setup. In my case, I simply spinned up an instance in public subnet of my VPC.

module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.64.0"
name = "mac-instance-vpc" azs = var.availability_zones cidr = var.vpc_cidr
public_subnets = var.public_subnets_cidrs
enable_dns_hostnames = true
enable_dns_support = true
resource "aws_security_group" "ssh" {
name_prefix = "mac-ssh-sg-"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [""]
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [""]
lifecycle {
create_before_destroy = true
resource "aws_instance" "mac_instance_b" {
ami = data.aws_ami.mac.image_id
instance_type = "mac1.metal"
key_name = var.ssh_key_name
availability_zone = "eu-west-1b"
host_id = "h-002de77f93125e3c2"
subnet_id = module.vpc.public_subnets[1]
vpc_security_group_ids = []


In order to SSH into Mac instance, you simply run the following:

ssh -i private_key.pem ec2-user@

Additional bits

Creating Mac instances is not a painful process but a very long one. It takes ages to create one. Rebooting of Mac instance also takes countless minutes and you will see failing health checks on your instances. In such case, simply wait for the instance to settle.

Known Issues and Solutions

docker installation


ssh -L 5900:localhost:5900 -i private_key.pem ec2-user@<Instance-Public-IP>
brew install --cask docker 
sudo su — 
passwd ec2-user <You’ll be prompted to enter your password twice> exit
sudo /System/Library/CoreServices/RemoteManagement/ -activate -configure -access -on -clientopts -setvnclegacy -vnclegacy yes -clientopts -setvncpw -restart -agent -privs -all 
open ‘vnc://localhost:5900’
Please Note: The above SSH session should be running while you are in the remote session
open /Applications/ # works!


I love the fact that this feature has finally landed. But like with every AWS’s first release, I don’t believe this is a production ready product. Takes ages to do anything. User Metadata is impossible to debug as system logs are simply not reported (I waited for 3 hours). I think we still need to wait a few months for this implementation to optimised.

Lead Software/Infrastructure/Devops Engineer and AWS Community Builder

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store