I just bought two—
I just bought two new Macs, and I have a problem. I'm tempted to treat these things like pets.
Maybe name them something cute, instead of "Macintosh HD", or do something crazy like
migrate my data from my old MacBook Pro or a Time Machine backup.
But NO! These computers are cattle, not pets! Some people think they should fall in love
with their computers. Some people have precious backups. Some people have their computer die
on them and it takes a week before they're productive again.
But NOT YOU! YOU don't treat your computer like a pet. You
use it to do things. It's a tool. Make it replaceable! Upgrades don't phase you anymore!
You don't have to wait like a schmuck while Time Machine sits around restoring your data!
You grab life by the horns, you don't have time to wait for boring restore processes!
You AUTOMATE! Well, anyways, that's the story I tell myself
as I spend hours completely automating my Mac setup process.
I use Ansible, for Pete's sake—If there's something worth doing once, it's worth automating
and doing a thousand times—even if I only NEED to do it once.
And that's why I maintain this: the Mac Dev Playbook. It automates my Mac setup, keeps my Mac's
configuration synchronized, and makes sure that even if my Mac and my entire backup
system went belly-up today, I'd be able to get back into a productive state pretty quickly.
(Assuming there's an Apple Store nearby.)
And how is that possible? Well, this Ansible-based playbook will take a brand new Mac, install
all the software and command line tools I need, configure many of them automatically,
and all I really need to do is log into iCloud, Dropbox, and any other cloud services I use.
I just finished updating my Ansible Mac automation to work on M1 Macs, so I thought I'd show
how I set up my Air and mini in this quick video.
And you might also be asking, "if you can automatically set up your Mac with Ansible, does the Mac even
have to be in front of you? No! In fact, I recently made sure the whole playbook works great
with any Mac anywhere, even if it's in a rack in a datacenter somewhere, like
at MacStadium, or the Macs you can rent in Amazon Web Services!
Before I get to it though, I should take a short pause and emphasize that I DO still
have backups. In fact, I follow the 3-2-1 backup plan, because losing my data would be devastating.
No, really, I couldn't bear to lose my grade
school report "All About Computers".
The 3-2-1 backup plan means I have three copies of ALL my data, on at least two different
types of storage media, with at least one copy offsite.
My primary data copy is always on my main Mac, with a local Time Machine backup to my NAS.
That NAS is completely backed up to Amazon Glacier every night.
In fact, it goes a little deeper, because in addition to my two local copies and one
cloud backup, I also put all my critical data and projects inside Dropbox, which means it's
backed up in four places!
Anyways, that means even if I had a huge disaster like Red Shirt Jeff burning down my house
or aliens taking over St. Louis, I can rest easy knowing that my data's intact.
Well, I probably wouldn't rest easy since I'd just have the charred remains of a bed,
but you get what I mean.
Back to the Mac Dev Playbook though. Setup is really fast, you basically install Ansible,
set your options, and run the playbook. After fixing a few bugs in the playbook while I
set up my MacBook Air, I unplugged my old MacBook Pro, slid the mini into my rack, and
set it up from scratch.
First, I ran through the manual steps creating a user account and signing into iCloud.
Then, once I was in macOS, I opened the App Store and signed in, since I'll need to be
signed in for my Mac Apps to install automatically.
I made sure I could use the Python 3 version shipped with macOS, then I installed Ansible
with pip, and made sure to install the Xcode developer tools when asked.
I downloaded the Mac Dev Playbook from GitHub, copied over my customized config file from
my iPhone with AirDrop, and installed the open source Ansible content with this `ansible-galaxy`
command.
Finally, it's time to unleash the automation! I ran the playbook using the `-K` command
line option, which asks for my account password so the playbook can manage apps on my computer.
It installs all the apps I bought from the App Store, then it installs other apps with
Homebrew casks like Chrome, Docker, Discord, and Slack, and it installs everything I ever
use on the command line too!
The first time I ran the playbook I actually ran into a few errors installing apps, like
this one, because I was still getting used to the M1 architecture. But it was short work
fixing everything, and thanks especially to GitHub user shuuji3 for a PR that fixed homebrew
installation on M1!
I also noticed that most apps take a few seconds, or maybe a minute or two to install, but for
some reason Xcode took like an hour, and it was maxing out the CPU the whole time! I'm
not sure what it was doing, but I noticed the Xcode app was a whopping 30 gigabytes after that!
Anyways, the playbook also configures a bunch of things, like most of the system settings
I prefer—like having a dark grey desktop background, the size of my Dock, and making
my key repeat rate as fast as possible.
It even configures which the order of the Apps in my Dock, since I like having the Dock
identical between my two Macs!
And you know what's best about all this—I built this thing to be idempotent. That means
I can run the playbook again, and it won't make any changes or break anything. It just
makes sure my Mac is set up exactly how I like it.
In fact, I run the playbook at least once a week on both my Macs so they can stay
perfectly in sync!
Sadly, not everything in this world is perfectly automatable. Applications like Photoshop and Illustrator
can't be installed automatically, at least not in any way I've found.
Plus, you still have to sign into everything and enter license keys for any paid apps that
aren't installed through the App Store.
So after all the fun watching my Mac automatically build itself from scratch, I had to sit there
like a caveman and click buttons to get my precious paid apps installed.
And some apps, like Terminal and Sublime Text, are easy to configure automatically, or by
saving a plist file. But many apps don't expose their configuration to macOS's defaults system,
so I have to scroll around and click on things like they did in the stone ages.
How old fashioned!
But the nice thing about all this is I unboxed my Mac mini, plugged it in, and within an
hour it was up and running with an identical configuration ALL all my apps and data—and
I didn't even have to use Time Machine or sit around for hours watching the migration
assistant grab all the data from my old MacBook Pro!
And there are two other benefits: First, if you have more than one Mac, it's
easy to keep the configuration in sync.
No, not that Nsync... wrong graphic!
And second, doing a one-hundred-percent clean reinstall of your system every year or two,
instead of constantly upgrading and migrating everything, keeps your Mac running lean and
mean. Ten year old forgotten kernel extensions or a background app you installed for a 'smart
mousepad' won't cause you trouble next macOS update.
You can get the free and open source Mac Dev Playbook on GitHub, and there's a link
to it below.
And do you use Linux? Well, you could build pretty much the same thing! It's easy to automate
with Ansible! It could even do Windows, but you'll have to spend a lot more time with
Powershell scripts if you want to go that route...
If you want to learn more about Ansible, I'd strongly encourage you to check out my free
Ansible 101 series, or buy my book, Ansible for DevOps.
Until next time, I'm Jeff Geerling.