Update 4th Jan 2021: If you don't need Python 3.9, installing azure-cli natively can be done by using this homebrew formula: https://formulae.brew.sh/formula/azure-cli. Note: there's an open issue with upgrading: https://github.com/Azure/azure-cli/issues/16417.
Anyone else having trouble installing Azure CLI natively on Apple Silicon? You may remember some rough edges being mentioned in our previous post. If like me you're a big user of Azure's cloud services and you've got your hands on a new M1 MacBook Pro or MacBook Air, then you might have noticed that installing some software isn't as straight forward as it used to be. In this post I'll take you through the steps I took to install Azure CLI natively on your Apple Silicon Mac.
Note: this post is likely to become old pretty quickly given the pace at which things are being fixed for M1.
As of the last few days, homebrew now supports Apple Silicon Mac natively which means no more manual steps on the M1, just go to the homebrew homepage and install as normal. It should install into /opt/homebrew/
, you can test it by running $ brew
in the terminal.
This step is the simplest in this whole process, savour it:
brew install wget
Install Python 3 with this command:
brew install python3
It will download and build targetting Apple Silicon ARM. We now need to check you can access python3 via the Terminal and that the right version is being loaded (MacOS comes with older versions of both Python2 and Python3):
type -a python3
python3 is /usr/bin/python3
If a path going via your homebrew folder isn't at the top of the list, e.g. python3 is /opt/homebrew/opt/python@3.9/bin/python3.9
, you can simply create an alias for it in your ~/.zshrc
file.
Open ~/.zshrc
with either nano or vim:
nano ~/.zshrc
and add these lines:
alias python3='/opt/homebrew/opt/python@3.9/bin/python3.9'
alias pip3='/opt/homebrew/bin/pip3'
Save (Control + O
) and exit (Control + X
), and run this for the changes to take effect:
source ~/.zshrc
Now check that your homebrew version of python3 is at the top of your type -a
list:
type -a python3
python3 is an alias for /opt/homebrew/opt/python@3.9/bin/python3.9
python3 is /usr/bin/python3
You can run the same test for pip3
. If the homebrew version is at the top of the type -a pip3
list then you're good to go!
Normally it would be enough to run:
pip3 install azure-cli
and this would've been the end of the post had it not been for the wall of compilation errors I received as pip attempted to compile the dependencies for azure-cli. The following packages needed manual intervention:
cffi
cryptography
bcrypt
PyNaCl
After spending some hours troubleshooting these errors I was close to throwing in the towel, calling it a day on native brew/python and moving over to rosetta2. And then a breakthrough...
Building and installing the cryptography
package requires cffi
to be installed, and OpenSSL lib include files to be in your PATH. Both of these need manual attention:
cffi doesn't build via pip
OpenSSL isn't in the path
To build and install cffi follow these steps:
Install libffi
brew install pkg-config libffi
Take note of the path to this libffi.pc file:
find /opt/homebrew/ | grep "Cellar.*libffi.pc"
/opt/homebrew/Cellar/libffi/3.3/lib/pkgconfig/libffi.pc
Grab the sources from https://pypi.org/project/cffi/:
wget https://files.pythonhosted.org/packages/66/6a/98e023b3d11537a5521902ac6b50db470c826c682be6a8c661549cb7717a/cffi-1.14.4.tar.gz
tar -xzvf cffi-1.14.4.tar.gz
cd cffi-1.14.4
Edit setup.py and add the path for libffi.pc that you noted down in step 2 to include_dirs
:
setup.py
import sys, os
import subprocess
import errno
# on Windows we give up and always import setuptools early to fix things for us
if sys.platform == "win32":
import setuptools
sources = ['c/_cffi_backend.c']
libraries = ['ffi']
include_dirs = ['/usr/include/ffi',
'/usr/include/libffi',
'/opt/homebrew//Cellar/libffi/3.3/lib/pkgconfig/']
...
Build
python3 setup.py install
cffi is done! Now to the next dependency ...
azure-cli requires an older version (<3.0.0) of cryptography, which in turn needs the OpenSSL library. First grab OpenSSL via brew:
brew install openssl
Grab the lib path:
find /opt/homebrew | grep "Cellar.*openssl.*/lib$"
/opt/homebrew/Cellar/openssl@1.1/1.1.1i/lib
Now install version 2.9.2 and reference the OpenSSL lib and include folders from above:
pip3 install cryptography==2.9.2 --global-option=build_ext --global-option="-L/opt/homebrew/Cellar/openssl@1.1/1.1.1i/lib" --global-option="-I/opt/homebrew/Cellar/openssl@1.1/1.1.1i/include"
Only two more dependencies to go.
Both bcrypt and PyNaCl have the same steps:
Download sources
Manual install
Go to https://pypi.org/project/bcrypt/ and download sources, unpack, and run setup.py:
wget https://files.pythonhosted.org/packages/d8/ba/21c475ead997ee21502d30f76fd93ad8d5858d19a3fad7cd153de698c4dd/bcrypt-3.2.0.tar.gz
tar -xzvf bcrypt-3.2.0.tar.gz
cd bcrypt-3.2.0
python3 setup.py install
Go to https://pypi.org/project/PyNaCl/, get sources and do the same:
wget https://files.pythonhosted.org/packages/cf/5a/25aeb636baeceab15c8e57e66b8aa930c011ec1c035f284170cacb05025e/PyNaCl-1.4.0.tar.gz
tar -xzvf PyNaCl-1.4.0.tar.gz
cd PyNaCl-1.4.0
python3 setup.py install
Finally, you should have everything you need to install azure-cli via pip. Go ahead and try it:
pip3 install azure-cli
Good luck and thanks for reading!