> ## Content Index
> Fetch the complete content index at: https://albertodebortoli.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Easy connection to AWS Mac instances with EC2macConnector
- URL: https://albertodebortoli.com/2023/07/05/easy-connection-to-aws-mac-instances-with-ec2macconnector/
- Published: 2023-07-05T13:54:56.000Z
- Updated: 2023-08-06T13:00:35.000Z
- Author: Alberto De Bortoli

## Overview

Amazon Web Services (AWS) provides [EC2 Mac instances](https://aws.amazon.com/ec2/instance-types/mac/?ref=albertodebortoli.com) commonly used as CI workers. Configuring them can be either a manual or an automated process, depending on the DevOps and Platform Engineering experience in your company. No matter what process you adopt, it is sometimes useful to log into the instances to investigate problems.

[EC2macConnector](https://github.com/albertodebortoli/EC2macConnector?ref=albertodebortoli.com) is a CLI tool written in Swift that simplifies the process of connecting over SSH and VNC for DevOps engineers, removing the need of updating private keys and maintaining the list of IPs that change across deployment cycles.

## Connecting to EC2 Mac instances without EC2macConnector

[AWS documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-mac-instances.html?ref=albertodebortoli.com) describes the steps needed to allow connecting via VNC:

1. Start the Apple Remote Desktop agent and enable remote desktop access on the instance
2. Set the password for the `ec2-user` user on the instance to allow connecting over VNC
3. Start an SSH session
4. Connect over VNC

Assuming steps 1 and 2 and done, steps 3 and 4 are usually manual and repetitive: the private keys and IPs usually change across deployments which could happen frequently, even daily.

Here is how to start an SSH session in the terminal binding a port locally:

```bash
ssh ec2-user@<instance_IP> \
  -L <local_port>:localhost:5900 \
  -i <path_to_privae_key> \
```

To connect over VNC you can type the following in Finder → Go → Connect to Server (⌘ + K) and click Connect:

```bash
vnc://ec2-user@localhost:<local_port>

```

or you could create a `.vncloc` file with the following content and simply open it:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "<http://www.apple.com/DTDs/PropertyList-1.0.dtd>">
<plist version="1.0">
<dict>
	<key>URL</key>
	<string>vnc://ec2-user@localhost:<local_port></string>
</dict>
</plist>

```

If you are a system administrator, you might consider [EC2 Instance Connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html?ref=albertodebortoli.com), but sadly, in my experience, it's not a working option for EC2 Mac instances even though I couldn't find evidence confirming or denying this statement. 

Administrators could also consider using [Apple Remote Desktop](https://apps.apple.com/gb/app/apple-remote-desktop/id409907375?mt=12&ref=albertodebortoli.com) which comes with a price tag of $/£79.99.

## Connecting to EC2 Mac instances with EC2macConnector

EC2macConnector is a simple and free tool that works in 2 steps:

- the `configure` command fetches the private keys and the IP addresses of the running EC2 Mac instances in a given region, and creates files using the said information to connect over SSH and VNC:

```bash
ec2macConnector configure \
  --region <aws_region> \
  --secrets-prefix <mac_metal_private_keys_prefix>
```

Read below or the [README](https://github.com/albertodebortoli/EC2macConnector?ref=albertodebortoli.com) for more information on the secrets prefix value.

- the `connect` command connects to the instances via SSH or VNC.

```bash
ec2macConnector connect --region <aws_region> <fleet_index>

```

```bash
ec2macConnector connect --region <aws_region> <fleet_index> --vnc

```

💡

Connecting over VNC requires an SSH session to be established first.

As with any tool written using [ArgumentParser](https://github.com/apple/swift-argument-parser?ref=albertodebortoli.com), use the `--help` flag to get more information.

## Requirements

There are some requirements to respect for the tool to work:

### Permissions

EC2macConnector requires AWS credentials either set as environment variables (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`) or configured in `~/.aws/credentials` via the [AWS CLI](https://aws.amazon.com/cli/?ref=albertodebortoli.com). Environment variables take precedence.

The user must be granted the following permissions:

- `ec2:DescribeInstances`
- `secretsmanager:ListSecrets`
- `secretsmanager:GetSecretValue`

### EC2 instances

The EC2 Mac instances must have the `EC2macConnector:FleetIndex` tag set to the index of the instance in the fleet. Indexes should start at 1\. Instances that don't have the said tag will be ignored.

### Secrets and key pairs formats

EC2macConnector assumes that the private key for each instance key pair is stored in SecretsManagers. The name of the key pair could and should be different from the secret ID. For example, the instance key pair should include an incremental number also part of the corresponding secret ID.

Consider that the number of Mac instances in an AWS account is limited and it's convenient to refer to them using an index starting at 1\. It's good practice for the secret ID to also include a nonce as secrets with the same name cannot be recreated before the deletion period has elapsed, allowing frequent provisioning-decommissioning cycles.

For the above reasons, EC2macConnector assumes the following formats are used:

- instance key pairs: `<keypair_prefix>_<index_of_instance_in_fleet>` e.g. `mac_instance_key_pair_5`
- secret IDs: `<secrets_prefix>_<index_of_instance_in_fleet>_<nonce>` e.g. `private_key_mac_metal_5_dx9Wna73B`

## EC2macConnector Under the hood

The `configure` command:

- downloads the private keys in the `~/.ssh` folder
- creates scripts to connect over SSH in `~/.ec2macConnector/<region>/scripts`
- creates vncloc files to connect over VNC in `~/.ec2macConnector/<region>/vnclocs`

```bash
➜  .ec2macConnector tree ~/.ssh
/Users/alberto/.ssh
├── mac_metal_1_i-08e4ffd8e9xxxxxxx
├── mac_metal_2_i-07bfff1f52xxxxxxx
├── mac_metal_3_i-020d680610xxxxxxx
├── mac_metal_4_i-08516ac980xxxxxxx
├── mac_metal_5_i-032bedaabexxxxxxx
├── config
├── known_hosts
└── ...
```

The `connect` command:

- runs the scripts (opens new shells in Terminal and connects to the instances over SSH)
- opens the vncloc files

```bash
➜  .ec2macConnector tree ~/.ec2macConnector
/Users/alberto/.ec2macConnector
└── us-east-1
    ├── scripts
    │   ├── connect_1.sh
    │   ├── connect_2.sh
    │   ├── connect_3.sh
    │   ├── connect_4.sh
    │   └── connect_5.sh
    └── vnclocs
        ├── connect_1.vncloc
        ├── connect_2.vncloc
        ├── connect_3.vncloc
        ├── connect_4.vncloc
        └── connect_5.vncloc
```