# MNX.io Documentation

The MNX.io Compute Service allows you to securely deploy and operate containers with bare metal speed powered by [Triton](https://www.joyent.com/triton). Triton also supports high performance hardware virtual machines that can be used to run a broad range of operating systems and applications including Linux, FreeBSD, and Windows.

Triton is an open-source cloud management platform that delivers next generation, container-based, service-oriented infrastructure across one or more data centers.   With an emphasis on ease of installation and operation, Triton is proven at scale: Triton powers our [MNX.io](https://mnx.io) Triton Cloud and private data centers ([Triton Enterprise](https://www.tritondatacenter.com)) worldwide.

Visit [https://github.com/TritonDataCenter/triton ](<https://github.com/TritonDataCenter/triton >)for information on the open source version of Triton cloud.

### Performance and scale <a href="#performance-and-scale" id="performance-and-scale"></a>

MNX.io, powered by Triton, delivers bare metal performance with the elasticity of virtual machines. By eliminating layers of virtualization and running containers directly on bare metal, applications enjoy the highest possible performance. And, because you are running on OS virtualized containers, you can easily scale your applications and infrastructure up and down.

### Security <a href="#security" id="security"></a>

The MNX.io platform provides secure isolation for each container, leveraging Zones, a technology that acts as an additional, "steel-wall" to prevent neighboring tenants from attacking other occupants. Patented resource protections insulate containers from noisy neighbors and insure that each container gets its fair share of I/O.

### Software defined networking <a href="#software-defined-networking" id="software-defined-networking"></a>

The built-in networking offers each container one or more network interfaces, so each container has a full IP stack and is a full peer on the network, making network management easy.

### CloudAPI

The CloudAPI is our public API for the MNX.io cloud: it allows end users of the cloud to manage their accounts, instances, networks, images, and to inquire about other relevant details. CloudAPI provides a single view of docker containers, infrastructure containers and hardware virtual machines.


# Getting started

Welcome to MNX.io! In a few easy steps, you can sign up for a account and begin your journey toward the future of container computing.

1. [Request an MNX.io account](https://portal.mnx.io/register/). You can also set a password to secure your account.
2. [Add payment information](https://portal.mnx.io/billing/). Your billing information authorizes the account creation process.
3. [Add an SSH key to your account](https://portal.mnx.io/account/ssh_key/). You can upload an existing key or create one in the Triton Service portal.

### [Generating SSH keys](/getting-started#generating-ssh-keys) <a href="#generating-ssh-keys" id="generating-ssh-keys"></a>

If you don’t have an SSH key pair, visit [Generating an SSH key](/getting-started/generating-an-ssh-key) for more information about creating SSH keys.

### [Watch to learn](/getting-started#watch-to-learn) <a href="#watch-to-learn" id="watch-to-learn"></a>

[Watch the video](/getting-started#watch-to-learn-how-to-create-a-triton-account) to see how easy it is to signup for Triton Compute Service in the portal.

### [What are my next steps?](/getting-started#what-are-my-next-steps) <a href="#what-are-my-next-steps" id="what-are-my-next-steps"></a>

Once you complete the account setup, your [Triton Compute Service account](https://my.joyent.com/main/#!/account) is ready to use. What do you want to do next?

* [Set up the Triton CLI and CloudAPI](/api/triton-cli-tool).
* [Create an instance in the Triton Service Portal](broken://pages/-LuID4_z4H27TQV9GCdQ).
* [Create a container from the Triton Docker command line toolbox](broken://pages/-LuID4a1sKuPAsgSAf5s).


# SSH to an instance from Windows

## SSH to an instance from Windows

You can use the [PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/) program as an SSH client to connect to your machine.

{% hint style="info" %}
This page gives you basic information about using PuTTY and PuTTYgen to log in to your provisioned machine. For more information on PuTTY, see the official PuTTY documentation.
{% endhint %}

If you are using Windows and you want to connect to your machine using a more Unix-like approach, you may want to consider [Cygwin](http://www.cygwin.com/) instead.

This topic shows you how to log in to your machine as the root user using the Windows program PuTTY.

When you provision a machine, the Machine Details page will display two different IP addresses: a public IP address and a private IP address. Take note of these IP addresses as **you will use the public IP to connect to your machine**.

To log in to your machine, follow these instructions:

* Open the PuTTY program.
* Type the public IP address of your provisioned machine in the **Host Name (or IP address)** field.
* In the **Category** panel on the left, expand the SSH section to expose the Auth settings.

![](/files/-LuiYLu34U_9eNyBmrNP)

* Click **Auth** to display the Options controlling SSH authentication panel.
* Click **Browse** and select the private key file you created. This is the private key you saved when you \[manually generating your SSH key in Windows]\(Manually Generating Your SSH Key in Windows.html).

![](/files/-LuiYbk3rwINvrtPm-La)

* Click **Open** to open a PuTTY terminal session.

{% hint style="info" %}
The first time you connect to your machine, you may see a **PuTTY Security Alert** warning you that the host's key is not cached in the the registry. This is normal because PuTTY has never seen this machine before. Go ahead and click **Yes**.
{% endhint %}

#### Follow These Steps to Login

* At the `login as:` prompt, type "root" and press ENTER.

{% hint style="info" %}
**Note**: For Ubuntu based instances, the default username is "ubuntu".
{% endhint %}

```
login as: root
Authenticating with public key "rsa-key-20120104"
Passphrase for key "rsa-key-20120104":
```

* Type the passphrase you chose for this key and press ENTER.

You are now logged into your machine.

Once you are connected to a machine, you can start setting up your application.


# Account password requirements

## Account password requirements

Your Triton Compute Service account must meet the following requirements:

* It must be at least 7 characters.
* The password mush have at least one letter (a-z, A-Z) and one number (0-9).
* **You cannot reuse the last four passwords** associated with your account.

Additional information:

* After six failed log-in attempts, your account will be locked for 30 minutes.
* You can regain access to your account by using the password reset form or by contacting support.
* Your session expires after 15 minutes of inactivity.


# Improving security using two-factor authentication (2FA)

## Improving security using two-factor authentication (2FA)=

MNX has added additional security features to the [portal](https://portal.mnx.io) to assist customers who must comply with stringent security requirements, such as those mandated by PCI-DSS.

### What is two-factor authentication? <a href="#what-is-two-factor-authentication" id="what-is-two-factor-authentication"></a>

Typically when we log into computer systems, whether it an email account or the MNX portal, we supply a username which identifies us and a password which authenticates us. This is "single-factor authentication" using a password, a series of characters that (hopefully) only we know.

Two-factor authentication (i.e. "2FA") seeks to improve security by adding a second type ("factor") of authentication. The first factor is still a traditional password. The most common second factor is a one-time password (OTP) generated by a physical device or by software on a smartphone.

The advantage of using a second factor of authentication is that if your password being compromised, that alone isn't sufficient information to gain access to your account.

### How do I enable two-factor authentication? <a href="#how-do-i-enable-two-factor-authentication" id="how-do-i-enable-two-factor-authentication"></a>

Login to the [MNX Portal](https://portal.mnx.io). Select your username from the top right corner and choose [**Two Factor**](https://portal.mnx.io/account/two_factor/). A popup will appear indicating if you have or have no turned on Two Factor Authentication. If it is disabled, **Enable** it.

From this page, follow the guided steps to complete the setup of two factor authentication.

At MNX, we recommends using either [Google Authenticator application](https://support.google.com/accounts/answer/1066447?hl=en), [Duo Mobile application](http://guide.duosecurity.com/iphone), or [Authy](https://authy.com).&#x20;

Once your preferred authenticator app is installed on your device, add a new account and scan the QR code into the app. Following this, the application should be registered..

### How do I disable two-factor authentication? <a href="#how-do-i-disable-two-factor-authentication" id="how-do-i-disable-two-factor-authentication"></a>

If you decide to revert to single-factor authentication, just go back to the menu under your account name and select **Two Factor**. From this page, there is an option to disable two factor authentication.

### How can I use two-factor authentication to protect my instances? <a href="#how-can-i-use-two-factor-authentication-to-protect-my-instances" id="how-can-i-use-two-factor-authentication-to-protect-my-instances"></a>

The MNX portal two-factor authentication only protects your MNX portal account, not your instances themselves.

If you wish to use two-factor authentication to protect your instances, we recommend looking at [Duo Security](https://duo.com).


# Generating an SSH key

## Generating an SSH key

The MNX.io services use SSH key pairs for authentication. If you have an existing SSH key pair, you must upload the public key in the MNX.io portal to associate it with your account.&#x20;

If you don’t have an SSH key pair, you can create SSH keys and then associate them with your MNX.io account.&#x20;

For Windows or Mac environments visit:

* [Manually generating an SSH key in macOS](/getting-started/generating-an-ssh-key/generating-an-ssh-key-in-macos).
* [Manually generating an SSH key in Windows](/getting-started/generating-an-ssh-key/untitled-1).

### What are my next steps? <a href="#what-are-my-next-steps" id="what-are-my-next-steps"></a>

Once you have created an account, added billing information to complete your profile, and uploaded your public SSH key, your MNX.io account is ready to use. What do you want to do next?

* [Set up the Triton CLI and CloudAPI](/api/triton-cli-tool).
* [Create an instance in the Triton Service Portal](broken://pages/-LuID4_z4H27TQV9GCdQ).


# Manually generating your SSH key in macOS

## Manually generating your SSH key in macOS

You generate an SSH key through macOS by using the Terminal application. Once you upload a valid public SSH key, the MNX portal uses SmartLogin to copy the public key to any new SmartOS based machine you provision.

### About Terminal <a href="#about-terminal" id="about-terminal"></a>

Terminal is the terminal emulator which provides a text-based command line interface to the Unix shell of macOS.

To open the macOS Terminal, follow these steps:

1. In Finder, choose **Utilities** from the **Applications** folder.
2. Find **Terminal** in the Utilities listw.
3. Open Terminal.

The Terminal window opens with the commandline prompt displaying the name of your machine and your username.

### Generating an SSH key <a href="#generating-an-ssh-key" id="generating-an-ssh-key"></a>

An SSH key consists of a pair of files. One is the private key, which should never be shared with anyone. The other is the public key. The other file is a public key which allows you to log into the containers and VMs you provision. When you generate the keys, you will use `ssh-keygen` to store the keys in a safe location so you can bypass the login prompt when connecting to your instances.

To generate SSH keys in macOS, follow these steps:

1. Enter the following command in the Terminal window.

   ```
   ssh-keygen -t rsa
   ```

   This starts the key generation process. When you execute this command, the `ssh-keygen` utility prompts you to indicate where to store the key.
2. Press the ENTER key to accept the default location. The `ssh-keygen` utility prompts you for a passphrase.
3. Type in a passphrase. You can also hit the ENTER key to accept the default (no passphrase). However, this is not recommended.

&#x20;You will need to enter the passphrase a second time to continue.

After you confirm the passphrase, the system generates the key pair.

```
Your identification has been saved in /Users/myname/.ssh/id_rsa.
Your public key has been saved in /Users/myname/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:AXTDpdct0/6DldSSoeR+4j/qb23laGWE3+te43+a3yg yourname@local
The key's randomart image is:
+---[RSA 2048]----+
|        o.....   |
|       . o.. .oo.|
|        . . ..=+o|
|         o . .**.|
|        S   o= .+|
|          .o..* .|
|           ooO +.|
|            *+=oo|
|           +E*O*+|
+----[SHA256]-----+
```

Your private key is saved to the `id_rsa` file in the `.ssh` directory and is used to verify the public key you use belongs to the same MNX account.

{% hint style="info" %}
Never share your private key with anyone!
{% endhint %}

Your public key is saved to the `id_rsa.pub`;file and is the key you upload to your MNX.io account. You can save this key to the clipboard by running this:

```
pbcopy < ~/.ssh/id_rsa.pub
```

### Importing your SSH key <a href="#importing-your-ssh-key" id="importing-your-ssh-key"></a>

Now you must import the copied SSH key to the portal.

1. After you copy the SSH key to the clipboard, return to [your account page](https://portal.mnx.io/account/ssh/).
2. Click **Create SSH Key** and paste your SSH key into the Public Key field.
3. In the **Name** field, provide a name or description of the key.
4. **Submit** to add the key. It will now appear in your table of keys under SSH Keys.

### Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

You may see a password prompt like this:

```
$ ssh root@198.x.x.x
root@198.x.x.x    's password:
```

This is because:

* You did not enter the correct passphrase.
* You are using the wrong username (Ubuntu uses `ubuntu` as the default username)
* The private key on your Macintosh (`id_rsa`) does not match the public key stored with your MNX account.
* The public key was not entered correctly in your MNX account.


# Manually generating your SSH key in Windows

## Manually generating your SSH key in Windows

On Windows, you can create SSH keys in many ways. This document explains how to use two SSH applications, PuTTY and Git Bash.

### PuTTY <a href="#putty" id="putty"></a>

[PuTTY](http://www.chiark.greenend.org.uk/~sgtatham/putty/) is an SSH client for Windows. You can use PuTTY to generate SSH keys. PuTTY is a free open-source terminal emulator that functions much like the Terminal application in macOS in a Windows environment. This section shows you how to manually generate and upload an SSH key when working with PuTTY in the Windows environment.

### About PuTTY <a href="#about-putty" id="about-putty"></a>

PuTTY is an SSH client for Windows that you will use to generate your SSH keys. You can download PuTTY from [www.chiark.greenend.org.uk](http://www.chiark.greenend.org.uk/~sgtatham/putty/).

When you install the PuTTY client, you also install the PuTTYgen utility. PuTTYgen is what you will use to generate your SSH key for a Windows VM.

{% hint style="info" %}
This page gives you basic information about using PuTTY and PuTTYgen to log in to your provisioned machine. For more information on PuTTY, see the PuTTY documentation
{% endhint %}

### Generating an SSH key <a href="#generating-an-ssh-key" id="generating-an-ssh-key"></a>

To generate an SSH key with PuTTYgen, follow these steps:

1. Open the PuTTYgen program.
2. For **Type of key to generate**, select **SSH-2 RSA**.
3. Click the **Generate** button.
4. Move your mouse in the area below the progress bar. When the progress bar is full, PuTTYgen generates your key pair.
5. Type a passphrase in the **Key passphrase** field. Type the same passphrase in the **Confirm passphrase** field. You can use a key without a passphrase, but this is not recommended.
6. Click the **Save private key** button to save the private key.  You **must** save the private key. You will need it to connect to your machine.
7. Right-click in the text field labeled **Public key for pasting into OpenSSH authorized\_keys file** and choose **Select All**.
8. Right-click again in the same text field and choose **Copy**.

### Importing your SSH key <a href="#importing-your-ssh-key" id="importing-your-ssh-key"></a>

Now you must import the copied SSH key to the portal.

1. After you copy the SSH key to the clipboard, return to [your account page](https://portal.mnx.io/account/ssh/).
2. Click **Create SSH Key** and paste your SSH key into the Public Key field.
3. In the **Name** field, provide a name or description of the key.
4. **Submit** to add the key. It will now appear in your table of keys under SSH Keys.


# API integrations and CLI usage

## API integrations and CLI usage

The primary method of managing infrastructure in Triton data center is with the Triton command line tool.

* [`triton` CLI](/api/triton-cli-tool)

Container Monitor is a Prometheus-compatible interface to performance metrics for all your instances on Triton.

* [Container Monitor with Prometheus](/api/container-monitor-with-prometheus)

The Triton Go SDK is an idiomatic library exposing a client SDK for Go applications using Triton Compute and Triton Object Storage. The Triton Go SDK is used in several open source projects.

* [`triton-go`](https://github.com/joyent/triton-go/)

Additionally, there are a number of well-known API integrations with Triton Compute Service, including:

* [Docker](broken://pages/-LuID4a1sKuPAsgSAf5s)
* [Hashicorp's Packer](/api/hashicorp/create-and-manage-images-with-packer)
* [Hashicorp's Terraform](/api/hashicorp/manage-infrastructure-with-terraform)


# Provisioning limits

In order to maintain the quality and performance of our cloud infrastructure, MNX has a default total memory quota of 3 instances and 2GB of RAM. If you provision an instance or multiple instances with a combined RAM exceeding 2GB, the quota will be hit and you will not be able to provision additional instances. To request an increase to the total memory quota or set the limit as needed to control costs, contact support at [helpdesk@mnxsolutions.com](mailto:mhelpdesk@mnxsolutions.com).

Requests to provision instances that would exceed the memory limits will be refused.


# Cancelling your account

## Cancelling your account

To cancel your MNX.io account, contact <helpdesk@mnxsolutions.com>.

When sending in a request that requires MNX to modify your account, you will need to send this email from an authorized email address.

{% hint style="info" %}
If we can not verify that you are authorized to make requests for that account, we will have to email you back (causing a delay) to assist you.
{% endhint %}

### [Stop billing your account](/getting-started/cancelling-your-account#stop-billing-your-account) <a href="#stop-billing-your-account" id="stop-billing-your-account"></a>

While you wait to hear from support, you can stop your account from being billed further by removing all existing instances.

To remove an instance with `triton` CLI, execute `triton instance delete <UUID>`. That command can remove any instance, including Docker containers. Repeat within each `triton` profile and every data center to remove all instances.

To remove an instance in the portal, [login to your account](https://portal.mnx.io). Navigate to the [Instances list](https://portal.mnx.io/compute/).Click on the instance you wish to remove.  From the instance itself, click the "Actions" menu and the dropdown "Destroy Server".  &#x20;

{% hint style="info" %}
You will be billed for all provisioned instances, including those which are stopped.  **Only destroying a server will stop billing.**
{% endhint %}


# Data centers

## Data centers

MNX operates from data centers worldwide. All data centers feature:

* Class-1 DC operators
* SSAE 16 certified
* Multi-layered physical security
* Highly-redundant power
* Early warning fire suppression
* All tier-1 ISP connectivity
* 10gb/40gb fully-meshed network
* Full peering, fiber connectivity

Select your data centers by region:

* [us-central-1](/data-centers#us-east-1)

### [us-central-1](/data-centers#us-east-1) <a href="#us-east-1" id="us-east-1"></a>

Mt. Prospect Illinois, United States

#### [API access](/data-centers#api-access) <a href="#api-access" id="api-access"></a>

* [CloudAPI endpoint](/api/triton-cli-tool): `https://us-central-1.api.mnx.io`
* [Docker API endpoint](broken://pages/-LuID4a1sKuPAsgSAf5s): `tcp://us-central-1.docker.mnx.io:2376`

#### [Triton CNS](/data-centers#triton-cns) <a href="#triton-cns" id="triton-cns"></a>

* Public interfaces: `https://<service name>.svc.<account uuid>.us-central-1.triton.zone`
* Private interfaces: `https://<service name>.svc.<account uuid>.us-central-1.cns.mnx.io`

#### [Supported features](/data-centers#supported-features) <a href="#supported-features" id="supported-features"></a>

| Feature                                                                      | Support     |
| ---------------------------------------------------------------------------- | ----------- |
| [Bare metal Docker containers](broken://pages/-LuID4_toQjz50xpAsA2)          | coming soon |
| [Bare metal infrastructure containers](/instances/infrastructure-containers) | ✓           |
| [Hardware virtual machines](/instances/virtual-machines)                     | ✓           |
| [VXLAN overlay networking](/network/triton-networking-and-fabric-user-guide) | ✓           |
| Triton CNS for DNS management                                                | coming soon |


# Instances

## Containers and virtual machines

MNX.io provides three classes of compute instances: hardware virtual machines, infrastructure containers, and Docker containers.

### [Virtual Machines](/instances/virtual-machines) <a href="#triton-virtual-machines" id="triton-virtual-machines"></a>

Virtual machines (VMs) are hardware virtual machines (HVMs) wrapped in highly secure zones, supporting a variety of images including Linux, FreeBSD, Windows, and Docker Engine.

Each HVM is implemented using a hypervisor: either KVM or bhyve. KVM was the first HVM supported and remains a strong choice for most VMs, particularly if you are already using KVM in Triton and are satisfied with the performance and features. Bhyve is a newer HVM which aims to improve performance and scalability, while growing the feature set. Because bhyve is relatively new, not all images are supported on bhyve.&#x20;

### [Infrastructure containers](/instances/infrastructure-containers) <a href="#infrastructure-containers" id="infrastructure-containers"></a>

Leverage container-native Linux (lx zones) on infrastructure containers to extend the benefits of containerization to legacy applications and stateful services, such as databases. Containerizing an application in infrastructure containers is easy because they offer all the services of a typical unix host and behave similarly to hardware virtual machines.

Infrastructure containers enjoy their own virtual NICs, filesystems, and all the resource and security isolation that you'd expect of a Virtual Machine, but with the elastic performance and bursting that's only possible with containers.

### [Docker containers](broken://pages/-LuID4_toQjz50xpAsA2) <a href="#docker-containers" id="docker-containers"></a>

Other Docker run-time environments require complex VM host cluster management and provide only limited networking and security capabilities, Using MNX.io transforms an entire data center into an easy to manage, elastic Docker host, while delivering enterprise grade networking and security to each Docker container.

### Comparing containers vs. virtual machines <a href="#comparing-containers-vs-virtual-machines" id="comparing-containers-vs-virtual-machines"></a>

It can be difficult to decide which type of infrastructure to use for an application. Below are some example scenarios in which you may decide on using a containerized instance versus a virtual machine.

| Purpose                                                                | Container | VM |
| ---------------------------------------------------------------------- | --------- | -- |
| Secure and high performance                                            | ✓         | ✓  |
| Brand new microservice-based application                               | ✓         | ✓  |
| Existing application to be converted into microservices                | ✓         | ✓  |
| Quickly resize instances without rebooting                             | ✓         | ✗  |
| Specific environment needs such as FreeBSD, Windows, and Docker Engine | ✗         | ✓  |
| Legacy applications                                                    | ✗         | ✓  |


# Infrastructure containers

## Infrastructure containers

Infrastructure containers offer all the services you'd expect of a unix host, but running on bare metal.

### [Security](/instances/infrastructure-containers#security) <a href="#security" id="security"></a>

All bare metal containers on Triton enjoy security and performance isolation that exceeds that offered by hardware virtual machines.

### [Elasticity](/instances/infrastructure-containers#elasticity) <a href="#elasticity" id="elasticity"></a>

Containers allow unparalleled elasticity, scaling from instances as small as 256 megabytes of RAM to over 200GB with 48 VCPUs.


# Virtual machines

## Virtual machines

MNX virtual machines (VMs) are hardware virtual machines (HVMs) wrapped in highly secure zones, supporting a variety of images including Linux, FreeBSD, Windows, and Docker Engine. They offer a solution for a wide variety of applications that have certain operating system dependencies or applications that can't be run in a containerized environment. Triton offers support for these applications via hardware virtualization but there are some differences between infrastructure containers and virtual machines to be aware of.

Infrastructure containers run on top of a bare metal hypervisor. They do not run a separate guest OS, resulting in better performance, scalability, and stability than a hosted hypervisor. All VMs get the same high performance networking stack, regardless of the instance type or size.

### [Machine resizing](/instances/virtual-machines#machine-resizing) <a href="#machine-resizing" id="machine-resizing"></a>

Live resizing of HVM instances is not supported today. Infrastructure containers can be resized to add memory, CPU, and disk space without rebooting, but the nature of hardware virtualization does not allow that convenience today.


# Snapshots

Snapshots, often employed as a short-term solution are commonly used for patching, updates, or for quick tests with an option to rollback in case of a failure.

Snapshots, often employed as a short-term solution in testing and development environments, are commonly used for patching, updates, or for quick tests with an option to rollback in case of a failure. Their utility extends to certain scenarios in production environments too, especially when undertaking high-risk operations like OS updates or potential system-altering configuration changes.

**Our snapshot implementation serves to provide rollback milestones.** When an instance is booted to a specific snapshot, it permanently destroys all data written after the snapshot was taken. In a typical scenario, accessing snapshot data requires rebooting to that snapshot, effectively discarding any data accumulated post the snapshot's creation.

It is also paramount to understand that **snapshots are not a replacement for a comprehensive backup strategy**. Snapshots reside alongside your live data on the same system and unlike a full backup strategy, they do not generally provide a separate, recoverable data copy.

## Creating a Snapshot

### Create a snapshot using the portal

This guide outlines the steps to create a snapshot in the MNX.io portal. Please note that we recommend testing the rollback functionality on your system to ensure your application recovers properly before the need arises to use it.

* **Access Instance Management** Once logged in, find and click on the "Compute" or "Instances" section in the left-hand navigation menu to access your instances.
* **Select the Instance** From the list of instances, select the instance for which you want to create a snapshot.

<figure><img src="/files/KNOUT3UBaZmHi05VU9Pc" alt="" width="375"><figcaption><p>Compute > Instances > Instance Details</p></figcaption></figure>

* **Create a Snapshot** After selecting the instance, look for the "Snapshots" tab and click on it. Within this tab, find and click on the "Create Snapshot" button.

<figure><img src="/files/ShWDokRS7hwuKVL5SsmJ" alt="" width="375"><figcaption><p>Create Snapshot</p></figcaption></figure>

* **Name Your Snapshot** A dialog box will appear asking you to name your snapshot. Choose a meaningful name that will help you identify the snapshot later. It's a good practice to include the date and the state of the instance in the snapshot name. By default the name will be a datetime stamp.&#x20;

<figure><img src="/files/xagmeAm2laLP1lyFV4ZG" alt="" width="375"><figcaption><p>Name your snapshot</p></figcaption></figure>

* **Initiate Snapshot Creation** After naming your snapshot, click on the "Create" button. The snapshot creation process will start and it may take some time depending on the size of your instance.

<figure><img src="/files/IaRGuPDP66sB33U6IzHn" alt="" width="375"><figcaption><p>Snapshot default name </p></figcaption></figure>

* **Monitor Snapshot Creation** You can monitor the progress of the snapshot creation from the "Snapshots" tab. Once the snapshot has been created, it will appear in the list of available snapshots.

### **Creating a Snapshot using the Triton-CLI Command Line Utility**

This guide will take you through the steps of creating a snapshot in the portal using the Triton-CLI command line utility. This process is a handy alternative if you prefer using the command line over the graphical user interface.

To get started, please refer to the [Triton CLI tools installation documentation](/api/triton-cli-tool#installation).

1. **List Your Instances** To list all of your instances, you can use the following command:

   ```
   triton instance list
   ```
2. **Create a Snapshot** To create a snapshot of a specific instance, you'll need to use the 'instance snapshot create' command followed by the instance ID. Like so:

   ```
   triton instance snapshot create <instance_id>
   ```

   Replace `<instance_id>` with the ID of the instance you want to create a snapshot for.
3. **Name Your Snapshot** To name your snapshot, append the command above with the desired name:

   ```
   triton instance snapshot create -n <snapshot_name> <instance_id>
   ```

   Replace `<snapshot_name>` with your desired snapshot name. Remember, it's a good practice to include the date and state of the instance in the snapshot name.
4. **Monitor Snapshot Creation** To check the status of your snapshot creation, use the 'instance snapshot get' command:

   ```
   triton instance snapshot get <instance_id> <snapshot_name>
   ```

   This will display the status of the specified snapshot.


# Automating Snapshots

This guide provides the steps to automate snapshots in a Triton Datacenter using Unix-like system's cron jobs, streamlining the task and ensuring regular creation of your instance snapshots.

**Automating Snapshots in Triton Datacenter**

Automating the creation of snapshots in the Triton Datacenter is a practical way to ensure regular backups of your instances without the need for manual intervention. This guide will take you through a simple process of setting up a cron job on a Unix-like system to automate the snapshot creation.

1. **Log In to Your Server** Log into your server where you have[ Triton-CLI installed and configured](/api/triton-cli-tool#installation) with SSH or any method you usually use.
2. **Open Crontab** Once you're logged in, open your crontab file by typing the following command:

   ```
   crontab -e
   ```
3. **Schedule a Cron Job** Now, you'll need to schedule a cron job that will run the snapshot creation command at regular intervals. Below is an example of a cron job that creates a snapshot every day at 1:00 AM. Remember to replace `<instance_id>` and `<snapshot_name_prefix>` with your own details.

   ```
   0 1 * * * /usr/local/bin/triton instance snapshot create <instance_id> <snapshot_name_prefix>_$(date +\%Y\%m\%d\%H\%M\%S)
   ```

   This command appends a timestamp to the snapshot name to avoid naming conflicts and to help you identify when the snapshot was created.
4. **Save and Exit** Once you've added the cron job, save and exit the crontab. The exact command to do so will depend on the text editor you're using.
5. **Verify the Cron Job** To verify your cron job has been set up correctly, you can display the list of your cron jobs by typing:

   ```
   crontab -l
   ```

   You should see the snapshot creation cron job in the list.

This process will now automate the creation of snapshots for the specified instance at the time you've set. However, keep in mind that this is not a complete backup solution and should be used in combination with other data protection strategies.

#### Further automation

Automating the creation of snapshots in the Triton Datacenter can be conveniently done using a script that is scheduled to run at regular intervals. This method further streamlines the process, requires minimal manual intervention, and ensures regular and consistent snapshots. Below, we provide a sample script which you can adapt to your needs.

This script automatically creates a new snapshot and manages the retention of these snapshots, deleting the older ones that exceed the specified limit. The snapshots are logged for reference and any issues that might occur during the process.

{% hint style="info" %}
This is an example script, please review and test thourougly before using.
{% endhint %}

{% code overflow="wrap" %}

```bash
#!/bin/bash
instance_uuid=$(mdata-get sdc:uuid)
export TRITON_URL="https://us-central-1.api.mnx.io"
export TRITON_ACCOUNT=<portal login>

# How many snapshots to keep. 
# This will remove snapshots more than this many
keep_count=2

# log file location
log_file="/var/log/snapshot.log"

export TRITON_PROFILE="env"
unset TRITON_USER
export TRITON_KEY_ID="$(ssh-keygen -l -f $HOME/.ssh/id_rsa.pub | awk '{print $2}')"
unset TRITON_TESTING
unset TRITON_PROFILE
keep=$(expr $keep_count + 1)

exec >> "${log_file}"
exec 2>&1

echo "==== STARTED $(date +'%Y%m%d_%H%M') ===="
triton instance snapshot create -w --name="$(date +'%s')" "${instance_uuid}"

# Get snapshots more than keep_count
for snap_name in $(triton instance snapshot list "${instance_uuid}" | sed -n '1!p' |\
  sort -nr -k1 | awk '{ print $1 }' | tail -n +${keep}); do
  triton instance snapshot delete -f -w "${instance_uuid}" "${snap_name}"
done
echo "==== FINISHED $(date +'%Y%m%d_%H%M') ===="
echo ""

```

{% endcode %}


# Tags and metadata

## Tags and metadata

Tags and metadata can both be used to help describe an instance or configure its properties.

### [Comparison chart](/instances/tags-and-metadata#comparison-chart) <a href="#comparison-chart" id="comparison-chart"></a>

Tags and metadata differ in how they're used within Triton, how they're managed via the APIs, and how they're best used.

| Data Type | Purpose                                                                | Mange with                                             | Accessible within instances |
| --------- | ---------------------------------------------------------------------- | ------------------------------------------------------ | --------------------------- |
| tags      | Identify an instance externally and use as instance selection criteria | Portal, CloudAPI                                       | no                          |
| metadata  | Insert data within an instance, such as environment variables          | Portal, CloudAPI, metadata client (`mdata-*` commands) | yes                         |

To create or modify **tags** with `triton`, the user must have the proper permissions and keys. **Metadata** can be modified within an instance without the need for permissions or keys.

Learn more about the use cases for [tags](https://docs.joyent.com/public-cloud/tags-metadata/tags#use-cases-for-tags) and [metadata](https://docs.joyent.com/public-cloud/tags-metadata/metadata#use-cases-for-metadata).


# Connecting to containers and VMs

## Connecting to containers and VMs=

SSH, `triton-docker exec`, and Microsoft Remote Desktop are all supported connection methods to "log in" to instances in Triton.

### [Detailed instructions](/instances/connecting-to-containers-and-vms#detailed-instructions) <a href="#detailed-instructions" id="detailed-instructions"></a>

SSH is the primary means of connecting and authenticating for command line access to all container types with the exception of Docker and Windows instances.

* [SSH to an instance from Mac OS X or Windows](/getting-started/ssh-from-windows)
* Connecting to Docker containers using `triton-docker exec`

### [SSH key management](/instances/connecting-to-containers-and-vms#ssh-key-management) <a href="#ssh-key-management" id="ssh-key-management"></a>

The propagation of SSH keys is handled differently depending on container type. The following table provides an overview of the differences.

| Container Type               | Authentication Type                                         | Notes                                                                                                                                                                                                |
| ---------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SmartOS                      | Uses SmartLogin                                             | Authenticates against current list of keys in the account of the container owner.                                                                                                                    |
| Container Native Linux       | Uses `authorized_keys` file                                 | Keys in the account of the container owner are copied at provision time. Changes to the keys in the account are not reflected. Can force an update to the authorized\_keys file via a metadata item. |
| Hardware Virtualized Linux   | Uses `authorized_keys` file                                 | Keys in the account of the container owner are copied at provision time. Changes to the keys in the account are not reflected. Can force an update to the authorized\_keys file via a metadata item. |
| Hardware Virtualized Windows | Uses generated administrator password                       | Uses password generated for a given account via the \*generate\_passwords" option in the image configuration json.                                                                                   |
| Docker Containers            | Communication is via TLS secured HTTP; no `sshd` by default | Uses client certificate.                                                                                                                                                                             |

Notes:

* All access should be done as the `root` user unless otherwise noted.
* Newer Ubuntu distributions use the `ubuntu` user for remote access.
* Windows based distributions use the `administrator` account and the normal windows login process; Windows containers do not use SSH keys.


# Instance Types

An overview of the various instance types

## Compute, General & Memory

&#x20;There are 3 instance types defined.  Compute, General & Memory.  The major difference between these instance types is the CPU to Memory allocation as follows:

c1.\*  --  Compute Instance = 1 vCPU to 2GB of RAM\
g1.\* -- General Instance = 1 vCPU to 4GB of RAM\
m1.\* -- Memory Instance = 1 vCPU to 8GB of RAM

Each instance also has a specific amount of disk allocated.

{% hint style="info" %}
If you need a custom instance type created, please reach out and we'll provide feedback and pricing.
{% endhint %}


# Triton CLI & Tools

* [Triton CLI tool](/api/triton-cli-tool)
* [Hashicorp Packer and Terraform](/api/hashicorp#hashicorp-packer-and-terraform)
* [Container Monitor with Prometheus](/api/container-monitor-with-prometheus)

Details on the CloudAPI URL [available on our datacenter page.](/data-centers)


# Using the VNC console

When running KVM or BHYVE based compute instances you can access the VNC console

## Getting access to the console

To gain access to the console, you must have the [Triton CLI tools installed](/api/triton-cli-tool).     Configure the environmental variables.   As an example:

```
$ export SDC_ACCOUNT="<your username>";
$ export SDC_KEY_ID="<your SSH key ID (XX:XX:XX:XX...)";
$ export SDC_URL="https://us-central-1.api.mnx.io";
```

{% hint style="info" %}
&#x20;Login to the portal and these are generated for you at <https://portal.mnx.io/faq/triton-cli/>.
{% endhint %}

Next, use the triton CLI to establish a VNC proxy session

{% code title="Using triton-cli to establish a VNC session" %}

```bash
$ triton inst ls
SHORTID   NAME          IMG                  STATE    FLAGS  AGE
dec9179d  mnx-test-vnc  centos-8@20200528    running  K      19w
1928324a  mnx-webserve  freebsd-12@20190424  running  K      18w

$ triton inst vnc dec9179d
Listening on vnc://127.0.0.1:60823
```

{% endcode %}

Now, use your VNC program to connect to the listening address and you will have access to the console.


# Triton CLI tool

## Triton CLI tool

The Triton command line tool (`triton`) uses CloudAPI to manage infrastructure in Triton data centers. Many of the tasks that you can perform through the portal are also possible with Triton CLI, including:

* Provision compute instances, including infrastructure containers and hardware virtual machines
* Manage compute instances, including Docker containers, infrastructure containers and hardware virtual machines
* Provision and manage networks
* Manage your account

In this page, you will learn how to install `triton`. You can learn more about CloudAPI methods and resources [in our additional reference documentation](http://apidocs.joyent.com/cloudapi/).

Need a visual reference? [Watch the screencast](/api/triton-cli-tool#watch-to-learn) which covers how to install the Triton CLI tool and manage infrastructure in Triton data centers.

### [Installation](/api/triton-cli-tool#installation) <a href="#installation" id="installation"></a>

To install Triton CLI and CloudAPI tools, you must first install Node.js. You can find the latest version of Node.js for your operating system and architecture at [nodejs.org](http://nodejs.org/).

You can install `triton` using Node Package Manager (`npm`). In the following example, the `npm` install command sets a global flag (`-g`) that makes `npm` modules accessible to all users. This flag is mandatory when installing `triton` on Windows.

```
$ sudo npm install -g triton
. . .
/usr/local/bin/triton -> /usr/local/lib/node_modules/triton/bin/triton
triton@4.11.0 /usr/local/lib/node_modules/triton
├── bigspinner@3.1.0
├── assert-plus@0.2.0
├── extsprintf@1.0.2
├── wordwrap@1.0.0
├── strsplit@1.0.0
├── node-uuid@1.4.3
├── read@1.0.7 (mute-stream@0.0.6)
├── semver@5.1.0
├── vasync@1.6.3
├── once@1.3.2 (wrappy@1.0.2)
├── backoff@2.4.1 (precond@0.2.3)
├── verror@1.6.0 (extsprintf@1.2.0)
├── which@1.2.4 (isexe@1.1.2, is-absolute@0.1.7)
├── cmdln@3.5.4 (extsprintf@1.3.0, dashdash@1.13.1)
├── lomstream@1.1.0 (assert-plus@0.1.5, extsprintf@1.3.0, vstream@0.1.0)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── sshpk@1.7.4 (ecc-jsbn@0.1.1, jsbn@0.1.0, asn1@0.2.3, jodid25519@1.0.2, dashdash@1.13.1, tweetnacl@0.14.3)
├── rimraf@2.4.4 (glob@5.0.15)
├── tabula@1.7.0 (assert-plus@0.1.5, dashdash@1.13.1, lstream@0.0.4)
├── smartdc-auth@2.3.0 (assert-plus@0.1.2, once@1.3.0, clone@0.1.5, dashdash@1.10.1, sshpk@1.7.1, sshpk-agent@1.2.0, vasync@1.4.3, http-signature@1.1.1)
├── restify-errors@3.0.0 (assert-plus@0.1.5, lodash@3.10.1)
├── bunyan@1.5.1 (safe-json-stringify@1.0.3, mv@2.1.1, dtrace-provider@0.6.0)
└── restify-clients@1.1.0 (assert-plus@0.1.5, tunnel-agent@0.4.3, keep-alive-agent@0.0.1, lru-cache@2.7.3, mime@1.3.4, lodash@3.10.1, restify-errors@4.2.3, dtrace-provider@0.6.0)
```

**NOTE**: on some platforms and for some installations of Node.js, you may receive an error when using `sudo`. Remove it from the command to install `triton`:

```
$ npm install -g triton
```

### [Environment variables](/api/triton-cli-tool#environment-variables) <a href="#environment-variables" id="environment-variables"></a>

We recommend setting up environment variables to populate an initial environment-based profile. These environment variables are useful for interacting with CloudAPI as well as other tools such as Packer and Terraform.

On Windows, this step is mandatory.

#### [Add environment variables on macOS](/api/triton-cli-tool#add-environment-variables-on-macos) <a href="#add-environment-variables-on-macos" id="add-environment-variables-on-macos"></a>

Environment variables live in your bash profile, `.bash_profile`. On macOS, this file should be in your home directory.

From the terminal, edit your bash profile:

```
$ vi .bash_profile
```

Add the following content to your profile, modified to include the correct Triton username and SSH key if not `id_rsa.pub`:

```
export TRITON_PROFILE="env"
export TRITON_URL="https://us-central-1.api.mnx.io"
export TRITON_ACCOUNT="<TRITON_USERNAME>"
unset TRITON_USER
export TRITON_KEY_ID="$(ssh-keygen -l -f $HOME/.ssh/id_rsa.pub | awk '{print $2}')"
unset TRITON_TESTING
unset TRITON_PROFILE
```

Previous versions of `triton` required environment variables that began with `SDC_*`, i.e. `SDC_URL` and `SDC_ACCOUNT`. As of January 2018, the SDC environment variables are still supported by `triton`.

If you've installed `smartdc`, you must [set up `SDC_*` environment variables](https://apidocs.joyent.com/cloudapi/#set-up-your-cli).

### [Configuring Triton profiles](/api/triton-cli-tool#configuring-triton-profiles) <a href="#configuring-triton-profiles" id="configuring-triton-profiles"></a>

Triton CLI uses "profiles" to store access information. Profiles contain the data center CloudAPI URL, your login name, and SSH key fingerprint. You can create a profile for each data center or profiles for different users. Profiles make it easy to connect to different data centers, or connect to the same data center as different users.

The `triton profile create` command prompts you to answer a series of questions to configure your profile. The following example shows the steps for Triton user `jill`.

```
$ triton profile create

A profile name. A short string to identify a CloudAPI endpoint to the `triton` CLI.
name: us-central-1

The CloudAPI endpoint URL.
url: https://us-central-1.api.mnx.io

Your account login name.
account: myuser

The fingerprint of the SSH key you have registered for your account. You may enter a local path to a public or private key to have the fingerprint calculated for you.
keyId: ~/.ssh/<ssh key name>.id_rsa
Fingerprint: 2e:c9:f9:89:ec:78:04:5d:ff:fd:74:88:f3:a5:18:a5

Saved profile "us-central-1"
```

Select a CloudAPI endpoint URL from any of our [global data centers](/data-centers), or use a Triton-powered data center of your own (remember: [it's open source](https://github.com/joyent/sdc)).

To test the installation and configuration, let's use `triton info`:

```
$ triton info
login: myuser
name: MyUser Example
email: myuser@example.com
url: https://us-central-1.api.mnx.io
totalDisk: 22.1 GiB
totalMemory: 2.0 GiB
instances: 2
running: 2
```

The `triton info` output above shows that myuser's account already has two instances running.

### [Using profiles](/api/triton-cli-tool#using-profiles) <a href="#using-profiles" id="using-profiles"></a>

You can view all configured profiles with the `triton profiles` command:

```
$ triton profiles
NAME      CURR  ACCOUNT      USER  URL
us-central-1 *   myuser       -     https://us-central-1.api.mnx.io
```

Next let's make a profile for each data center. To do this we will use `triton` commands to make a copy of the `us-sw-1` profile for each of the data center urls. Copy this snippet below to add the new profiles (in this case, based on a profile named 'env'):

```
triton datacenters | egrep -v NAME | while read -r i; do name=$(echo $i | awk {'print $1'}); url=$(echo $i | awk {'print $2'}); triton profile get -j env | sed -e "s/env/$name/" -e "s#http[^\"]*#$url#" | triton profile create -f - -y; done
```

Run `triton profiles` again to check to see that it worked. We should have a new profile for each data center listed in `triton datacenters`:

```
$ triton profiles
NAME       CURR  ACCOUNT      USER  URL
us-central-1     myuser       -     https://us-central-1.api.mnx.io

```

You can change the default profile with the `triton profile set` command:

```
$ triton profile set us-central-1
Set "us-central-1" as current profile
```

### [Completions](/api/triton-cli-tool#completions) <a href="#completions" id="completions"></a>

You can also [configure bash completions](https://github.com/joyent/node-triton#bash-completion) with this command:

```
# Mac OSX
$ triton completion > /usr/local/etc/bash_completion.d/triton

# Linux
$ triton completion > /etc/bash_completion.d/triton

# Windows bash shell
$ triton completion >> ~/.bash_completion
```

### [Quick start: create an instance](/api/triton-cli-tool#quick-start-create-an-instance) <a href="#quick-start-create-an-instance" id="quick-start-create-an-instance"></a>

With `triton` installed and configured, we can jump right into provisioning instances. Here's an example of provisioning an infrastructure container running Ubuntu. Think of infrastructure containers like virtual machines, only faster and more efficient.

Let's run `triton instance create` and we'll talk about the pieces after:

```
$ triton instance create -w --name=server-1 ubuntu-14.04 g4-highcpu-1G
Creating instance server-1 (e9314cd2-e727-4622-ad5b-e6a6cac047d4, ubuntu-14.04@20160114.5, g4-highcpu-1G)
Created instance server-1 (e9314cd2-e727-4622-ad5b-e6a6cac047d4) in 22s
```

Now that we have an instance, we can run `triton ssh` to connect to it. This is an awesome addition to our tools because it means that we don't need to copy SSH keys or even lookup the IP address of the instance.

```
$ triton ssh server-1
Welcome to Ubuntu 14.04 (GNU/Linux 3.19.0 x86_64)

 * Documentation:  https://help.ubuntu.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

   __        .                   .
 _|  |_      | .-. .  . .-. :--. |-
|_    _|     ;|   ||  |(.-' |  | |
  |__|   `--'  `-' `;-| `-' '  ' `-'
                   /  ;  Instance (Ubuntu 14.04 20151105)
                   `-'   https://docs.joyent.com/images/container-native-linux

root@8367b339-799b-cff5-a662-a211e1927797:~#
```

### [Instance creation options and details](/api/triton-cli-tool#instance-creation-options-and-details) <a href="#instance-creation-options-and-details" id="instance-creation-options-and-details"></a>

In our quick start example, we ran `triton instance create -w --name=server-1 ubuntu-14.04 g4-highcpu-1G`. That command has three parameters:

1. We gave our instance a name using `--name server-1`
2. We used `-w` to wait the instance to be created
3. We used `ubuntu-14.04` as our image
4. We set `g4-highcpu-1G` as our package

Let's look at each of those in detail to see how you can set the options that will work best for your needs.

#### [Specifying the instance name](/api/triton-cli-tool#specifying-the-instance-name) <a href="#specifying-the-instance-name" id="specifying-the-instance-name"></a>

Names for instances can be up to 189 characters and include any alphanumeric character plus `_`, `-`, and `.`

#### [Selecting an image](/api/triton-cli-tool#selecting-an-image) <a href="#selecting-an-image" id="selecting-an-image"></a>

Finding our Ubuntu image is pretty easy. We use `triton images` to list the images and add `name=~ubuntu` to do a substring search for Ubuntu. It's sorted by published date so usually we'll pick the most recent. Today we'll choose 14.04 because it has wider support.

```
$ triton images name=~ubuntu type=lx-dataset
SHORTID   NAME          VERSION   FLAGS  OS     TYPE        PUBDATE
...
c8d68a9e  ubuntu-14.04  20150819  P      linux  lx-dataset  2015-08-19
52be84d0  ubuntu-14.04  20151005  P      linux  lx-dataset  2015-10-05
ffe82a0a  ubuntu-15.04  20151105  P      linux  lx-dataset  2015-11-05
```

**Note**: Want to build a custom application using our infrastructure containers? Learn how to [create a custom ifrastructure image](https://docs.joyent.com/public-cloud/instances/infrastructure/images/creating#commandlinetools).

#### [Selecting a package](/api/triton-cli-tool#selecting-a-package) <a href="#selecting-a-package" id="selecting-a-package"></a>

There are 4 types of packages available for containers: compute optimized (`g4-highcpu-<size>`), general purpose (`g4-general-<size>`), memory optimized (`g4-highram-<size>`), and storage optimized (`g4-fastdisk-<size>` and `g4-bigdisk-<size>`).

The package types for [HVMs](broken://pages/-LuID4_hwqbFpo0AVCQc#triton-virtual-machines) have a similar name structure: compute optimized (`k4-highcpu-<kvm|bhyve>-<size>`), general purpose (`k4-general-<kvm|bhyve>-<size>`), memory optimized (`k4-highram-<kvm|bhyve>-<size>`), and storage optimized (`k4-fastdisk-<kvm|bhyve>-<size>` and `k4-bigdisk-<kvm|bhyve>-<size>`).

We'll use `triton package` to search for a package with 1 gigabyte of RAM. We'll pick the `g4-highcpu-1G`.

```
$ triton packages memory=1024
SHORTID   NAME               MEMORY  SWAP  DISK  VCPUS
14af2214  g4-highcpu-1G      1G      4G    25G     -
```

At this time, there is no way to use `triton` to fetch the pricing details for the different packages. To find out those costs, you can visit our [public pricing page](https://www.joyent.com/pricing/cloud/compute).

### [Watch to learn](/api/triton-cli-tool#watch-to-learn) <a href="#watch-to-learn" id="watch-to-learn"></a>

This screencast covers how to install the Triton CLI tool and use CloudAPI to manage infrastructure in Triton data centers.

If you skipped ahead to the video, you can go back and review the [installation process](/api/triton-cli-tool#installation) for step-by-step instructions.

### [Bootstrapping an instance with a script](/api/triton-cli-tool#bootstrapping-an-instance-with-a-script) <a href="#bootstrapping-an-instance-with-a-script" id="bootstrapping-an-instance-with-a-script"></a>

Our quick start example didn't include one of the most useful options for automating infrastructure on Triton: specifying a script for containers to run at startup.

The command below sets up a 16GB CentOS infrastructure container, and installs Couchbase. The `--script` file installs Couchbase, and the `triton ssh` runs `cat /root/couchbase.txt` to show the address of the Couchbase dashboard.

```
curl -sL -o couchbase-install-triton-centos.bash https://raw.githubusercontent.com/misterbisson/couchbase-benchmark/master/bin/install-triton-centos.bash

triton instance create \
    --name=couch-bench-1 \
     $(triton images name=~centos-6 type=lx-dataset -Ho id | tail -1) \
    'Large 16GB' \
    --wait \
    --script=./couchbase-install-triton-centos.bash

triton ssh couch-bench-1 'cat /root/couchbase.txt'
```

Infrastructure management isn't just about creating instances. Triton CLI offers some of its biggest improvements in this space. Below are some examples of `triton` commands.

#### [List instances](/api/triton-cli-tool#list-instances) <a href="#list-instances" id="list-instances"></a>

```
$ triton instances
SHORTID    NAME           IMG                    STATE    PRIMARYIP         AGO
1fdc4b78   couch-bench-1  8a1dbc62               running  165.225.136.140   3m
8367b039   server-1       ubuntu-14.04@20151005  running  165.225.122.69    3m
```

#### [Wait for tasks](/api/triton-cli-tool#wait-for-tasks) <a href="#wait-for-tasks" id="wait-for-tasks"></a>

By default the `triton` tool does not wait for tasks to finish. This is great because it means that your commands return control back to you very quickly. However sometimes you'll need to wait for a task to complete before you do the next one. When this happens you can wait by using either the `--wait` or `-w` flags, or the `triton instance wait` command. In the example above we used `--wait` so that the instance would be ready by the time the `triton ssh` command ran.

#### [Show instance details](/api/triton-cli-tool#show-instance-details) <a href="#show-instance-details" id="show-instance-details"></a>

Use `triton instance get -j` to view your instance's details as a JSON blob. To parse fields out of the blob, I recommend using [json](https://github.com/trentm/json) although there are many other great tools out there.

```
$ triton instance get -j couch-bench-1
{
    "id": "1fdc4b78-62ec-cb97-d7ff-f99feb8b3d2a",
    "name": "couch-bench-1",
    "type": "smartmachine",
    "state": "running",
    "image": "82cf0a0a-6afc-11e5-8f79-273b6aea6443",
    "ips": [
        "165.225.136.140",
        "10.112.2.230"
    ],
    "memory": 16384,
    "disk": 409600,
    "metadata": {
        "user-script": "#!/bin/bash\n...\n\n",
        "root_authorized_keys": "ssh-rsa ..."
    },
    "tags": {},
    "created": "2015-12-18T03:44:42.314Z",
    "updated": "2015-12-18T03:45:10.000Z",
    "networks": [
        "65ae3604-7c5c-4255-9c9f-6248e5d78900",
        "56f0fd52-4df1-49bd-af0c-81c717ea8bce"
    ],
    "dataset": "82cf0a0a-6afc-11e5-8f79-273b6aea6443",
    "primaryIp": "165.225.136.140",
    "firewall_enabled": false,
    "compute_node": "44454c4c-4400-1059-804e-b5c04f383432",
    "package": "g4-general-16G"
}
```

Up above you can see that the `user-script` that we ran is part of the metadata.

You can pull out individual values by piping the output to `json KEYNAME`. For example you could get the IP address of an instance like this:

```
$ triton instance get -j couch-bench-1 | json primaryIp
165.225.136.140
```

#### [Clean up](/api/triton-cli-tool#clean-up) <a href="#clean-up" id="clean-up"></a>

Let's wrap up with this container. We'll delete it using the `triton instance delete` command:

```
$ triton instance delete server-1 couch-bench-1
Delete (async) instance server-1 (8367b039-759b-c6f5-a6c2-a210e1926798)
Delete (async) instance couch-bench-1 (1fdc4b78-62ec-cb97-d7ff-f99feb8b3d2a)
```

For something a bit more dangerous, you can delete all your instances using this command:

```
$ triton instance delete $(triton instances -Ho shortid)
```

Be careful. Using the `triton instance delete` command removes all of your instances regardless of whether they running or stopped.

If you are familiar with using `docker`, note that this is equivalent to using `docker rm -f $(docker ps -aq)` to force the deletion of all your containers. If you want to remove all of your instances, using `triton instance delete` might be faster since it deletes the instances in parallel.

### [CloudAPI and Triton Elastic Docker Host](/api/triton-cli-tool#cloudapi-and-triton-elastic-docker-host) <a href="#cloudapi-and-triton-elastic-docker-host" id="cloudapi-and-triton-elastic-docker-host"></a>

In addition to CloudAPI and the Triton CLI tool, you can also create and manage bare metal Docker containers on Triton using the Triton Elastic Docker Host and Triton-Docker CLI tools. The two APIs work in parallel, though the Triton-Docker CLI can *only* create and manage bare metal Docker containers on Triton. CloudAPI and the Triton CLI tool can manage almost every aspect of Docker containers with the exception of provisioning bare metal Docker containers on Triton.


# Hashicorp Packer and Terraform

## Hashicorp Packer and Terraform

[Hashicorp's Packer](https://www.packer.io/) is a tool for creating and managing customized Triton infrastructure or HVM images which you can easily deploy into multiple instances. These images can be deployed independently with `triton` CLI or by using Terraform.

[Hashicorp's Terraform](https://www.terraform.io/) is a powerful tool to create, manage, and version reproducible infrastructure, including compute resources and upstack services. [From the Terraform.io website](https://www.terraform.io/intro/index.html):

> Terraform allows you to effortlessly combine high-level system providers with your own or with each other. Launch a server from one cloud provider, add a DNS entry with its IP with a different provider. Built-in dependency resolution means things happen in the right order.

### Learn more <a href="#learn-more" id="learn-more"></a>

* [Learn more about how to use Packer](/api/hashicorp/create-and-manage-images-with-packer)
* [Learn more about how to use Terraform](/api/hashicorp/manage-infrastructure-with-terraform)

Joyent customers can [contact support](/contacting-mnx-support) for issues specific to Packer or Terraform on Triton.


# Create and manage images with Packer

## Create and manage images with Packer

There are a number of ways to deploy custom applications on Triton. Triton provides multiple hardware virtual machine (HVM) and infrastructure images to meet your various application needs. Run `triton images` to see a list of what's available.

Packer is platform-agnostic. That means if you've got existing Packer templates which build images for other cloud providers, it's easy to adapt them to build those same images on Triton.

Although those images can be deployed into containers that can be customized individually, that extra work can be cumbersome and difficult to replicate.

[Watch to learn](/api/hashicorp/create-and-manage-images-with-packer#watch-to-learn) how to create custom infrastructure images with Packer.

### [Watch to learn](/api/hashicorp/create-and-manage-images-with-packer#watch-to-learn) <a href="#watch-to-learn" id="watch-to-learn"></a>

Watch this demo to understand how to use Packer to build a custom image.

To see the instructions for building the Happiness Randomizer, [read our blog post](https://www.joyent.com/blog/video-create-images-with-packer)

### [Installing Packer](/api/hashicorp/create-and-manage-images-with-packer#installing-packer) <a href="#installing-packer" id="installing-packer"></a>

Before you can create an image with Packer, you must [install it](https://www.packer.io/docs/install/index.html).

It is also important to set the PATH for your system.

#### [Set PATH for macOS or Linux](/api/hashicorp/create-and-manage-images-with-packer#set-path-for-macos-or-linux) <a href="#set-path-for-macos-or-linux" id="set-path-for-macos-or-linux"></a>

Edit your bash profile (that may look like `.bash_profile` or `.bashrc`) to add the PATH and other environment variables, just as you've done for [CloudAPI environment variables](/api/triton-cli-tool#environment-variables).

Add the following content:

```
export PATH=$PATH:/usr/local/packer
```

If you've installed Packer in a different directory, you must modify `/usr/local/packer` to reflect the correct information.

#### [Set PATH for Windows](/api/hashicorp/create-and-manage-images-with-packer#set-path-for-windows) <a href="#set-path-for-windows" id="set-path-for-windows"></a>

You can set the PATH by going to the Control Panel -> System -> Advanced System Settings. Under Environment Variables, scroll until you find PATH. Edit accordingly and be sure to include a semicolon at the end of any previously set paths. For example:

```
c:\path\to\example1;c:\path\to\packer
```

#### [Validate Packer's installation](/api/hashicorp/create-and-manage-images-with-packer#validate-packers-installation) <a href="#validate-packers-installation" id="validate-packers-installation"></a>

Validate the installation of Packer by running `packer` in your terminal:

```
$ packer
Usage: packer [--version] [--help] <command> [<args>]

Available commands are:
    build       build image(s) from template
    fix         fixes templates from old versions of packer
    inspect     see components of a template
    push        push a template and supporting files to a Packer build service
    validate    check that a template is valid
    version     Prints the Packer version
```

If `packer` cannot be found, PATH was not properly set up.

### [Create a Packer template](/api/hashicorp/create-and-manage-images-with-packer#create-a-packer-template) <a href="#create-a-packer-template" id="create-a-packer-template"></a>

To create a Packer image for an application, you must create a Packer template. The template can live either within a local directory of the application or in a separate empty directory.

The configuration file determines the type of image being built and is written in JSON. For example, this file may be called `my-application.json`.

#### [Add variables](/api/hashicorp/create-and-manage-images-with-packer#add-variables) <a href="#add-variables" id="add-variables"></a>

The contents of the file begin with [Triton environment variables](https://docs.joyent.com/public-cloud/api/triton-cli#environment-variables) for your account, followed by the builders and provisioners.

**NOTE**: Though it is possible to create a Packer configuration file without setting up environment variables, we do not advise you do so. It is a best practice to store all important keys locally as environment variables instead of tying it to your application files.

Variables are particularly useful when it comes to sensitive information, such as your account login and SSH key fingerprint. These are the same variables used for CloudAPI and other Triton tools. To access these variables, it's important to set the Triton environment before [building your image](/api/hashicorp/create-and-manage-images-with-packer#build-the-image).

```
{
  "variables": {
      "triton_url": "{{env `SDC_URL`}}",
      "triton_account": "{{env `SDC_ACCOUNT`}}",
      "triton_key_id": "{{env `SDC_KEY_ID`}}"
  },
```

#### [Add Packer builders](/api/hashicorp/create-and-manage-images-with-packer#add-packer-builders) <a href="#add-packer-builders" id="add-packer-builders"></a>

[**Builders**](https://www.packer.io/docs/builders/index.html) create machine images for individual platforms. [Triton](https://www.packer.io/docs/builders/triton.html) is a builder, using CloudAPI to create the image. The builder launches a temporary VM based on the template, runs any provisioning necessary, creates a reusable image, and then destroys the VM. This builder does not manage images; you must use or delete it with CloudAPI outside of Packer.

Below is an example of a Triton builder for a web-based application using Nginx.

```
"builders": [
   {
      "type": "triton",
      "triton_url": "{{user `triton_url`}}",
      "triton_account": "{{user `triton_account`}}",
      "triton_key_id": "{{user `triton_key_id`}}",

      "source_machine_image_filter": {
         "name": "nginx",
         "most_recent": "true"
      },
      "source_machine_package": "g4-highcpu-128M",

      "ssh_username": "root",

      "image_name": "my_application",
      "image_version": "1.0.0",
      "image_tags": {
         "Project": "My Application"
      }
   }
],
```

**NOTE**: For your SSH key to be usable, it must be available through the [`ssh-agent`](/getting-started/generating-an-ssh-key).

There is also a [Docker builder](https://www.packer.io/docs/builders/docker.html) available to create custom Docker images.

#### [Add provisioners to customize the image](/api/hashicorp/create-and-manage-images-with-packer#add-provisioners-to-customize-the-image) <a href="#add-provisioners-to-customize-the-image" id="add-provisioners-to-customize-the-image"></a>

[**Provisioners**](https://www.packer.io/docs/provisioners/index.html) install and configure software within a running machine prior to the machine becoming a static image. The provisioners perform the work that customizes Triton images to contain software including installing packages, creating users, and downloading application code.

Two of the most common provisioners are `file` and `shell`.

The `file` provisioner uploads files to machines built by Packer. The recommended usage of the file provisioner is to use it to upload files, and then use `shell` provisioner to move them to the proper place, set permissions, etc. The `file` provisioner can refer to a single file, such as `index.html`, or an entire directory, such as `directory/`.

```
"provisioners": [
   {
      "type": "file",
      "source": "index.html",
      "destination": "/usr/share/nginx/html/"
   },   {
      "type": "file",
      "source": "directory-name/",
      "destination": "/usr/share/nginx/html/directory-name/"
   }
]
}
```

The `shell` provisioner provisions machines built by Packer using shell scripts. Shell provisioning is the easiest way to get software installed and configured on a machine.

```
"provisioners": [
   {
      "type": "shell",
      "script": "create-directories.sh"
   }
]
}
```

[Read more about provisioners](https://www.packer.io/docs/provisioners/index.html).

### [Build a Packer image](/api/hashicorp/create-and-manage-images-with-packer#build-a-packer-image) <a href="#build-a-packer-image" id="build-a-packer-image"></a>

Once your template is complete, you can proceed to build the application image.

####

Validate the Packer template and ensure that the JSON syntax and configuration values are correct.

```
$ packer validate my-application.json
Template validated successfully.
```

**NOTE**: If the template validation was not successful, that means there is an error in your configuration file. The `validate` command should tell you where to find the error.

#### &#x20;[to create the image](/api/hashicorp/create-and-manage-images-with-packer#-to-create-the-image) <a href="#to-create-the-image" id="to-create-the-image"></a>

To create your Packer image, execute `packer build` with the name of the template file. The output will look something like this:

```
$ packer build my-application.json
triton output will be in this color.

==> triton: Waiting for source machine to become available...
==> triton: Waiting for SSH to become available...
==> triton: Connected to SSH!
==> triton: Provisioning with shell script: add-directories.sh
==> triton: Uploading index.html => /usr/share/nginx/html/
==> triton: Uploading css/ => /usr/share/nginx/html/css/
==> triton: Uploading js/ => /usr/share/nginx/html/js/
==> triton: Stopping source machine (6163c9e1-0ee6-eccb-c8bb-9f4369c73bb0)...
==> triton: Waiting for source machine to stop (6163c9e1-0ee6-eccb-c8bb-9f4369c73bb0)...
==> triton: Creating image from source machine...
==> triton: Waiting for image to become available...
==> triton: Deleting source machine...
==> triton: Waiting for source machine to be deleted...
Build 'triton' finished.

==> Builds finished. The artifacts of successful builds are:
--> triton: Image was created: c7da3619-5b1d-4fc7-bde6-503a3f8450b1
```

**Artifacts** are the result of a single build, including a set of IDs or files that represent the final machine image. Every builder produces a single artifact. For the Triton builder, the artifact is the new image ID.

#### [View custom Packer images with Triton CLI](/api/hashicorp/create-and-manage-images-with-packer#view-custom-packer-images-with-triton-cli) <a href="#view-custom-packer-images-with-triton-cli" id="view-custom-packer-images-with-triton-cli"></a>

To see the custom Packer image details with Triton CLI, use `triton image get` with either the image ID or the image name.

```
$ triton image get my_application
```

### [Next steps](/api/hashicorp/create-and-manage-images-with-packer#next-steps) <a href="#next-steps" id="next-steps"></a>

Once the image is created, you can create an instance. [Read our documentation on instance creation](https://docs.joyent.com/public-cloud/api/triton-cli#quick-start-create-an-instance).


# Manage infrastructure with Terraform

## Manage infrastructure with Terraform

[Hashicorp's Terraform](https://www.terraform.io/) is a tool designed for creating, managing, updating, and versioning reproducible application infrastructure. Application infrastructure is composed of all physical and virtual resources (including compute resources and upstack services) which support the flow, storage, processing, and analysis of data.

Terraform can manage all three types of Triton compute resources as first order objects:

1. Bare metal Docker containers. These run the Docker images you expect, but without complication of having to run them in a virtual machine or prepare the infrastructure first.
2. Infrastructure containers. These work like hardware virtual machines, but perform like the bare metal containers they are.
3. Hardware virtual machines. These allow flexibility to run Windows or other non-Linux operating systems.

### [Installing Terraform](/api/hashicorp/manage-infrastructure-with-terraform#installing-terraform) <a href="#installing-terraform" id="installing-terraform"></a>

Follow [Terraform's installation instructions](https://www.terraform.io/intro/getting-started/install.html).

Verify the installation by opening a new terminal session. Execute `terraform` and you should see a help output similar to this:

```
$ terraform
Usage: terraform [--version] [--help] <command> [args]

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
# ...
```

If you receive an error that `terraform` could not be found, PATH was not properly set up.

#### [Set PATH on macOS or Linux](/api/hashicorp/manage-infrastructure-with-terraform#set-path-on-macos-or-linux) <a href="#set-path-on-macos-or-linux" id="set-path-on-macos-or-linux"></a>

Open your terminal and run the following command:

```
export PATH=$PATH:/path/to/dir
```

You can also symlink to `terraform`:

```
cd /usr/bin
sudo ln -s </path/to/dir> terraform
```

#### [Set PATH on Windows](/api/hashicorp/manage-infrastructure-with-terraform#set-path-on-windows) <a href="#set-path-on-windows" id="set-path-on-windows"></a>

Go to: Control Panel -> System -> Advanced System settings\* -> Environment Variables.

Scroll down in system variables until you find PATH. Click edit and change accordingly. You will need to launch a new console for the settings to take effect.

### [Terraform input variables](/api/hashicorp/manage-infrastructure-with-terraform#terraform-input-variables) <a href="#terraform-input-variables" id="terraform-input-variables"></a>

To ensure your application is shareable and version controlled, it's important to include input variables in your Terraform configuration.

Create a variables file. This file can be named anything, since Terraform loads all files ending in .tf in a directory. The most common file name is `variables.tf`.

Variables may include login credentials or secret keys. Variables can also include image names, package names, version numbers, counts, and more.

Here is an example of variables including descriptions for each:

```
variable "service_name" {
  type        = "string"
  description = "The name of the service for Triton CNS."
  default     = "my-application"
}

variable "service_networks" {
  type        = "list"
  description = "Triton networks connected to your instance."
  default     = ["Joyent-SDC-Public"]
}

variable "image_name" {
  type        = "string"
  description = "The name of the image for deployment."
  default     = "nginx-1"
}

variable "image_type" {
  type        = "string"
  description = "Is this image a Linux image or a HVM image."
  default     = "lx-dataset"
}

variable "image_version" {
  type        = "string"
  description = "The version number for this image."
  default     = "20170404"
}

variable "package_name" {
  type        = "string"
  description = "The package to use when making a deployment."
  default     = "g4-highcpu-128M"
}
```

### [Terraform modules](/api/hashicorp/manage-infrastructure-with-terraform#terraform-modules) <a href="#terraform-modules" id="terraform-modules"></a>

[**Modules**](https://www.terraform.io/docs/configuration/modules.html) are self-contained packages of Terraform configuration. Modules can be used to create reusable components and to organize code. Think of modules like functions: modules have input variables and output variables.

The only required piece of information in a module is the **`source`**, which tells Terraform where to download the data sources and resources which in turn tell Terraform what to use.

For example, here is a module for deploying an application to `us-sw-1`:

```
module "east" {
  source      = "./modules/service"
  region_name = "us-sw-1"

  instance_count  = 3

  service_production = "${var.service_production}"
  service_name       = "${var.service_name}"
  service_networks   = "${var.service_networks}"

  image_name     = "${var.blue_image_name}"
  image_type     = "${var.blue_image_type}"
  image_version  = "${var.blue_image_version}"
  package_name   = "${var.blue_package_name}"
}
```

### [Terraform configuration file](/api/hashicorp/manage-infrastructure-with-terraform#terraform-configuration-file) <a href="#terraform-configuration-file" id="terraform-configuration-file"></a>

The confirmation file will declare the provider, data sources, resources, and outputs after running Terraform. The minimum version of Terraform required is 0.10.x.

To ensure the correct version is being used, include the following at the top of your configuration file:

```
terraform {
  required_version = ">= 0.10.0"
}
```

#### [Define the Triton provider](/api/hashicorp/manage-infrastructure-with-terraform#define-the-triton-provider) <a href="#define-the-triton-provider" id="define-the-triton-provider"></a>

[**Providers**](https://www.terraform.io/docs/configuration/providers.html) are the underlying platforms which support Terraform. Providers are responsible for managing the lifecycle of a resource: create, read, update, delete. Triton is a Terraform provider.

```
provider "triton" {
  # The provider takes the following environment variables:
  # TRITON_URL, TRITON_ACCOUNT, and TRITON_KEY_ID
}
```

The `"triton"` provider uses Triton environment variables including your Triton username, SSH fingerprint, and the CloudAPI endpoint.

**NOTE**: Though it is possible to proceed without setting up environment variables by replacing the contents with the corresponding information, we do not advise you do so. It is a best practice to store all important keys locally instead of tying it to your application files.

#### [Define data sources](/api/hashicorp/manage-infrastructure-with-terraform#define-data-sources) <a href="#define-data-sources" id="define-data-sources"></a>

[**Data sources**](https://www.terraform.io/docs/configuration/data-sources.html) allow data to be fetched or computed for use within Terraform configuration, allowing Terraform to build infrastructure based on information from outside of Terraform (or from a separate Terraform configuration file). Providers are responsible for defining and implementing data sources, which present read-only views of pre-existing data or compute new values on the fly.

Common data sources for Terraform include `triton_image` and `triton_network`. Below is an example of data sources which refer to Terraform variables.

```
data "triton_image" "my_image" {
  name        = "${var.image_name}"
  version     = "${var.image_version}"
  type        = "${var.image_type}"
  most_recent = true
}

data "triton_network" "service_networks" {
  count = "${length(var.service_networks)}"
  name  = "${element(var.service_networks, count.index)}"
}
```

#### [Define resources](/api/hashicorp/manage-infrastructure-with-terraform#define-resources) <a href="#define-resources" id="define-resources"></a>

[**Resource**](https://www.terraform.io/docs/configuration/resources.html) blocks define components of your infrastructure. This could be a VM or container on Triton, or it could be an email provider, DNS record, or database provider.

Below us an example using variables and data sources to build a Triton machine:

```
resource "triton_machine" "my_new_machine" {
  name     = "my_new_application"
  package  = "${var.package_name}"
  image    = "${data.triton_image.my_image.id}"
  networks = ["${data.triton_network.service_networks.*.id}"]
  cns {
    services = ["${var.service_name}"]
  }
}
```

Let's break down this block further:

* The **name** of our container will be `my_new_application`
* The **package** assigned to our container is `g4-highcpu-128M`
* The **image** uses the ID of the previously defined data source, `my_image`
* The **networks** include the IDs taken from the data source `service_networks`
* We've added **tags** for Triton CNS, so our DNS names will start with our Triton CNS service name

#### [Add outputs for Terraform data](/api/hashicorp/manage-infrastructure-with-terraform#add-outputs-for-terraform-data) <a href="#add-outputs-for-terraform-data" id="add-outputs-for-terraform-data"></a>

Terraform creates and stores attribute values for all created resources. Not all of this information may be immediately valuable. Some may have immediate importance such as IP addresses or domain names. [**Outputs**](https://www.terraform.io/intro/getting-started/outputs.html) are a way for Terraform to query and display the necessary values after implementing application infrastructure.

Here are some examples for getting the `primaryIP` address and Triton CNS powered domain names:

```
output "primaryIp" {
  value = ["${triton_machine.my_new_machine.*.primaryip}"]
}

output "dns_names" {
  value = ["${triton_machine.my_new_machine.*.domain_names}"]
}
```

### [Download the Terraform provider](/api/hashicorp/manage-infrastructure-with-terraform#download-the-terraform-provider) <a href="#download-the-terraform-provider" id="download-the-terraform-provider"></a>

Downloading the Terraform provider is a critical step in determining how Terraform will work going forward. Execute `terraform init` to download the Triton provider in the background into the local application directory.

```
   $ terraform init

   Initializing provider plugins...
   - Checking for available provider plugins on https://releases.hashicorp.com...
   - Downloading plugin for provider "triton" (0.4.1)...

   The following providers do not have any version constraints in configuration,
   so the latest version was installed.

   To prevent automatic upgrades to new major versions that may contain breaking
   changes, it is recommended to add version = "..." constraints to the
   corresponding provider blocks in configuration, with the constraint strings
   suggested below.

   * provider.triton: version = "~> 0.4"

   Terraform has been successfully initialized!

   You may now begin working with Terraform. Try running "terraform plan" to see
   any changes that are required for your infrastructure. All Terraform commands
   should now work.

   If you ever set or change modules or backend configuration for Terraform,
   rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
```

This output informs us that version 0.4 of Triton has been installed. If you require a different version of a provider, you can specify it within the configuration file.

### [Creating, modifying, and updating application infrastructure](/api/hashicorp/manage-infrastructure-with-terraform#creating-modifying-and-updating-application-infrastructure) <a href="#creating-modifying-and-updating-application-infrastructure" id="creating-modifying-and-updating-application-infrastructure"></a>

Below are some important terms going forward.

**Plan**: the plan is the first of two steps required for Terraform to make changes to infrastructure. Using `terraform plan` determines what changes need to be made and outputs what will be done before it's done.

**Apply**: the second of two steps required to make changes to the infrastructure. With `terraform apply`, Terraform communicates with external APIs (i.e. the providers) to make changes.

**State**: the Terraform state is the state of your infrastructure stored from the last time Terraform was run or applied. By default, this is stored in a local file named `terraform.tfstate`.

#### [Planning the application infrastructure](/api/hashicorp/manage-infrastructure-with-terraform#planning-the-application-infrastructure) <a href="#planning-the-application-infrastructure" id="planning-the-application-infrastructure"></a>

Run `terraform plan -out application.plan` to review what Terraform will be building based on your configuration file. The `-out` parameter saves the plan to `applican.plan` to ensure you know exactly what's going to happen when you're ready to deploy.

The result should look similar the following:

```
   $ terraform plan -out application.plan
   Refreshing Terraform state in-memory prior to plan...
   The refreshed state will be used to calculate this plan, but will not be
   persisted to local or remote state storage.

   data.triton_network.service_networks: Refreshing state...
   data.triton_image.my_image: Refreshing state...

   An execution plan has been generated and is shown below.
   Resource actions are indicated with the following symbols:
     + create

   Terraform will perform the following actions:

     + triton_machine.my_new_machine
         id:                   <computed>
         cns.#:                "1"
         cns.0.services.#:     "1"
         cns.0.services.0:     "my-application"
         created:              <computed>
         dataset:              <computed>
         disk:                 <computed>
         domain_names.#:       <computed>
         firewall_enabled:     "false"
         image:                "45dff701-ce98-481d-94d3-ab0e66fbb8b6"
         ips.#:                <computed>
         memory:               <computed>
         name:                 "my_new_application"
         networks.#:           "1"
         networks.0:           "31428241-4878-47d6-9fba-9a8436b596a4"
         nic.#:                <computed>
         package:              "g4-highcpu-128M"
         primaryip:            <computed>
         root_authorized_keys: <computed>
         type:                 <computed>
         updated:              <computed>

   Plan: 1 to add, 0 to change, 0 to destroy.

   This plan was saved to: application.plan

   To perform exactly these actions, run the following command to apply:
       terraform apply "application.plan"
```

If there have been any errors, you may have to go back and modify the configuration file before proceeding.

#### [Applying the Terraform plan](/api/hashicorp/manage-infrastructure-with-terraform#applying-the-terraform-plan) <a href="#applying-the-terraform-plan" id="applying-the-terraform-plan"></a>

Once you know *what* Terraform will do, use `terraform apply` to build your infrastructure.

```
$ terraform apply application.plan
```

If you've included outputs in your configuration file, you will see those at the end.

### [Community and support](/api/hashicorp/manage-infrastructure-with-terraform#community-and-support) <a href="#community-and-support" id="community-and-support"></a>

* The Terraform [mailing list](https://groups.google.com/group/terraform-tool) and IRC channel (`#terraform-tool` on Freenode) are great for general questions about Terraform.
* The sdc-discuss mailing list is a great starting point for questions about how to use and manage Triton, including with Terraform: [Subscribe](https://www.listbox.com/subscribe/?list_id=247449), [archives](https://www.listbox.com/member/archive/247449/=now).

We have several demos available on Joyent's blog for using Terraform.

* Step-by-step walkthrough [building simple application infrastructure](https://www.joyent.com/blog/video-simple-terraform-app)
* [Blue-green deployment with Terraform](https://www.joyent.com/blog/blue-green-deploys-with-terraform)
* [Deploy to multiple data centers](https://www.joyent.com/blog/multiple-data-centers-with-terraform)


# Container Monitor with Prometheus

## Container Monitor with Prometheus

Container Monitor is a Prometheus-compatible interface to performance metrics for all your instances on Triton.

Container Monitor allows you to use the Prometheus-compatible ecosystem of monitoring solutions to visualize the status of your applications and track alerts for your performance thresholds. Learn more about Prometheus, an open source application that can read Container Monitor metrics, at [prometheus.io](http://prometheus.io/).

Any solution that can read a [prometheus-compatible metrics exporter](https://prometheus.io/docs/instrumenting/exporters/) can use Container Monitor, but the following configuration documentation is written for Prometheus itself.

### [Authentication](/api/container-monitor-with-prometheus#authentication) <a href="#authentication" id="authentication"></a>

If you haven't already, [add an SSH key to your Triton account](/getting-started). You can choose to upload a key or we'll make one for you. This key is used to authenticate you with all of your account's containers and Joyent's APIs, including Container Monitor. Container Monitor uses this key to identify and authenticate your access to the Container Monitor interfaces.

### [Configuration](/api/container-monitor-with-prometheus#configuration) <a href="#configuration" id="configuration"></a>

Container Monitor exposes a metrics endpoint for every instance in your account. Rather than manually configuring (and reconfiguring) Prometheus for every instance, you can use the [Triton service discovery configuration in Prometheus](https://prometheus.io/docs/operating/configuration/#%3Ctriton_sd_config%3E) to automate it.

The Triton configuration block in the `prometheus.yml` file looks like the following:

```
  - job_name: 'triton'
    scheme: https

    triton_sd_configs:
        # The account username to use for discovering new target containers
        - account: <string>

          # The API is versioned, the current version is "1"
          version: 1

          # The DNS suffix which should be applied to target containers
          # For Triton Public Cloud, this is cmon.<data center name>.triton.zone (example: cmon.us-sw-1.triton.zone)
          dns_suffix: <string>

          # The Triton discovery endpoint
          # For Triton Public Cloud, this is cmon.<data center name>.triton.zone (the same value as dns_suffix)
          endpoint: <string>

          # TLS configuration.
          tls_config:
            ca_file: '<path to the CA file>'
            cert_file: '<path to the cert file>'
            key_file: '<path to the key file>'
            insecure_skip_verify: true

    relabel_configs:
      - source_labels: [__meta_triton_machine_alias]
        target_label: instance
```

You must also enable [Triton CNS](broken://pages/-LuID4a5KZimfgOxWIjZ) in order to use Container Monitor. All new containers will get a Container Monitor CNAME record automatically. Similarly, proxy records will be added and removed when proxies come and go, along with corresponding CNAME records.

Each CNAME record represents a virtual Prometheus endpoint backed by a proxy.

To retrieve containers that can be scraped by a Prometheus server for metrics:

```
$ triton inst get <container>
```

For users running pre-existing Prometheus servers, the suggested service discovery mechanism will be leveraging [file based service discovery](https://prometheus.io/docs/operating/configuration/#%3Cfile_sd_config%3E) in conjunction with our [Prometheus Autopilot Pattern](https://github.com/autopilotpattern/prometheus). That way the servers will have an equivalent experience to CloudAPI-based discovery without having to upgrade their Prometheus installation.

### [Available metrics](/api/container-monitor-with-prometheus#available-metrics) <a href="#available-metrics" id="available-metrics"></a>

There are several metrics with a singular endpoint to learn more about your containers:

* `cpu_user_usage`: User CPU utilization in nanoseconds
* `cpu_sys_usage`: System CPU usage in nanoseconds
* `cpu_wait_time`: CPU wait time in nanoseconds
* `load_average`: Load average
* `mem_agg_usage`: Aggregate memory usage in bytes
* `mem_limit`: Memory limit in bytes
* `mem_swap`: Swap in bytes
* `mem_swap_limit`: Swap limit in bytes
* `mem_anon_alloc_fail`: Anonymous allocation failure count
* `net_agg_packets_in`: Aggregate inbound packets
* `net_agg_packets_out`: Aggregate outbound packets
* `net_agg_bytes_in`: Aggregate inbound bytes
* `net_agg_bytes_out`: Aggregate outbound bytes
* `tcp_failed_connection_attempt_count`: Failed TCP connection attempts
* `tcp_retransmitted_segment_count`: Retransmitted TCP segments
* `tcp_duplicate_ack_count`: Duplicate TCP ACK count
* `tcp_listen_drop_count`: TCP listen drops. Connection refused because backlog full
* `tcp_listen_drop_Qzero_count`: Total # of connections refused due to half-open queue (q0) full
* `tcp_half_open_drop_count`: TCP connection dropped from a full half-open queue
* `tcp_retransmit_timeout_drop_count`: TCP connection dropped due to retransmit timeout
* `tcp_active_open_count`: TCP active open connections
* `tcp_passive_open_count`: TCP passive open connections
* `tcp_current_established_connections_total`: TCP total established connections
* `vfs_bytes_read_count`: VFS number of bytes read
* `vfs_bytes_written_count`: VFS number of bytes written
* `vfs_read_operation_count`: VFS number of read operations
* `vfs_write_operation_count`: VFS number of write operations
* `vfs_wait_time_count`: VFS cumulative wait (pre-service) time
* `vfs_wait_length_time_count`: VFS cumulative wait length\*time product
* `vfs_run_time_count`: VFS cumulative run (pre-service) time
* `vfs_run_length_time_count`: VFS cumulative run length\*time product
* `vfs_elements_wait_state`: VFS number of elements in wait state
* `vfs_elements_run_state`: VFS number of elements in run state
* `zfs_used`: zfs space used in bytes
* `zfs_available`: zfs space available in bytes
* `time_of_day`: System time in seconds since epoch


# Network

MNX built-in networking offers each container one or more network interfaces, so each container has a full IP stack and is a full peer on the network, making network management easy. Additionally, MNX provides the ability to create and manage:

* [Firewall rules](/network/firewall)
* [VLANs](/network/triton-networking-and-fabric-user-guide#vlans)
* [IPv4 networks](/network/triton-networking-and-fabric-user-guide#ip-networks)
* [Internet gateways](/network/triton-networking-and-fabric-user-guide#internet-gateways)
* DNS

To learn more about networking on MNX, [read the FAQs](/network/frequently-asked-questions).


# Networking and fabric user guide

## &#x20;Networking and fabric user guide

This document introduces and covers topics in the use of networking and fabrics in MNX.&#x20;

At the heart of any instance is its ability to communicate with other instances in a given data center and the broader Internet. Designing and customizing your network topology is an important part of planning and operating your infrastructure.

### [Fabrics](/network/triton-networking-and-fabric-user-guide#fabrics) <a href="#fabrics" id="fabrics"></a>

In every MNX data center, your account has access to a `fabric`. The fabric is a logical set of interconnected switches -- just like the switching fabric that powers a data center network. In MNX, the fabric is an isolated blank slate on which you can build:

* VLANs
* IPv4 Networks
* Internet Gateways

Anything built on top of a fabric is always *private* to a customer. This means that traffic generated by one customer cannot be seen by another customer -- it's only ever visible to the containers and VMs on your VLANs and networks. This allows for truly *private* networks in the data center. In addition, it allows for different sets of containers and VMs to be completely isolated from one another from a networking perspective.

### [VLANs](/network/triton-networking-and-fabric-user-guide#vlans) <a href="#vlans" id="vlans"></a>

VLANs, also known as IEEE 802.11Q, provide a low level way to segregate and subdivide the network. Traffic on one VLAN cannot, on its own, reach another VLAN.

VLANs are specified by a unique integer ID that ranges from 0-4095. Not all networks necessarily have a VLAN. For example, most home networks, don't use VLANs, while corporate and data center networks do. VLAN 0 is used to refer to a network without such a tag and is equivalent to traditional networks.

In MNX, an account has VLAN 2 automatically created in each data center. Additional VLANs can be created and destroyed through CloudAPI.

For more background on VLANs, see the [wikipedia article](http://en.wikipedia.org/wiki/Virtual_LAN).

### [IP Networks](/network/triton-networking-and-fabric-user-guide#ip-networks) <a href="#ip-networks" id="ip-networks"></a>

An IP network is the basic building block of your infrastructure. By default, all machines in the same IP network can talk to one another. Machines in different IP networks cannot talk to one another unless something has been set up to route between the networks which involves the router having an address on both networks.

IP networks come in two flavors: [IPv4](http://en.wikipedia.org/wiki/IPv4) and [IPv6](http://en.wikipedia.org/wiki/IPv6). Currently, only IPv4 networks are supported in MNX.

An IPv4 address is a series of four numbers that range from 0 to 255 and are commonly written out, separated with `.` characters. For example, `10.100.23.4` and `192.168.1.1` are both valid IP addresses. IP networks, collections of IP addresses that can talk to each other, are described in blocks called [CIDR blocks](http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing), also known as subnets. Sample subnets include `192.168.1.0/24`, `10.1.0.0/16`, and `172.16.128.0/23`.

On a fabric, you can create any IPv4 networks you'd like, making subnetworks based on the [RFC 1918](http://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces) addresses -- `10.0.0.0/8`, `192.168.0.0/16`, and `172.16.0.0/12`.&#x20;

### [Internet Gateways](/network/triton-networking-and-fabric-user-guide#internet-gateways) <a href="#internet-gateways" id="internet-gateways"></a>

A network on a fabric cannot talk to any other network on a fabric, including ones that exist between two customers. However, while a private network is desirable, many times the ability to still reach the broader Internet is desirable for the purposes of being able to install security updates or send alerts.

To facilitate this, networks are created with an Internet gateway by default. This Internet gateways allows instances on a network that don't have a public IP address to still be able to reach the Internet and initiate connection to it. It does not allow for the Internet to initiate connections back to the machine and is not suitable for running a public facing service. Instead, a public IP address should be assigned to the instance.

For IPv4 networks, this functionality is provided using [Network Address Translation (NAT)](http://en.wikipedia.org/wiki/Network_Address_Translation).


# Firewall

## Firewall

MNX.io firewall rules enable you to secure instances by defining network traffic rules to control inbound and outbound connections.  You can enable, define, and edit firewall rules by using [Triton CLI](/network/firewall#creating-and-managing-firewall-rules-using-triton).

{% hint style="info" %}
By default, firewall rules are **not** automatically enabled on new instances provisioned with CloudAPI.
{% endhint %}

This page covers firewall rule basics. Read the [firewall rules reference document](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#priority) for details on how to create rules and read the [firewall rule examples](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-examples) for sample use cases.

**NOTE**: Firewall rules are automatically created and enabled for Docker containers based on the exposed port specifications in the Dockerfile. For more information, see the [Optimizing Docker operations for Triton blog post](https://www.joyent.com/blog/optimizing-docker-on-triton), [Docker API documentation](https://apidocs.joyent.com/docker/features/networks), and [networking FAQs](/network/frequently-asked-questions).

### [Default firewall policy](/network/firewall#default-firewall-policy) <a href="#default-firewall-policy" id="default-firewall-policy"></a>

Without a firewall enabled, each instance allows all inbound and all outbound traffic. When firewall rules are enabled, three default rules apply:

* **Block all inbound traffic**. This rule blocks traffic from any source to all instances.
* **Allow all outbound traffic**. This rule allows traffic from any instance through to any destination.
* **Allow ICMP type 8 code 0**. This rule enables you to ping an instance.

### [Rule syntax](/network/firewall#rule-syntax) <a href="#rule-syntax" id="rule-syntax"></a>

Getting familiar with the rule syntax ensures that you create rules that apply as you expect. Triton firewall rules have the following syntax:

```
FROM <target a> TO <target b> <action> <protocol> <port>
```

You can associate rules with instances (or instances with rules) using target criteria such as tags, instance IDs, or the `ALL VMS` keyword. Target criteria include:

* Instances
* IP addresses
* TCP, UDP, or ICMP, ESP, and AH ports
* [Tags](https://docs.joyent.com/public-cloud/tags-metadata/tags)
* Subnets
* All VMs in a data center

The [Firewall Rules Reference](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#target_list) document describes firewall rule syntax in more detail.

The words `FROM`, `TO`, and the action name (such as `ALLOW` or `BLOCK`) do not have to be capitalized when creating a new rule. Triton will automatically normalize and update the syntax once created.=

#### [List instances command](/network/firewall#list-instances-command) <a href="#list-instances-command" id="list-instances-command"></a>

To see a list of triton instances, run `triton instance list`. The output lists the instances for your account and enables you to obtain the `SHORTID` and `NAME`.

```
$ triton instance list
SHORTID   NAME      IMG                    STATE    FLAGS  AGE
3a1f3346  3a1f3346  base-64@17.3.0         running  F      11w
1009d417  1009d417  standard@15.1.1        running  -      11w
c85da785  server2   ubuntu-14.04@20170403  running  -      11w
4f3a2681  server-1  ubuntu-14.04@20170403  running  -      6w
```

The `FLAGS` column indicates the firewall rule status. `F` indicates an enabled status. If there are no flags, the firewall rules for the instance are disabled.

#### [Instance details command](/network/firewall#instance-details-command) <a href="#instance-details-command" id="instance-details-command"></a>

To find the full `UUID` for an instance, run the command `triton instance get <instance>` where `<instance>` is the `SHORTID` or `NAME` of the instance. This example shows the JSON payload (output) for `server-1`, which contains the `UUID` as `"id"` and other details.

```
$ triton instance get server-1
{
    "id": "4f3a2681-a9e9-c2bc-e64f-da5c57950a8e",
    "name": "server-1",
    "type": "smartmachine",
    "brand": "lx",
    "state": "running",
    "image": "04179d8e-188a-11e7-af4a-1349e98cbd17",
    "ips": [
        "64.30.129.97",
        "192.168.27.167"
    ],
    [...]
}
```

#### [Create firewall rules command](/network/firewall#create-firewall-rules-command) <a href="#create-firewall-rules-command" id="create-firewall-rules-command"></a>

To create a firewall rule, run `triton fwrule create` with the appropriate rule syntax. For example:

```
$ triton fwrule create "FROM any TO tag www ALLOW tcp (port 80 and port 443)"
Created firewall rule f5653bef-2e91-4c07-a1a5-2f5fc81aeaf3
```

When you create a rule using `triton`, it is automatically granted an enabled status. You have the option to create rules in a disabled status and enable them at another time to better control when rules are put into effect.

To create rules in a disabled status, run `triton fwrule create` with the `-d` flag:

```
$ triton fwrule create -d "FROM any TO all vms ALLOW tcp PORT 22"
Created firewall rule 93cbb439-b539-4b4e-b809-966394630ff6 (disabled)
```

#### [Enable firewall rules command](/network/firewall#enable-firewall-rules-command) <a href="#enable-firewall-rules-command" id="enable-firewall-rules-command"></a>

The command to enable firewall rules for an instance is `triton instance enable-firewall <instance>` where `<instance>` is the `UUID`, `SHORTID`, or `NAME`.

For example:

```
$ triton instance enable-firewall server-1
Enabling firewall for instance "server-1"
```

If you run `triton instance list`, the output shows the `F` flag indicating that firewall rules are enabled for `server-1`.

```
$ triton instance list
SHORTID   NAME      IMG                    STATE    FLAGS  AGE
3a1f3346  3a1f3346  base-64@17.3.0         running  F      11w
1009d417  1009d417  standard@15.1.1        running  -      11w
c85da785  server2   ubuntu-14.04@20170403  running  -      11w
4f3a2681  server-1  ubuntu-14.04@20170403  running  F      6w
```

To create a rule that allows you to log into your machines using SSH, run:

```
$ triton fwrule create "FROM any TO all vms ALLOW tcp PORT 22"
Created firewall rule 3a1f3346-b700-4032-f86c-ea3173eedf8a
```

#### [Disable firewall command](/network/firewall#disable-firewall-command) <a href="#disable-firewall-command" id="disable-firewall-command"></a>

The command to disable firewall rules for an instance is `triton instance disable-firewall <instance>` where `<instance>` is the `UUID`, `SHORTID`, or `NAME`.

You can define a rule, disable it, and then enable it when you are ready to implement it. You can also disable active firewall rules.

To disable firewall rules using the instance name:

```
$ triton instance disable-firewall server-1
Disabling firewall for instance "server-1"
```

You can disable a specific rule using the firewall rule ID, which you can obtain with `triton fwrules -l`.

To disable a currently active rule, run `triton fwrule disable <FWRULE-ID>`.

```
$ triton fwrule disable 037740ed-fe54-4ff6-8507-a1896571415c
Created firewall rule 037740ed-fe54-4ff6-8507-a1896571415c (disabled)
```

#### [List all rules commands](/network/firewall#list-all-rules-commands) <a href="#list-all-rules-commands" id="list-all-rules-commands"></a>

You can list firewall rules to help manage what rules you have and how they apply. Firewall rules are assigned a unique ID on creation, `FWRULE-ID`, which you reference in the commands run to manage your firewall rules.

To list rules to obtain the `FWRULE-ID`, run:

```
$ triton fwrules -l
ID                                    ENABLED  GLOBAL  RULE
680a5224-fde8-4e08-b251-95d696dbc0f5  true     -       FROM any TO all vms ALLOW tcp PORT 22
b9c25d17-ecef-4ee1-8931-09c26e847606  true     -       FROM subnet 172.16.0.0/24 TO all vms ALLOW tcp PORT all
47e8a50b-1fb7-4147-a42a-3aa8768086a3  true     -       FROM tag "sdc_docker" TO tag "sdc_docker" ALLOW tcp PORT all
3535e168-5a34-406f-bce3-d39c59d9736c  true     -       FROM tag "sdc_docker" TO tag "sdc_docker" ALLOW udp PORT all
8197c46e-f731-4090-8543-c1584b64fd4b  false    -       FROM vm c85da785-6310-44a8-e95b-f0a97afa57be TO all vms ALLOW tcp PORT all
```

The `triton fwrule list` command lists also displays all of the rules associated with your account, organized by `SHORTID`.

#### [List all rules for an instance command](/network/firewall#list-all-rules-for-an-instance-command) <a href="#list-all-rules-for-an-instance-command" id="list-all-rules-for-an-instance-command"></a>

The `triton instance fwrules <instance>` command lists all rules that have been defined for a specific instance.

To list the firewall rules that apply to an instance:

```
$ triton instance fwrules 98338d48-d2a7-4e17-bbc7-b44054b04503
SHORTID                               ENABLED  GLOBAL  RULE
3473327e-6d0c-4747-97c5-ced1260a7e42  true     true    FROM any TO all vms ALLOW icmp TYPE 8 CODE 0
58dfcdf6-0a39-494a-8856-ff3169806954  true     -       FROM all vms TO all vms ALLOW tcp PORT all
4ecbc8ee-6621-4b68-b659-e9e631129480  true     -       FROM any TO vm 98338d48-d2a7-4e17-bbc7-b44054b04503 ALLOW tcp PORT 22
```

Refer to the [Firewall Rules Reference](https://docs.joyent.com/network/firewall/cloud-firewall-rules-reference#firewall-rule-commands) document for the complete list of firewall rule commands.

#### [Update rules command](/network/firewall#update-rules-command) <a href="#update-rules-command" id="update-rules-command"></a>

To edit a firewall rule, use the `triton fwrule update` command. Note that you must specify the entire rule, not just the part that you're changing.

```
$ triton fwrule update 037740ed-fe54-4ff6-8507-a1896571415c rule="FROM all vms TO tag db ALLOW tcp port 5432"
Updated firewall rule 037740ed-fe54-4ff6-8507-a1896571415c (fields: rule)
```

#### [Delete rules command](/network/firewall#delete-rules-command) <a href="#delete-rules-command" id="delete-rules-command"></a>

To delete a firewall rule, use the `triton fwrule delete` command. Note that this command does not produce any output if it is successful.

```
$ triton fwrule delete 037740ed-fe54-4ff6-8507-a1896571415c
Delete firewall rule "037740ed-fe54-4ff6-8507-a1896571415c"? [y/n] y
Deleted rule 037740ed-fe54-4ff6-8507-a1896571415c
$ triton fwrule delete 037740ed-fe54-4ff6-8507-a1896571415c
Delete firewall rule "037740ed-fe54-4ff6-8507-a1896571415c"? [y/n] y
triton fwrule delete: error: first of 1 error: Rule not found
```

### [Rule precedence](/network/firewall#rule-precedence) <a href="#rule-precedence" id="rule-precedence"></a>

The default firewall rules have a [priority level of 0](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#priority), which means that the firewall rules you define always take precedence over the default rules. In general, rules are not evaluated in order but by how restrictive they are.

* **Inbound**: For incoming traffic, the *least* restrictive rule wins. The default rules for incoming traffic block everything, so any rule that allows incoming traffic is less restrictive.
* **Outbound**: For outgoing traffic, the *most* restrictive rule takes precedence. The default rules for outgoing traffic allow everything, so any rule that blocks outgoing traffic is more restrictive.

You can prioritize firewall rules to define the order in which rules should apply. The [Firewall Rules Reference document](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#priority) describes how to set priority levels.

### [Frequently asked questions](/network/firewall#frequently-asked-questions) <a href="#frequently-asked-questions" id="frequently-asked-questions"></a>

This section answers some questions you may have about Triton firewall rules.

#### [What is the relationship between Triton's firewall rules and IPFilter?](/network/firewall#what-is-the-relationship-between-tritons-firewall-rules-and-ipfilter) <a href="#what-is-the-relationship-between-tritons-firewall-rules-and-ipfilter" id="what-is-the-relationship-between-tritons-firewall-rules-and-ipfilter"></a>

Triton's firewall rules apply to all the instances in the same data center that have the firewall feature enabled. IPFilter rules apply only to the instance in which they are defined.

For incoming traffic, the firewall rules set with Triton are applied first. If an instance has IPFilter rules, they are applied next.

```
                  +----------+         +----------+
                  | Cloud    |         | instance |
  Internet ------>| Firewall +-------->| IPFilter +------> instance
                  | Rules    |         | rules    |
                  +----------+         +----------+
```

For outgoing traffic, any IPFilter rules defined for the instance apply first and then the Triton firewall rules are applied.

```
                  +----------+         +----------+
                  | Cloud    |         | instance |
  Internet <------+ Firewall |<--------+ IPFilter |<------ instance
                  | Rules    |         | rules    |
                  +----------+         +----------+
```


# Firewall rules reference

## Firewall rules reference

Firewall rules apply to all instances in the same data center that have the firewall feature enabled. This document covers the following firewall rule topics:

* [Default rules](/network/firewall-rules-reference#the-default-rules)
* [Rule commands](/network/firewall-rules-reference#firewall-rule-commands)
* [Rule syntax](/network/firewall-rules-reference#basic-rule-syntax)
* [Priority](/network/firewall-rules-reference#priority)
* [Rule examples](/network/firewall-rules-reference#rule-examples)
* [Rules which result in errors](/network/firewall-rules-reference#rules-which-result-in-errors)

### The default rules <a href="#the-default-rules" id="the-default-rules"></a>

By default, when an instance is provisioned, the firewall is disabled. It must be enabled explicitly, either at provision-time or after an instance has been provisioned. If it is not enabled, all traffic is permitted, both inbound and outbound.

When firewall rules are enabled, the default rules apply. These rules block all incoming traffic and allow all outgoing traffic as follows:

* FROM any TO all vms BLOCK TCP PORT all
* FROM any TO all vms BLOCK UDP PORT all
* FROM any TO all vms BLOCK ICMP (TYPE 0 AND TYPE 1 AND ... TYPE 255)
* FROM all vms TO any ALLOW TCP PORT all
* FROM all vms TO any ALLOW UDP PORT all
* FROM any TO all vms ALLOW ICMP TYPE 8 CODE 0

Traffic to ICMP type 8 code 0 (ping) is always allowed.

Since the default behavior for inbound connections is to block everything and the outbound connections is to allow everything, rules must be added to specify inbound and outbound network connections.

### [Firewall rule commands](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#firewall-rule-commands) <a href="#firewall-rule-commands" id="firewall-rule-commands"></a>

The following table lists firewall commands and their corresponding actions:

| Command                                              | Function                                                                                                         |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `triton fwrule create <RULE>`                        | Adds a new firewall rule for the specified account. New rules have a unique rule ID and are in an enabled state. |
| `triton fwrule enable <FWRULE-ID>`                   | Enables the given firewall rule if it is disabled.                                                               |
| `triton fwrule disable <FWRULE-ID>`                  | Disables the given firewall rule if it is enabled.                                                               |
| `triton fwrule update <FWRULE-ID> <FIELD=VALUE ...>` | Updates the given rule record by adding/removing/updating the rule on all the required instances.                |
| `triton fwrule delete <FWRULE-ID>`                   | Removes the given firewall rule from all specified instances.                                                    |
| `triton fwrule list`                                 | Lists all firewall rules for the current account.                                                                |
| `triton fwrule get <FWRULE-ID>`                      | Retrieves an individual firewall rule.                                                                           |
| `triton fwrule instances <FWRULE-ID>`                | Lists all instances a firewall rule is applied to.                                                               |
| `triton instance fwrules <instance>`                 | Lists all firewall rules applied to a specified instance.                                                        |

#### [Rule components](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#rule-components) <a href="#rule-components" id="rule-components"></a>

Rules are created with several different components:

* **rule**: The firewall rule. Required.
* **enabled**: The firewall status. If set to true, the rule is applied to VMs. If set to false, the rule is added but not applied. Optional, boolean.
* **description**: A description of what this rule is for. Optional, string.

There is also a `global` property on predefined rules which apply to all VMs in the data center. (You can use priorities to override the effects of these rules.)

### [Basic rule syntax](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#basic-rule-syntax) <a href="#basic-rule-syntax" id="basic-rule-syntax"></a>

Triton firewall rules have the following syntax:

```
FROM <target a> TO <target b> <action> <protocol> <port>
```

#### [Valid values](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#valid-values) <a href="#valid-values" id="valid-values"></a>

This table describes the valid values for each parameter:

| Parameter  | Description                          | Argument                                   |
| ---------- | ------------------------------------ | ------------------------------------------ |
| `target`   | A list of sources and destinations   | any, ip, subnet, tag, all vms, or instance |
| `action`   | Describes the rule behavior          | allow or block                             |
| `protocol` | Specifies what ports or types to use | TCP, UDP, ICMP, ESP, AH                    |
| `port`     | Specifies the port number            | a valid port number                        |

#### [Parameter limits](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#parameter-limits) <a href="#parameter-limits" id="parameter-limits"></a>

The limits for the parameters are:

* 24 from targets
* 24 to targets
* 8 ports or types

#### [Targets](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#targets) <a href="#targets" id="targets"></a>

Targets are FROM sources and TO destinations that use the following syntax:

#### [Target types](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#target-types) <a href="#target-types" id="target-types"></a>

**FROM** targets and **TO** targets can be any of the following types:

| Target                   | Description                                                                                                                           |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `ANY`                    | Any machine anywhere on the Internet                                                                                                  |
| `ALL VMS`                | All instances in a data center that have Triton's firewall feature enabled.                                                           |
| `IP ADDRESS`             | An IPv4 or IPv6 address: nnn.nnn.nnn.nnn                                                                                              |
| `SUBNET CIDR`            | A specified IPv4 or IPv6 subnet range                                                                                                 |
| `tag_string`             | Any instance in a data center that has Triton's firewall feature enabled and that has the tag `tag_string`                            |
| `tag_string = tag_value` | Any instance in a data center that has Triton's firewall feature enabled and that has the tag `tag_string` with the value `tag_value` |
| `UUID`                   | An instance with the specified UUID. The instance must be in the specified data center and have Triton's firewall feature enabled.    |

#### [Target type examples](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#target-type-examples) <a href="#target-type-examples" id="target-type-examples"></a>

To allow HTTPS traffic from any machine on the Internet to all instances in a data center:

```
FROM any TO all vms ALLOW tcp port 80
```

To allow SSH traffic between all instances in a data center:

```
FROM all vms TO all vms ALLOW tcp port 22
```

To allow HTTP traffic from any host to VM:

```
FROM any to vm 04128191-d2cb-43fc-a970-e4deefe970d8 ALLOW tcp port 80
```

To block SMTP traffic to a specific IPv4 or IPv6 address:

```
FROM all vms to (ip 10.2.0.1 OR ip fd22::1234) BLOCK tcp port 25
```

To allow HTTPS traffic from a specific IPv4 subnet to a specific VM:

```
FROM subnet 10.8.0.0/16 TO vm 0f570678-c007-4610-a2c0-bbfcaab9f4e6 ALLOW tcp port 443
```

And to allow HTTPS traffic from a specific IPv6 subnet to the same VM, you can do:

```
FROM subnet fd22::/64 TO vm 0f570678-c007-4610-a2c0-bbfcaab9f4e6 ALLOW tcp port 443
```

#### [Target lists](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#target-lists) <a href="#target-lists" id="target-lists"></a>

The `vm`, `ip`, `subnet`, and `tag` target types can be combined into a list surrounded by parentheses and joined by `OR`, such as:

```
( <target> OR <target> OR ... )
```

#### [Target list examples](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#target-list-examples) <a href="#target-list-examples" id="target-list-examples"></a>

To block HTTPS traffic to an internal subnet and IP:

```
FROM (vm 163dcedb-828d-43c9-b076-625423250ee2 OR tag db) TO (subnet 10.2.2.0/24 OR ip 10.3.0.1) BLOCK tcp port 443
```

#### [Action](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#action) <a href="#action" id="action"></a>

Actions can `ALLOW` or `BLOCK` network traffic.

| Term    | Meaning              |
| ------- | -------------------- |
| `ALLOW` | Allow traffic        |
| `BLOCK` | Do not allow traffic |

Note that certain combinations of actions and directions have no effect.

Since the default policy blocks all incoming ports, this rule example has no effect on any instance:

```
FROM any TO all vms BLOCK tcp port 143
```

Since the default policy allows all outbound traffic, this rule example has no effect on any instance:

```
FROM all vms TO any ALLOW tcp port 25
```

#### [Protocol](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#protocol) <a href="#protocol" id="protocol"></a>

The protocol can be one of `tcp`, `udp`, `icmp(6)`,`ah`, or `esp`. The protocol dictates whether ports or types can be used.

```
protocol ::= 'TCP' port_list
           | 'UDP' port_list
           | 'ICMP' type_list
```

| Term             | Meaning                                                |
| ---------------- | ------------------------------------------------------ |
| TCP `port_list`  | Rule applies to TCP traffic for given ports.           |
| UDP `port_list`  | Rule applies to UDP traffic for given ports            |
| ICMP `type_list` | Rule refers to ICMP traffic for given types and codes. |

For TCP and UDP, this specifies the port numbers that the rule applies to. Port numbers must be between 1 and 65535, inclusive.

For ICMP, this specifies the ICMP type and optional code that the rule applies to. Types and codes must be between 0 and 255, inclusive.

#### [Ports](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#ports) <a href="#ports" id="ports"></a>

For TCP and UDP, port specifies the port numbers that the rule applies to.

* Port numbers must be between 1 and 65535, inclusive.
* Ranges are written as two port numbers separated by a `-` (hyphen), with the lower number coming first, with optional spaces around the hyphen.
* Port ranges are inclusive, so using the range `20 - 22` would cause the rule to apply to the ports 20, 21 and 22.

#### [Port examples](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#port-examples) <a href="#port-examples" id="port-examples"></a>

To allow HTTP and HTTPS traffic from any IP to all web servers:

```
FROM tag www TO any ALLOW TCP (port 80 AND port 443)
```

To allow pinging all instances in a data center. This is a default rule:

```
FROM any TO all vms ALLOW icmp TYPE 8 CODE 0
```

To block outgoing ping replies from all instances in data center:

```
FROM all vms TO any BLOCK icmp TYPE 0
```

To allow UDP traffic from any IP to all tagged mosh servers:

```
FROM any TO tag mosh ALLOW udp PORTS 60000 - 61000
```

To allow TCP traffic from any web server to all tagged API servers:

```
FROM tag www TO tag api ALLOW tcp PORTS 10000 - 50000
```

#### ICMP types <a href="#icmp-types" id="icmp-types"></a>

ICMP specifies the ICMP type and optional code that the rule applies to. Types and codes must be between 0 and 255, inclusive.

To allow pinging all VMs:

```
FROM any TO all vms ALLOW icmp TYPE 8 CODE 0
```

The IPv6 equivalent of this rule is:

```
FROM any TO all vms ALLOW icmp6 TYPE 128 CODE 0
```

To block outgoing replies:

```
FROM all vms TO any BLOCK icmp TYPE 0
FROM all vms TO any BLOCK icmp6 TYPE 129
```

### Priority <a href="#priority" id="priority"></a>

Specifying a priority for a rule allows defining its relation with other rules. By default, a rule has a priority level of 0, the lowest priority. Rules with a higher priority will be used before ones with a lower priority. The highest level that can be specified is 100.

The syntax for priority level is:

```
priority <level>
```

#### Priority examples: <a href="#priority-examples" id="priority-examples"></a>

To allow traffic from anyone but 10.20.30.0/24 to access an MTA:

```
FROM any TO tag mta ALLOW tcp PORT 25
FROM subnet 10.20.30.0/24 TO tag mta BLOCK tcp PORT 25 PRIORITY 1
```

To blocks all outbound traffic, overriding the default outbound policy, except for SSH:

```
FROM all vms TO any BLOCK tcp PORT all
FROM all vms TO any ALLOW tcp PORT 22 PRIORITY 1
```

### [Rule examples](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#rule-examples) <a href="#rule-examples" id="rule-examples"></a>

If you are using the `triton` command line tools, use the `triton fwrule create` command:

```
$ triton fwrule create "FROM any TO tag www ALLOW tcp (port 80 and port 443)"
Created firewall rule 28cabe50-73c8-4443-b499-46ac4de3dc0d
```

New rules are immediately enabled. The command `triton fwrule enable` enables the given firewall rule if it is disabled. Use `triton fwrule disable` to disable a rule.

```
$ triton fwrule enable 28cabe50-73c8-4443-b499-46ac4de3dc0d
Enabled firewall rule 28cabe50-73c8-4443-b499-46ac4de3dc0d
```

#### [Rule example syntax](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#rule-example-syntax) <a href="#rule-example-syntax" id="rule-example-syntax"></a>

Do not allow SMTP (port 25) traffic to an instance with the IP 10.2.0.1 from any of the instances on the same data center that have Triton's firewall feature enabled.

```
FROM all vms TO ip 10.2.0.1 BLOCK tcp port 25
```

To allow HTTPS (port 443) from a private subnet to a specific instance:

```
FROM subnet 10.8.0.0/16 TO vm 0f570678-c007-4610-a2c0-bbfcaab9f4e6 ALLOW tcp port 443
```

To allow syslog (port 514) traffic from any instance in this data center to any instance in this data center that has the tag `syslog`:

```
FROM all vms TO tag syslog ALLOW udp port 514
```

To allow database traffic from databases to web servers. Any other instances with different `role` tags, such as `role = staging` are not affected by this rule:

```
FROM tag role = db TO tag role = www ALLOW tcp port 5432
```

To allow LDAP (port 389) traffic from any instance in this data center to instances with tag `VM type` set to `LDAP server`:

```
FROM all vms TO tag "VM type" = "LDAP server" ALLOW tcp PORT 389
```

To allow only HTTP traffic from any machine on the Internet to a specific instance:

```
FROM any TO vm 04128191-d2cb-43fc-a970-e4deefe970d8 ALLOW tcp port 80
```

#### [Rules which result in errors](https://docs.joyent.com/public-cloud/network/firewall/cloud-firewall-rules-reference#rules-which-result-in-errors) <a href="#rules-which-result-in-errors" id="rules-which-result-in-errors"></a>

Some rules cannot be created because they would not affect any instances in a data center. The following rules would result in a "rule does not affect VMs" error messages:

```
$ triton fwrule create "FROM any TO any ALLOW tcp port 22"
$ triton fwrule create "FROM ip 192.168.1.3 TO subnet 192.168.1.0/24 ALLOW tcp port 22"
```


# Frequently Asked Questions

## Frequently Asked Questions

### [What networks can my instance connect to?](/network/frequently-asked-questions#what-networks-can-my-instance-connect-to) <a href="#what-networks-can-my-instance-connect-to" id="what-networks-can-my-instance-connect-to"></a>

MNX has core features that handle the virtualization and management of layer 2 and layer 3 networks, and both can be broken down in two basic types:

* **Networks defined by the data center operator**. these can be networks that have internet-routable IP ranges (so you can connect your applications to the public internet), or they might have a [private address space](https://en.wikipedia.org/wiki/Private_network) that is not reachable by the public internet. These networks are typically shared by multiple customers (shared layer 2 and 3), but it's also possible for the operator to create truly isolated networks that can be used and accessed by a single user (private layer 2 and 3).
* **Networks defined by the user**. These networks are sometimes called [overlay or VXLAN networks](/network/triton-networking-and-fabric-user-guide), and they are private to the user who creates them. These network fabrics offer a convenient way to create isolated (private layer 2 and 3) networks to securely connect the internal components of your applications. At this time, each user can create up to 1024 different networks, so you can easily create separate networks for each application, and isolate staging instances of the application on their own network separated from production.

Importantly, these networking features are available to all the instance types MNX supports, including Docker containers, infrastructure containers, and hardware VMs.

### [How do I find my IP address(es)?](/network/frequently-asked-questions#how-do-i-find-my-ip-addresses) <a href="#how-do-i-find-my-ip-addresses" id="how-do-i-find-my-ip-addresses"></a>

Each instance, including Docker containers, infrastructure containers, and hardware VMs, gets one or more IP addresses on different networks. You can check the IP address(es) assigned to each instance in a number of different ways:

* [MNX portal](/network/frequently-asked-questions#finding-instance-ip-addresses-using-the-triton-portal)
* [Triton CLI](/network/frequently-asked-questions#finding-instance-ip-addresses-using-triton-cli)
* [Docker](/network/frequently-asked-questions#finding-instance-ip-addresses-using-docker)
* [Inside the instance](/network/frequently-asked-questions#finding-instance-ip-addresses-from-inside-the-instance)

#### [Finding instance IP addresses using the MNX portal](/network/frequently-asked-questions#finding-instance-ip-addresses-using-the-triton-portal) <a href="#finding-instance-ip-addresses-using-the-triton-portal" id="finding-instance-ip-addresses-using-the-triton-portal"></a>

Sign into the [MNX portal](https://portal.mnx.io) → [Compute](https://portal.mnx.io/compute/) where you'll see a full list of all of the containers and VMs you have running on MNX.io.

By clicking on the name of an instance, you’ll see a summary of all of those instance details. In the first section, labeled Network Cards, several pieces of information will appear. Among the data, you can get the instance IP addresses.

#### [Finding instance IP addresses using Triton CLI](/network/frequently-asked-questions#finding-instance-ip-addresses-using-triton-cli) <a href="#finding-instance-ip-addresses-using-triton-cli" id="finding-instance-ip-addresses-using-triton-cli"></a>

The [Triton CLI tool](/api/triton-cli-tool) is a fast and convenient way to mange infrastructure on MNX. You can get a list of your instances with `triton instances` . To get the IP address of your instance using `triton`, run the following command:

```
triton inst ip <instance>
```

This will give you the `primaryIp` address for your instance. On MNX, `primaryIp` is often a public IP address on your instance, but if you didn't request a public IP address (see below for how to request or not public IPs for your instance), it will typically[1](https://docs.mnx.io/network/pages/-LuID4a8VYndpw171ykB#fn:1) be the next most public IP address.

There may be more than one IP listed for your instance in an `ips` array. To get all of these IP addresses and more information about your instance, run:

```
triton instance get <instance>
```

That command will return information about your instance, including the image it is running, instance state, DNS names, and the instance IP(s). It will look something like this:

```
{
    "id": "ea66e367-031b-47c4-8a56-3649becb789f",
    "name": "<instance name>",
    "type": "smartmachine",
    "brand": "lx",
    "state": "running",
    "image": "6e9f2ba8-0ec3-3b9e-86a9-c0b84f0d042a",
    "ips": [
        "192.168.128.30",
        "72.2.114.213"
    ],
   [...]
    "primaryIp": "72.2.114.213"
}
```

If you install [this JSON-parser](https://github.com/trentm/json) with `npm install -g json`, then you can extract the `primaryIP` address from the JSON output, instead of having to read the entire array:

```
triton instance get -j <instance> | json primaryIp
```

You can also get the `primaryIp` address when listing instances. For example:

```
$ triton instances -l
ID                                    NAME   IMG                 BRAND   PACKAGE          STATE    FLAGS  PRIMARYIP       CREATED
40ea080c-8436-4fa3-9048-16b31ab063f0  gloom  base-64-lts@15.4.1  joyent  g4-highcpu-256M  running  -      165.225.151.17  2016-05-16T19:43:58.304Z

$ triton instances -o name,primaryIp
NAME                     PRIMARYIP
wp_nginx_1               165.225.156.123
wp_nginx_2               165.225.156.48
wp_mysql_1
wp_mysql_2
```

#### [Finding instance IP addresses using Docker](/network/frequently-asked-questions#finding-instance-ip-addresses-using-docker) <a href="#finding-instance-ip-addresses-using-docker" id="finding-instance-ip-addresses-using-docker"></a>

It is possible to find your primary IP address for your Docker containers with Docker CLI. You can get your list of containers (to get the `<container>` name or ID) using `triton-docker ps`.

```
triton-docker inspect <container>
```

This will output a large JSON array of information about your Docker container, and the primary IP address will be buried inside `NetworkSettings` → `IPAddress`.

If you want to get just the IP address, this command uses Go to parse out that information:

```
triton-docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container>
```

#### [Finding instance IP addresses from inside the instance](/network/frequently-asked-questions#finding-instance-ip-addresses-from-inside-the-instance) <a href="#finding-instance-ip-addresses-from-inside-the-instance" id="finding-instance-ip-addresses-from-inside-the-instance"></a>

If you're inside an instance, within a shell, you can use either `ifconfig -a` or `ip addr` to show the IP address. The command in use depends on the base OS/distro.

```
eth0      Link encap:Ethernet  HWaddr 90:b8:d0:7d:9f:e5
          inet addr:192.168.128.7  Bcast:192.168.131.255  Mask:255.255.252.0
          inet6 addr: fe80::92b8:d0ff:fe7d:9fe5/10 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:8500  Metric:1
          RX packets:3 errors:0 dropped:0 overruns:0 frame:0
          TX packets:22 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:138 (138.0 B)  TX bytes:1480 (1.4 KB)

eth1      Link encap:Ethernet  HWaddr 90:b8:d0:20:27:06
          inet addr:64.30.128.116  Bcast:64.30.129.255  Mask:255.255.254.0
          inet6 addr: fe80::92b8:d0ff:fe20:2706/10 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:30142 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13926 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:42094996 (42.0 MB)  TX bytes:983433 (983.4 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING MULTICAST  MTU:8232  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
```

In the example above, from `ifconfig -a`, `eth0` is connected to a private overlay network and is best used for internal connections between application components. The `eth1` interface is connected to the public internet with a routable public IP address, `64.30.128.116`.

### [What are NICs and why do I have so many?](/network/frequently-asked-questions#what-are-nics-and-why-do-i-have-so-many) <a href="#what-are-nics-and-why-do-i-have-so-many" id="what-are-nics-and-why-do-i-have-so-many"></a>

Network Interface Controllers (NICs) connect your instances to a computer network. Each of your instances has one or more NICs, each connected to particular networks. This is a key feature of network virtualization and isolation in MNX: the virtual NICs maximize performance, security, and convenience. Docker containers, for example, can be directly connected to the public internet on their own NIC, and you'll never need to worry about port collisions among multiple containers trying to use ports 80 or 443, or other common ports.

Each NIC can give you access to a different network, allowing you to create the exact network topology you need to isolate your applications while still connecting the components.

### [When do I get charged for bandwidth?](/network/frequently-asked-questions#when-do-i-get-charged-for-bandwidth) <a href="#when-do-i-get-charged-for-bandwidth" id="when-do-i-get-charged-for-bandwidth"></a>

We charge bandwidth for interfaces with a public IP address and an external network. So if you have an application and a database which communicate over external interfaces, you will be charged. If those instances communicate over internal interfaces with only private IP addresses, you are not charged.

To determine which interfaces, if any, are public, you'll need your container name or UUID, which you can get from `triton inst ls`. Use that name to get information to get the networks attached to your instance with `triton inst get`.

```
$ triton inst get <instance>
{
    "id": "faa1e2e8-25fc-4579-8257-f99ccfc7b0af",
    "name": "angry_fermi",
    "type": "smartmachine",
    [...]
    "networks": [
        "dcef4216-d34a-44fd-bf83-635172bf9e46",
        "a4294278-a494-4f7d-b5d6-983c70729c58"
    ],
    [...]
}
```

Using the networks' IDs, run `triton network get <network>` to determine if the network is public or private.

```
$ triton network get dcef4216-d34a-44fd-bf83-635172bf9e46
{
    "id": "dcef4216-d34a-44fd-bf83-635172bf9e46",
    "name": "My-Fabric-Network",
    "public": false,
    "fabric": true,
    "gateway": "192.168.128.1",
    "internet_nat": true,
    "provision_end_ip": "192.168.131.250",
    "provision_start_ip": "192.168.128.5",
    "resolvers": [
        "8.8.8.8",
        "8.8.4.4"
    ],
    "subnet": "192.168.128.0/22",
    "vlan_id": 2
}

$ triton network get a4294278-a494-4f7d-b5d6-983c70729c58
{
    "id": "a4294278-a494-4f7d-b5d6-983c70729c58",
    "name": "JoyentSDC-72.2.124.0/22",
    "public": true,
    "description": "JoyentSDC-72.2.124.0/22"
}
```

The first network, `dcef4216-d34a-44fd-bf83-635172bf9e46`, is a private network, while `a4294278-a494-4f7d-b5d6-983c70729c58` is a public network.

Want a shortcut? Find the networks associated with an instance with this one line command:

```
$ triton inst get <instance> | json networks | json -a | xargs -L1 -n1 triton network get
{
    "id": "2065ac74-8d04-4077-8682-7feffb0d7dee",
    "name": "Joyent-SDC-64.30.128.0/23",
    "public": true,
    "description": "Joyent-SDC-Public-Pool-64.30.128.0/23"
}
{
    "id": "43b174ba-03cd-48bb-8fb4-45c0584cfb15",
    "name": "JoyentSDC-192.168.24.0/21",
    "public": false
}
```

**Note**: Instances can be provisioned with a public network by selecting it at provision time via the web portal or with the `triton` CLI tool. For Docker instances, you can be give public network access using the `-p` or `-P` flag.

To view all available networks, run `triton network list`.

### [Can I connect my instances together on a private network?](/network/frequently-asked-questions#can-i-connect-my-instances-together-on-a-private-network) <a href="#can-i-connect-my-instances-together-on-a-private-network" id="can-i-connect-my-instances-together-on-a-private-network"></a>

Yes. You can choose the networks you want to connect your instance to when you create it, and add or remove network connections (NICs) while the instance is running.

By default, each instance will be connected to a private fabric network. It is also possible to [connect instances to a public network](/network/frequently-asked-questions#how-do-get-a-public-ip-address). Exactly what type of private network and whether or not the instance gets a public network depends on the instance type.

Private fabric networks are a good choice for connecting the components of your application, since their isolation from the public internet and other users in the data center (for user-defined networks) can improve the security of those application components. For example, databases are typically connected just to other application components in the data center and not exposed on the public internet.

### [What are the default networks for my instance?](/network/frequently-asked-questions#what-are-the-default-networks-for-my-instance) <a href="#what-are-the-default-networks-for-my-instance" id="what-are-the-default-networks-for-my-instance"></a>

* **Docker**
  * Defaults to your default fabric network
  * Can specify one or more different fabric networks when using `triton-docker run`
  * NICs and networks can be added and removed after the instance is started\[^2]
  * Can get an interface and IP on the operator-defined "public" network by using the `-p` argument to `triton-docker run`
* **Infrastructure containers and VMs**
  * Defaults to the operator-defined shared private network
  * Can get one or more user-defined fabric networks at start time
  * NICs and networks can be added and removed after the instance is started
  * Gets an interface and IP on the operator-defined "public" network by default

MNX user-defined networks (also called "fabrics" and "overlay networks") are built using [VXLAN](https://en.wikipedia.org/wiki/Virtual_Extensible_LAN) and [802.1Q](https://en.wikipedia.org/wiki/IEEE_802.1Q) industry standards. [Check out the docs](/network/triton-networking-and-fabric-user-guide).

Every account in MNX starts with a private user-defined network named "default", which is the default network for Docker containers and an optional network for other instances. To list the networks available, go to the [MNX portal](https://portal.mnx.io) → [Networks](https://portal.mnx.io/networking/networks/) or use the Triton CLI command `triton networks`.

Your container may also be connected to a public network, reachable over the internet. The IP address the public network is given varies based on the data center. By default, all containers and VM instances are given public VNICs. Docker containers do not have a public VNIC unless you request it with the `-p` or `-P` argument to `triton-docker run ...`.

### [How do get a public IP address?](/network/frequently-asked-questions#how-do-get-a-public-ip-address) <a href="#how-do-get-a-public-ip-address" id="how-do-get-a-public-ip-address"></a>

Docker containers on MNX only get interfaces and IP addresses on the public internet if you request one with the `-p` or `-P` argument to `triton-docker run ...`.

Infrastructure containers and hardware virtual machines get public IP addresses by default.

Use the [instructions above to find the IP address(es) for your instances](/network/frequently-asked-questions#how-do-i-find-my-ip-addresses).

### [What if I don't want a public IP address?](/network/frequently-asked-questions#what-if-i-dont-want-a-public-ip-address) <a href="#what-if-i-dont-want-a-public-ip-address" id="what-if-i-dont-want-a-public-ip-address"></a>

Applications often have many components or services, only a small portion of which should be exposed on the public internet. You want certain components such as a load balancer and the front-end design to be easily seen by the user. However, databases and certain back-end components should most often be hidden from the public for the safety of your application.

Public IP addresses are optional. They're on by default for infrastructure containers and hardware VMs, but you can create containers without them if you want. For Docker containers, they're off by default, and you have to explicitly ask for a public IP address using the `-p` or `-P` argument in your `triton-docker run...`.

### [Can I firewall my instance?](/network/frequently-asked-questions#can-i-firewall-my-instance) <a href="#can-i-firewall-my-instance" id="can-i-firewall-my-instance"></a>

Firewalls can help protect your instances from network attacks by blocking (or allowing) traffic based on a set of rules you can define. This can be especially valuable for protecting instances on public or shared networks. MNX [Cloud Firewall](/network/firewall) makes firewall management easy. In some cases, it's even automatic!

MNX Cloud Firewall can automatically apply firewall rules based on instance tags or Docker labels, making it easy to apply or change firewall policies.

And, for Docker instances, MNX Cloud Firewall will automatically set rules that block traffic to all the ports on a public network *except* those specified in the `-p` argument in your `triton-docker run...`.

You can modify these rules in your terminal with `triton fwrule`


# CloudAPI Documentation

CloudAPI is the public API for MNX.io: it allows end users of the cloud to manage their accounts, instances, networks, images, and to inquire about other relevant details.

* [Getting Started](/cloudapi/getting-started)
* [RBAC: Users, Roles & Polices](/cloudapi/rbac-users-roles-and-policies)
* [API Introduction](/cloudapi/api-introduction)
* [API Details](/cloudapi/api-details)

## Triton CloudAPI CLI Commands <a href="#appendix-c-cloudapi-cli-commands" id="appendix-c-cloudapi-cli-commands"></a>

| **`triton` Command**             | **Description**                                                               |
| -------------------------------- | ----------------------------------------------------------------------------- |
| triton instance tag set          | Allows you to add additional tags, other than those set at provisioning time. |
| -                                | Add role tags to CloudAPI resources.                                          |
| triton fwrule create             | Add a new firewall rule.                                                      |
| triton image create              | Create a new custom image from an instance.                                   |
| triton key add                   | Uploads a new OpenSSH key to Triton.                                          |
| triton instance create           | Allows you to provision an instance.                                          |
| triton instance snapshot create  | Allows you to take a snapshot of an instance.                                 |
| triton fwrule delete             | Removes a given firewall rule.                                                |
| triton image delete              | Delete a private image.                                                       |
| triton key delete                | Deletes an SSH key by name.                                                   |
| triton instance delete           | Allows you to completely destroy an instance.                                 |
| -                                | Deletes a single metadata key from this instance.                             |
| triton instance snapshot delete  | Deletes the specified snapshot of an instance.                                |
| triton instance tag delete       | Deletes a single tag from this instance.                                      |
| triton fwrule disable            | Disable an enabled firewall rule.                                             |
| triton instance disable-firewall | Completely disable the firewall on an instance.                               |
| triton fwrule enable             | Enable a disabled firewall rule.                                              |
| triton instance enable-firewall  | Enable the firewall on an instance.                                           |
| -                                | Export an image to Manta.                                                     |
| -                                | Administer fabric networks and VLANs.                                         |
| triton account get               | Gets details about your account.                                              |
| triton fwrule get                | Get details about a specific firewall rule.                                   |
| triton image get                 | Gets an individual image by id.                                               |
| triton key get                   | Retrieves an individual key record.                                           |
| triton instance get              | Gets the details for an individual instance.                                  |
| triton instance audit            | Get a historical list of actions performed on an instance.                    |
| -                                | Returns the complete set of metadata associated with this instance.           |
| triton instance snapshot get     | Gets the state of the named snapshot.                                         |
| triton instance tag get          | Returns the value for a single tag on this instance.                          |
| triton network get               | Gets a network by the given id.                                               |
| triton package get               | Gets a package by name.                                                       |
| -                                | List of role-tags assigned to a given resource.                               |
| triton datacenters               | Provides a list of all datacenters this cloud is aware of.                    |
| triton fwrule list               | List all firewall rules applying to this account.                             |
| triton image list                | Provides a list of images available in this datacenter.                       |
| triton key list                  | Lists all public keys we have on record for the specified account.            |
| triton instance fwrules list     | List firewall rules applying to a specific instance.                          |
| triton instance list             | Lists all instances on an account.                                            |
| triton instance snapshot list    | Lists all snapshots taken for a given instance.                               |
| triton instance tag list         | Returns the complete set of tags associated with this instance.               |
| triton network list              | Provides a list of networks available to the user in this datacenter.         |
| triton package list              | Provides a list of packages available in this datacenter.                     |
| -                                | List, add and remove NICs attached to an instance.                            |
| -                                | Add, list, update and remove policies.                                        |
| triton instance reboot           | Allows you to 'reboot' an instance.                                           |
| -                                | Rename an instance.                                                           |
| triton instance tag replace-all  | Replace all tags on an instance.                                              |
| -                                | Allows you to resize a container.                                             |
| -                                | Add, list, update and remove roles.                                           |
| triton instance start            | Allows you to boot up an instance.                                            |
| triton instance start            | Starts a stopped instance from the referenced snapshot.                       |
| triton instance stop             | Allows you to shut down an instance.                                          |
| triton account update            | Change details of the current account.                                        |
| triton fwrule update             | Change a firewall rule.                                                       |
| -                                | Update metadata about an image.                                               |
| -                                | Allows you to update the metadata for a given instance.                       |
| -                                | Add, update and remove account users and their keys.                          |
| trion image clone                | Clone a shared image.                                                         |
| triton image copy                | Copy an image into another DC.                                                |
| triton info                      | Print an account summary.                                                     |
| triton instance ip               | Print the primary IP of the given instance.                                   |
| triton instance ssh              | SSH to the primary IP of an instance.                                         |
| triton instance wait             | Wait on instances changing state.                                             |
| triton profile                   | List, get, create and update Triton CLI profiles.                             |
| triton services                  | List available service endpoints for the datacenter.                          |


# Getting Started

## Getting Started <a href="#getting-started" id="getting-started"></a>

If you choose to use node-triton or node-smartdc, be aware that they both require Node.js.

You can get Node.js from [nodejs.org](http://nodejs.org/) as source code, and as precompiled packages for Windows, Macintosh, Linux and Illumos distributions. Alternatively, when using a \*nix, you can usually install Node.js using a package manager as well (e.g. pkgsrc, brew, apt-get, yum). The version of Node.js should be at least v0.10, so npm (Node.js's package manager) should come with it as well.

Once you've installed Node.js, to install node-triton invoke:

```
npm install -g triton
```

or, to install node-smartdc:

```
npm install -g smartdc
```

You will probably want to install [json](https://www.npmjs.org/package/json) as well. It is a tool that makes it easier to work with JSON-formatted output. You can install it like this:

```
npm install -g json
```

In all cases above, the `-g` switch installs the tools globally, usually in `/usr/local/bin`, so that you can use them easily from the command line. Omit this switch if you'd rather the tools be installed in your home hierarchy, but you'll need to set your PATH appropriately.

### Generate an SSH key <a href="#generate-an-ssh-key" id="generate-an-ssh-key"></a>

Both CLIs require an SSH key to communicate with CloudAPI, as well as logging-in to many instances.

If you haven't already generated an SSH key (required to use both SSH and HTTP Signing), run the following command:

```
ssh-keygen -b 2048 -t rsa -m PEM
```

This will prompt you with a place to save the key. You should probably just accept the defaults, as many programs (SSH and CloudAPI CLIs) will first look for a file called \~/.ssh/id\_rsa. Before running the above command, ensure that \~/.ssh/id\_rsa does not already exist; overwriting it may have unintended consequences.

### Set Up your CLI <a href="#set-up-your-cli" id="set-up-your-cli"></a>

You need to set the following environment variables information in order to interact with CloudAPI using either node-triton or node-smartdc:

* `SDC_URL`: The URL of the CloudAPI endpoint.
* `SDC_KEY_ID`: Fingerprint for the key you uploaded to Triton.
* `SDC_ACCOUNT`: Your username; the login you use for Triton.
* `SDC_USER`: If authenticating as a subuser, the username of the subuser. See [Role Based Access Control](https://apidocs.joyent.com/cloudapi/#rbac-users-roles-policies).
* `SDC_TESTING`: If using a self-signed SSL certificate, set this to 1.

An example for `SDC_URL` is `https://us-west-1.api.joyent.com`. Each datacenter in a cloud has its own CloudAPI endpoint; a different cloud that uses Triton would have a different URL.

In this document, we'll use `api.example.com` as the `SDC_URL` endpoint; please replace it with the URL of your datacenter(s). Note that CloudAPI always uses SSL/TLS, which means that the endpoint URL must begin with `https`.

You can quickly get your key fingerprint for `SDC_KEY_ID` by running:

```
ssh-keygen -l -f ~/.ssh/id_rsa.pub | awk '{print $2}' | tr -d '\n'
```

where you replace `~/.ssh/id_rsa.pub` with the path to the public key you want to use for signing requests.

### Working with the CLI <a href="#working-with-the-cli" id="working-with-the-cli"></a>

For a complete list of CloudAPI CLI commands available, please see [Appendix C: CloudAPI CLI Commands](https://apidocs.joyent.com/cloudapi/#appendix-c-cloudapi-cli-commands).

To get help on a command, use the `--help` flag. For example:

```
triton datacenters --help
Show datacenters in this cloud.
A "cloud" is a set of related datacenters that share account
information.

Usage:
     triton datacenters

Options:
    -h, --help                Show this help.

  Output options:
    -H                        Omit table header row.
    -o field1,...             Specify fields (columns) to output.
    -s field1,...             Sort on the given fields. Default is "name".
    -j, --json                JSON output.
```

or

```
sdc-listdatacenters --help
sdc-listdatacenters [--account string] [--api-version string] [--debug boolean] [--help boolean] [--keyId string] [--url url] [--version boolean] [--verbose boolean] [--user string] [--role string]
```

You can set environment variables for the following flags so that you don't have to type them for each request (e.g. in your .bash\_profile). All the examples in this document assume that these variables have been set:

| **CLI Flags**          | **Description**                                                                                                     | **Environment Variable** |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| <p>--account<br>-a</p> | Login name (account)                                                                                                | SDC\_ACCOUNT             |
| --user                 | Subuser name when using [Role Based Access Control](https://apidocs.joyent.com/cloudapi/#rbac-users-roles-policies) | SDC\_USER                |
| <p>--keyId<br>-k</p>   | Fingerprint of key to use for signing                                                                               | SDC\_KEY\_ID             |
| <p>--url<br>-u</p>     | URL of the CloudAPI endpoint                                                                                        | SDC\_URL                 |

### Provision a new instance <a href="#provision-a-new-instance" id="provision-a-new-instance"></a>

To provision a new instance, you first need to get the `id`s for the image and package you want to use as the base for your instance.

An image is a snapshot of a filesystem and its software (for some types of container), or a disk image (for hardware virtual machines). You can get the list of available images using the `triton image list` or `sdc-listimages` commands; see the [ListImages](https://apidocs.joyent.com/cloudapi/#ListImages) section below for a detailed explanation of these commands.

A package is a set of dimensions for the new instance, such as RAM and disk size. You can get the list of available packages using the `triton package list` or `sdc-listpackages` commands; see the [ListPackages](https://apidocs.joyent.com/cloudapi/#ListPackages) section below for a detailed explanation of these commands.

Once you have the package and image ids, to provision a new instance:

```
triton instance create $image $package
```

or

```
sdc-createmachine --image=$image --package=$package
```

For example:

```
triton instance create 2b683a82-a066-11e3-97ab-2faa44701c5a 64e23114-d502-c171-967f-b0e0cfb2009a
Creating instance 61dc8be (9205af5b-f2c0-ef07-e1f3-94bf1ff8fb93, base@13.4.0, test_128)
```

You can use the `--name` flag to name your instance; if you do not specify a name, Triton will generate one for you. `--image` is the `id` of the image you'd like to use as the new instance's base. `--package` is the `id` of the package to use to set instance dimensions. For the `triton` command, you can also pass the name of the image or the package instead of their id.

Retrieve the status of your new instance by:

```
triton instance get $instance_id
```

or

```
sdc-getmachine $instance_id
```

For example:

```
triton instance get 9205af5b-f2c0-ef07-e1f3-94bf1ff8fb93
{
    "id": "9205af5b-f2c0-ef07-e1f3-94bf1ff8fb93",
    "name": "61dc8be",
    "type": "smartmachine",
    "brand": "joyent",
    "state": "running",
    "image": "2b683a82-a066-11e3-97ab-2faa44701c5a",
    "ips": [
        "10.88.88.56",
        "192.168.128.5"
    ],
    "memory": 128,
    "disk": 12288,
    "metadata": {
        "root_authorized_keys": "<...>"
    },
    "tags": {},
    "created": "2015-12-06T04:31:17.053Z",
    "updated": "2015-12-06T04:31:26.000Z",
    "networks": [
        "67f1232c-5b40-4693-8b55-560245984233",
        "05dcc9e2-8ae6-48d9-8222-25f64465693f"
    ],
    "primaryIp": "10.88.88.56",
    "firewall_enabled": false,
    "compute_node": "564d0b8e-6099-7648-351e-877faf6c56f6",
    "package": "test_128"
}
```

When you provision a new instance, the instance will take time to be initialized and booted; the `state` attribute will reflect this. Once the `state` attribute "running", you can login to your new instance (assuming it's a Unix-based instance), with the following:

```
ssh-add ~/.ssh/<key file>
$ ssh -A root@<new instance IP address>
```

These two commands set up your SSH agent (which has some magical properties, so you need to handle your SSH keys less often), and logs you in as the `admin` user on an instance. Note that the `admin` user has password-less sudo capabilities, so you may want to set up some less privileged users. The SSH keys on your account will allow you to login as `root` or `admin` on your new instance.

An alternative of using SSH directly is:

```
triton ssh <name of instance>
```

Now that we've done some basics with an instance, let's introduce a few concepts:

#### Images <a href="#images" id="images"></a>

By default, SmartOS images should be available to your for use. Your Triton cloud may have other images available as well, such as Linux or Windows images. The list of available images can be obtained with:

```
triton image list
```

or

```
sdc-listimages
```

For example:

```
triton image list
SHORTID   NAME            VERSION  FLAGS  OS       TYPE          PUBDATE
e1faace4  minimal-64-lts  15.4.1   P      smartos  zone-dataset  2016-03-03
```

#### Packages <a href="#packages" id="packages"></a>

You can list packages available in your cloud with:

```
triton package list
```

or

```
sdc-listpackages
```

For example:

```
 ./triton package list
SHORTID   NAME      DEFAULT  MEMORY  SWAP  DISK  VCPUS
64e23114  test_128  false      128M  256M   12G      1
```

Packages are the Triton name for the dimensions of an instance (how much CPU will be available, how much RAM, disk and swap, and so forth). Packages are provided so that you do not need to select individual settings, such as RAM or disk size.

### Managing SSH keys <a href="#managing-ssh-keys" id="managing-ssh-keys"></a>

For instances which don't have a `brand` of `kvm` or `bhyve` (see `triton instance list -o id,brand` or `sdc-listmachines`), you can manage the SSH keys that allow logging into the instance via CloudAPI. For example, to rotate keys:

```
triton key add --name=my-other-rsa-key ~/.ssh/my_other_rsa_key.pub
```

or

```
sdc-createkey --name=my-other-rsa-key ~/.ssh/my_other_rsa_key.pub
```

The `--name` option sets the name of the key. If you don't provide one, CloudAPI sets it to the name of the file; in this case `my_other_rsa_key.pub`.

To use the new key, you will need to update the environment variables:

```
export SDC_KEY_ID=`ssh-keygen -l -f ~/.ssh/my_other_rsa_key.pub | awk '{print $2}' | tr -d '\n'`
```

At this point you could delete your other key from the system; see [Cleaning Up](https://apidocs.joyent.com/cloudapi/#cleaning-up) for a quick example.

You cannot manage the SSH keys of instances with a `brand` of `kvm` or `bhyve`. Hardware virtual machines are static, and whatever keys were in your account at instance creation time are used, provided the OS inside KVM is a \*nix.

### Cleaning up <a href="#cleaning-up" id="cleaning-up"></a>

After going through this `Getting Started` section, you should now have at least one SSH key and one instance. The rest of the commands assume you have [json](https://www.npmjs.org/package/json) installed.

#### Deleting Machines <a href="#deleting-machines" id="deleting-machines"></a>

To clean up an instance, you can use either:

```
triton instance delete $instance_id
```

or

```
sdc-deletemachine $instance_id
```

For example:

```
triton instance delete 9205af5b
Delete (async) instance 9205af5b (9205af5b-f2c0-ef07-e1f3-94bf1ff8fb93)
```

#### Deleting keys <a href="#deleting-keys" id="deleting-keys"></a>

Finally, you probably have one or two SSH keys uploaded to Triton after going through the guide, so to delete the one we setup:

```
triton key delete id_rsa
```

or

```
sdc-deletekey id_rsa
```


# RBAC: Users, Roles & Policies

Starting at version 7.2.0, CloudAPI supports Role Based Access Control (RBAC), which means that [accounts](https://apidocs.joyent.com/cloudapi/#account) can have multiple users and roles associated with them.

While the behaviour of the [main account](https://apidocs.joyent.com/cloudapi/#GetAccount) remains the same, including the [SSH keys](https://apidocs.joyent.com/cloudapi/#keys) associated with it, it's now possible to have multiple [Users](https://apidocs.joyent.com/cloudapi/#users) subordinate to the main account. Each of these users have a different set of [SSH Keys](https://apidocs.joyent.com/cloudapi/#sshKeys). Both the users and their associated SSH keys have the same format as the main account object (and the keys associated with it).

It's worth mentioning that the `login` for an account's users must be different only between the users of that account, not globally. We could have an account with login *"mark"*, another account "exampleOne" with a user with login "mark", another account "exampleTwo" with another user with login "mark", and so forth.

These account users can additionally be organized using [Roles](https://apidocs.joyent.com/cloudapi/#roles):

```
{
  "id": "ff578c1f-bad5-4d3c-8880-2f76745f2511",
  "name": "devs",
  "members": [
    {
      "type": "subuser",
      "id": "985e0ed4-9994-4303-8c43-6c92b7988167",
      "login": "bob",
      "default": true
    },
    {
      "type": "subuser",
      "id": "0cc38461-787a-4c05-a3f3-352a4d55541f",
      "login": "fred",
      "default": false
    }
  ],
  "policies": [
    {
      "id": "2104c53f-2e33-4393-9320-a6521d5ef2dc",
      "name": "createMachine"
    },
    {
      "id": "e8bdd555-eef0-4c1c-83be-93c443b59e3e",
      "name": "restart instances"
    }
  ]
}
```

Each role can have an arbitrary set of [Policies](https://apidocs.joyent.com/cloudapi/#policies):

```
{
  "name": "restart instances",
  "id": "e8bdd555-eef0-4c1c-83be-93c443b59e3e",
  "rules": [
    "CAN rebootmachine if requesttime::time > 07:30:00 and requesttime::time < 18:30:00 and requesttime::day in (Mon, Tue, Wed, THu, Fri)",
    "CAN stopmachine",
    "CAN startmachine"
  ],
  "description": "This is completely optional"
}
```

The `rules` in policies are used for the access control of an account's users. These rules use [Aperture](https://github.com/joyent/node-aperture) as the policy language, and are described in detail in the next section.

Our recommendation is to limit each policy's set of rules to a very scoped collection, and then add one or more of these policies to each group. This aids easily reusing existing policies for one or more roles, allowing fine-grained definition of each role's abilities.

### Rules definition for access control <a href="#rules-definition-for-access-control" id="rules-definition-for-access-control"></a>

As mentioned earlier, the policies' rules use [Aperture Policy Language](https://github.com/joyent/node-aperture#policy-language), with the following *basic format*:

`<principals> CAN <actions> <resources> WHEN <conditions>`.

You should refer to the [Aperture documentation](https://github.com/joyent/node-aperture) for the complete details about the different possibilities when defining new rules. This section will only cover a limited set strictly related to CloudAPI's usage.

In the case of CloudAPI, `<principal>` will be always the user performing the HTTP request. Likewise, `<resource>` will always be the URL of such request, for example `/:account/machines/:instance_id`.

We add one or more roles to a resource to explicitly define the active roles a user trying to access a given resource must have. Therefore, we don't need to specify `<principal>` in our rules, since it'll always be defined by the role-tags of the resource the user is trying to get access to. For the same reason, we don't need to specify `<resource>` in our rules.

Therefore, CloudAPI's Aperture rules have the format:

```
    CAN <actions> WHEN <conditions>
```

By default, the access policy will `DENY` any attempt made by any account user to access a given resource, unless:

* that resource is tagged with a role
* that role is active
* that role has a policy
* that policy contains a rule which explicity `GRANTS` access to that resource

For example, a user with an active role `read`, which includes a policy rule like `CAN listmachines and getmachines` will not get access to resources like `/:account/machines` or `/:account/machines/:instance_id` unless these resources are *role-tagged* with the role `read` too.

Additionally, given that the `<actions>` included in the policy rule are just `listmachines` and `getmachine`, the user will be able to retrieve an instance's details provided by the [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) action, but will not be able to perform any other instance actions (like [StopMachine](https://apidocs.joyent.com/cloudapi/#StopMachine)). However, if the role has a rule including that `<action>` (like StopMachine), or the user has an additional role which includes that rule, then the user can invoke that action too.

As an aside, the active roles of a user are set by the `default_members` attribute in a role. If three different roles contain the "john" user (amongst others) in their default-members list, then the "john" user will have those three roles as active roles by default. This can be overridden by passing in `?as-role=<comma-separated list of role names>` as part of the URL, or adding a --role flag when using a node-smartdc command; provided that each role contains that user in their `members` list, then those roles are set as the currently-active roles for a request instead.

For more details on how Access Control works for both CloudAPI and Manta, please refer to [Role Based Access Control](https://docs.joyent.com/jpc/rbac/) documentation.

#### An important note about RBAC and certain reads after writes <a href="#an-important-note-about-rbac-and-certain-reads-after-writes" id="an-important-note-about-rbac-and-certain-reads-after-writes"></a>

CloudAPI uses replication and caching behind the scenes for user, role and policy data. This implies that API reads after a write on these particular objects can be up to several seconds out of date.

For example, when a user is created, CloudAPI returns both a user object (which is up to date), and a location header indicating where that new user object actually lives. Following that location header may result in a 404 for a short period.

As another example, if a policy is updated, the API call will return a policy object (which is up to date), but GETing that URL again may temporarily return a outdated object with old object details.

For the time being, please keep in mind that user, role and policy creation/updates/deletion may potentially take several seconds to settle. They have eventual consistency, not read-after-write.<br>


# API Introduction

CloudAPI exposes a REST API over HTTPS. You can work with the REST API by either calling it directly via tooling you already know about (such as curl, et al), or by using the CloudAPI CLIs and SDKs from Joyent. The node-triton CloudAPI SDK & CLI is available as an npm module, which you can install with:

```
npm install triton
```

Alternatively, there is the more stable and feature-complete node-smartdc:

```
npm install smartdc
```

Although node-triton has fewer features -- for now -- it will continue to receive the most development effort and future support. node-smartdc is in maintenance.

The rest of this document will show all APIs in terms of both the raw HTTP specification, the CLI commands, and sometimes the node-smartdc SDK.

### Issuing Requests <a href="#issuing-requests" id="issuing-requests"></a>

All HTTP calls to CloudAPI must be made over TLS, and requests must carry at least two headers (in addition to standard HTTP headers): `Authorization` and `Api-Version`. The details are explained below. In addition to these headers, any requests requiring content must be sent in an acceptable scheme to CloudAPI. Details are also below.

#### Content-Type <a href="#content-type" id="content-type"></a>

For requests requiring content, you can send parameters encoded with `application/json`, `application/x-www-form-urlencoded` or `multipart/form-data`. Joyent recommends `application/json`. The value of the `Accept` header determines the encoding of content returned in responses. CloudAPI supports `application/json` response encodings only.

For example, all of the following are valid calls:

Query String (on the uri):

```
POST /my/keys?name=rsa&key=... HTTP/1.1
Host: joyent.com
Authorization: ...
Content-Length: 0
```

Form encoded in the body:

```
POST /my/keys HTTP/1.1
Host: joyent.com
Authorization: ...
Content-Type: application/x-www-form-urlencoded
Content-Length: 123

name=rsa&key=...
```

JSON in the body:

```
POST /my/keys HTTP/1.1
Host: joyent.com
Authorization: ...
Content-Type: application/json
Content-Length: 123

{"name":"rsa","key":"..."}
```

#### Authorization <a href="#authorization" id="authorization"></a>

All API calls to CloudAPI require an Authorization header, which supports multiple ["schemes"](http://tools.ietf.org/html/rfc2617). Currently CloudAPI supports only one Authentication mechanism due to PCI compliance restrictions:

* HTTP Signature Authentication Scheme. This Scheme is outlined in [Appendix B](https://apidocs.joyent.com/cloudapi/#appendix-b-http-signature-authentication).

In order to leverage HTTP Signature Authentication, only RSA signing mechanisms are supported, and your keyId must be equal to the path returned from a [ListKeys](https://apidocs.joyent.com/cloudapi/#ListKeys) API call. For example, if your Triton login is `demo`, and you've uploaded an RSA SSH key with the name `foo`, an Authorization header would look like:

```
Authorization: Signature keyId=/demo/keys/foo,algorithm="rsa-sha256" ${Base64(sign($Date))}
```

The default value to sign for CloudAPI requests is simply the value of the HTTP `Date` header. For more information on the Date header value, see [RFC 2616](http://tools.ietf.org/html/rfc2616#section-14.18). All requests to CloudAPI using the Signature authentication scheme *must* send a Date header. Note that clock skew will be enforced to within 300 seconds (positive or negative) from the value sent.

Full support for the HTTP Signature Authentication scheme is provided in both CloudAPI SDKs; an additional reference implementation for Node.js is available in the npm `http-signature` module, which you can install with:

```
npm install http-signature
```

#### Using cURL with CloudAPI <a href="#using-curl-with-cloudapi" id="using-curl-with-cloudapi"></a>

Since [cURL](http://curl.haxx.se/) is commonly used to script requests to web services, here's a simple Bash function you can use to wrap cURL when communicating with CloudAPI:

```
function cloudapi() {
    local now=$(date -u '+%a, %d %h %Y %H:%M:%S GMT')
    local signature=$(echo -n "$now" | openssl dgst -sha256 -sign ~/.ssh/id_rsa | openssl enc -e -a | tr -d '\n')
    local url="$SDC_URL$1"
    shift

    curl -s -k -i \
        -H 'Accept: application/json' \
        -H "accept-version: ~8" \
        -H "Date: $now" \
        -H "Authorization: Signature keyId=\"/$SDC_ACCOUNT/keys/id_rsa\",algorithm=\"rsa-sha256\" $signature" \
        "$@" "$url"
    echo
}
```

You may need to alter the path to your SSH key in the above function, as well as the path its public-key is saved under in Triton.

With that function, you could just do:

```
cloudapi /my/machines
```

### CloudAPI HTTP Responses <a href="#cloudapi-http-responses" id="cloudapi-http-responses"></a>

CloudAPI returns all response objects as `application/json` encoded HTTP bodies. In addition to the JSON body, all responses have the following headers:

| **Header**    | **Description**                                         |
| ------------- | ------------------------------------------------------- |
| Date          | When the response was sent (RFC 1123 format)            |
| Api-Version   | The exact version of the CloudAPI server you spoke with |
| Request-Id    | A unique id for this request; you should log this       |
| Response-Time | How long the server took to process your request (ms)   |

If there is content, you can expect:

| **Header**     | **Description**                                             |
| -------------- | ----------------------------------------------------------- |
| Content-Length | How much content, in bytes                                  |
| Content-Type   | Formatting of the response (almost always application/json) |
| Content-MD5    | An MD5 checksum of the response; you should check this      |

#### HTTP Status Codes <a href="#http-status-codes" id="http-status-codes"></a>

Your client should check for each of the following status codes from any API request:

| **Code** | **Description**          | **Details**                                                                    |
| -------- | ------------------------ | ------------------------------------------------------------------------------ |
| 400      | Bad Request              | Invalid HTTP Request                                                           |
| 401      | Unauthorized             | Either no Authorization header was sent, or invalid credentials were used      |
| 403      | Forbidden                | No permissions to the specified resource                                       |
| 404      | Not Found                | Resource was not found                                                         |
| 405      | Method Not Allowed       | Method not supported for the given resource                                    |
| 406      | Not Acceptable           | Try sending a different Accept header                                          |
| 409      | Conflict                 | Most likely invalid or missing parameters                                      |
| 413      | Request Entity Too Large | You sent too much data                                                         |
| 415      | Unsupported Media Type   | Request was encoded in a format CloudAPI does not understand                   |
| 420      | Slow Down                | You're sending too many requests too quickly                                   |
| 449      | Retry With               | Invalid Version header; try with a different Api-Version string                |
| 500      | Internal Error           | An unexpected error occurred; see returned message for more details.           |
| 503      | Service Unavailable      | Either there's no capacity in this datacenter, or it's in a maintenance window |

#### Error Responses <a href="#error-responses" id="error-responses"></a>

In the event of an error, CloudAPI will return a standard JSON error response object in the body with the scheme:

```
{
  "code": "CODE",
  "message": "human readable string"
}
```

Where the code element is one of:

| **Code**           | **Description**                                       |
| ------------------ | ----------------------------------------------------- |
| BadRequest         | You sent bad HTTP                                     |
| InternalError      | Something went wrong in Triton                        |
| InUseError         | The object is in use and cannot be operated on        |
| InvalidArgument    | You sent bad arguments or a bad value for an argument |
| InvalidCredentials | Authentication failed                                 |
| InvalidHeader      | You sent a bad HTTP header                            |
| InvalidVersion     | You sent a bad Api-Version string                     |
| MissingParameter   | You didn't send a required parameter                  |
| NotAuthorized      | You don't have access to the requested resource       |
| RequestThrottled   | You were throttled                                    |
| RequestTooLarge    | You sent too much request data                        |
| RequestMoved       | HTTP Redirect                                         |
| ResourceNotFound   | What you asked for wasn't found                       |
| UnknownError       | Something completely unexpected happened!             |

Clients are expected to check HTTP status code first, and if it's in the 4xx range, they can leverage the codes above.<br>


# API Details


# Account

You can obtain your account details and update them through CloudAPI, although login cannot be changed, and password can not be retrieved.

### GetAccount (GET /:login) <a href="#getaccount" id="getaccount"></a>

Retrieves your account details. Instead of providing your login name, you can also provide 'my' (i.e. GET /my).

#### Inputs <a href="#inputs" id="inputs"></a>

* None

#### Returns <a href="#returns" id="returns"></a>

Account object:

| **Field**            | **Type**     | **Description**                              |
| -------------------- | ------------ | -------------------------------------------- |
| id                   | UUID         | Unique id for this account                   |
| login                | String       | Your login name                              |
| email                | String       | Email address                                |
| companyName          | String       | ...                                          |
| firstName            | String       | ...                                          |
| lastName             | String       | ...                                          |
| address              | String       | ...                                          |
| postalCode           | String       | ...                                          |
| city                 | String       | ...                                          |
| state                | String       | ...                                          |
| country              | String       | ...                                          |
| phone                | String       | ...                                          |
| created              | ISO8601 date | When this account was created                |
| updated              | ISO8601 date | When this account's details was last updated |
| triton\_cns\_enabled | Boolean      | `true` if Triton CNS is enabled for account  |

#### Errors <a href="#errors" id="errors"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**            |
| ---------------- | -------------------------- |
| ResourceNotFound | If `:login` does not exist |

#### CLI Command <a href="#cli-command" id="cli-command"></a>

```
triton account get
```

or

```
sdc-getaccount
```

#### Example Request <a href="#example-request" id="example-request"></a>

```
GET /my HTTP/1.1
authorization: Signature keyId="..."
accept: application/json
accept-version: ~8
host: api.example.com
```

#### Example Response <a href="#example-response" id="example-response"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 285
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: Sz+3BJ3EKDxL3MLQQumPgg==
Date: Tue, 22 Dec 2015 05:06:33 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: c3d496f0-a869-11e5-8662-47ccf5717dbf
Response-Time: 2122

{
  "id": "b89d9dd3-62ce-4f6f-eb0d-f78e57d515d9",
  "login": "barbar",
  "email": "barbar@example.com",
  "companyName": "Example Inc",
  "firstName": "BarBar",
  "lastName": "Jinks",
  "phone": "123-456-7890",
  "updated": "2015-12-21T11:48:54.884Z",
  "created": "2015-12-21T11:48:54.884Z"
}
```

### UpdateAccount (POST /:login) <a href="#updateaccount" id="updateaccount"></a>

Update your account details with the given parameters.

#### Inputs <a href="#inputs-2" id="inputs-2"></a>

| **Field**            | **Type** | **Description**                  |
| -------------------- | -------- | -------------------------------- |
| email                | String   | Email address                    |
| companyName          | String   | ...                              |
| firstName            | String   | ...                              |
| lastName             | String   | ...                              |
| address              | String   | ...                              |
| postalCode           | String   | ...                              |
| city                 | String   | ...                              |
| state                | String   | ...                              |
| country              | String   | ...                              |
| phone                | String   | ...                              |
| triton\_cns\_enabled | Boolean  | Enable or disable the Triton CNS |

#### Returns <a href="#returns-2" id="returns-2"></a>

Account object:

| **Field**            | **Type**     | **Description**                              |
| -------------------- | ------------ | -------------------------------------------- |
| id                   | UUID         | Unique id for this account                   |
| login                | String       | Your login name                              |
| email                | String       | Email address                                |
| companyName          | String       | ...                                          |
| firstName            | String       | ...                                          |
| lastName             | String       | ...                                          |
| address              | String       | ...                                          |
| postalCode           | String       | ...                                          |
| city                 | String       | ...                                          |
| state                | String       | ...                                          |
| country              | String       | ...                                          |
| phone                | String       | ...                                          |
| created              | ISO8601 date | When this account was created                |
| updated              | ISO8601 date | When this account's details was last updated |
| triton\_cns\_enabled | Boolean      | `true` if Triton CNS is enabled for account  |

#### Errors <a href="#errors-2" id="errors-2"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**            |
| ---------------- | -------------------------- |
| ResourceNotFound | If `:login` does not exist |

#### CLI Command <a href="#cli-command-2" id="cli-command-2"></a>

```
triton account update postalCode=12345 phone='1 (234) 567 890'
```

or

```
sdc-updateaccount --postal-code=12345 --phone='1 (234) 567 890'
```

#### Example Request <a href="#example-request-2" id="example-request-2"></a>

```
POST /my HTTP/1.1
authorization: Signature keyId="...
accept: application/json
content-type: application/json
accept-version: ~8
content-length: 48
content-md5: 6kCHdE651hsI9N82TUkU/g==
host: api.example.com
connection: keep-alive

postal-code=12345&phone=1%20(234)%20567%20890
```

#### Example Response <a href="#example-response-2" id="example-response-2"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 309
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: xxJ5ppNDrEyAf5VIlt4GZw==
Date: Tue, 22 Dec 2015 12:16:37 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: d8db9e90-a8a5-11e5-90c9-4dcf4848c834
Response-Time: 1244

{
  "id": "b89d9dd3-62ce-4f6f-eb0d-f78e57d515d9",
  "login": "barbar",
  "email": "barbar@example.com",
  "companyName": "Example Inc",
  "firstName": "BarBar",
  "lastName": "Jinks",
  "postalCode": "12345",
  "phone": "1 (234) 567 890",
  "updated": "2015-12-22T12:16:37.781Z",
  "created": "2015-12-21T11:48:54.884Z"
}
```

## GetAccountLimits (GET /:login/limits) <a href="#getaccountlimits-get-loginlimits" id="getaccountlimits-get-loginlimits"></a>

When the operator has enabled the CloudAPI Provisioning Limits plugin, you can retreive your account limits and usage through this API.

See the [Provisioning Limits](https://apidocs.joyent.com/cloudapi/admin.html#appendix-a-provision-limits-plugin) plugin for how limits are configured and used in Triton.

#### Inputs <a href="#inputs-3" id="inputs-3"></a>

* None

#### Returns <a href="#returns-3" id="returns-3"></a>

An array of provisioning limit objects. Possible values for each provisioning limit object are:

| **Field** | **Type** | **Description**                                                                                      | **Possible values**                                                                                                                                                               |
| --------- | -------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| by        | String   | The type of limit. Note that "machines" means the "number of machines".                              | "ram", "quota", or "machines".                                                                                                                                                    |
| value     | Number   | The limit value. I.e. the total number of machines, total ram or total quota.                        | Ram is defined in terms of MiB. Quota is defined in terms of GiB.                                                                                                                 |
| used      | Number   | How much of the limit is used by existing machines.                                                  | Ram is defined in terms of MiB. Quota is defined in terms of GiB.                                                                                                                 |
| check     | String   | Optional. Restricts the limit to an image name or to an image os.                                    | "image" or "os".                                                                                                                                                                  |
| os        | String   | Optional. When `check` is set to "os", this is the Image `os` name this limit will be restricted to. | Usually, this will be one of `windows`, `linux`, `smartos`, `bsd` or `other`. See [IMGAPI os values](https://github.com/joyent/sdc-imgapi/blob/master/docs/index.md#manifest-os). |
| image     | String   | Optional. When `check` is set to "image", this is the Image `name` this limit will be restricted to. | See [IMGAPI image name](https://github.com/joyent/sdc-imgapi/blob/master/docs/index.md#manifest-name).                                                                            |

#### Errors <a href="#errors-3" id="errors-3"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**            |
| ---------------- | -------------------------- |
| ResourceNotFound | If `:login` does not exist |

#### Example Request <a href="#example-request-3" id="example-request-3"></a>

```
GET /my/limits HTTP/1.1
authorization: Signature keyId="..."
accept: application/json
accept-version: ~9
host: api.example.com
```

#### Example Response <a href="#example-response-3" id="example-response-3"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 285
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: Sz+3BJ3EKDxL3MLQQumPgg==
Date: Tue, 01 Aug 2019 05:06:33 GMT
Server: Joyent Triton 9.8.0
Api-Version: 9.0.0
Request-Id: c3d496f0-a869-11e5-8662-47ccf5717dbf
Response-Time: 1455

[
  {
    "by": "machines",
    "value": 100,
    "used": 2
  },
  {
    "by": "ram",
    "value": 1024,
    "used": 512
  },
  {
    "check": "os",
    "os": "linux",
    "by": "quota",
    "value": 1024,
    "used": 1
  }
]
```

## Keys <a href="#keys" id="keys"></a>


# Keys

This part of the API is the means by which you operate on your SSH/signing keys.

This part of the API is the means by which you operate on your SSH/signing keys. These keys are needed in order to login to instances over SSH, as well as signing requests to this API (see the HTTP Signature Authentication Scheme outlined in [Appendix B](https://apidocs.joyent.com/cloudapi/#appendix-b-http-signature-authentication) for more details).

Currently CloudAPI supports uploads of public keys in the OpenSSH format.

Note that while it's possible to provide a `name` attribute for an SSH key in order to use it as a human-friendly alias, this attribute's presence is optional. When it's not provided, the ssh key fingerprint will be used as the `name` instead.

Keys can optionally be submitted along with a hardware attestation certificate signed by a trusted hardware manufacturer, which will be validated and processed. Keys generated in hardware devices which require some form of multi-factor authentication to sign requests (e.g. the device requires a PIN or Touch input) are marked by this mechanism and may be specially treated by Triton and Manta as providing a kind of 2-factor authentication (depending on administrator policy).

For the following routes, the parameter placeholder `:key` can be replaced with with either the key's `name` or its `fingerprint`. It's strongly recommended to use `fingerprint` when possible, since the `name` attribute does not have any uniqueness constraints.

### ListKeys (GET /:login/keys) <a href="#listkeys" id="listkeys"></a>

Lists all public keys we have on record for the specified account.

#### Inputs <a href="#inputs-4" id="inputs-4"></a>

* None

#### Returns <a href="#returns-4" id="returns-4"></a>

Array of key objects. Each key object has the following fields:

| **Field**   | **Type**       | **Description**                                            |
| ----------- | -------------- | ---------------------------------------------------------- |
| name        | String         | Name for this key                                          |
| fingerprint | String         | Key fingerprint                                            |
| key         | String         | Public key in OpenSSH format                               |
| attested    | Boolean        | Indicates if the key has a hardware device attestation     |
| multifactor | Array\[String] | Lists any additional factors required to use (if attested) |

Possible `multifactor` values:

| **Value** | **Meaning**                                                                       |
| --------- | --------------------------------------------------------------------------------- |
| pin       | Input of a PIN or password is required for key use                                |
| touch     | Touch input (not authenticated -- i.e. not a fingerprint) is required for key use |

#### Errors <a href="#errors-4" id="errors-4"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**            |
| ---------------- | -------------------------- |
| ResourceNotFound | If `:login` does not exist |

#### CLI Command <a href="#cli-command-3" id="cli-command-3"></a>

```
triton key list

or

$ sdc-listkeys
```

#### Example Request <a href="#example-request-4" id="example-request-4"></a>

```
GET /my/keys HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-4" id="example-response-4"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 832
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: u4xmk+MgKzzIvrRt09k4sg==
Date: Tue, 22 Dec 2015 12:23:12 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: c44e2000-a8a6-11e5-9030-479dc847c4b2
Response-Time: 1041

[
  {
    "name": "barbar",
    "fingerprint": "03:7f:8e:ef:da:3d:3b:9e:a4:82:67:71:8c:35:2c:aa",
    "key": "<...>"
  }
]
```

### GetKey (GET /:login/keys/:key) <a href="#getkey" id="getkey"></a>

Retrieves the record for an individual key.

#### Inputs <a href="#inputs-5" id="inputs-5"></a>

* None

#### Returns <a href="#returns-5" id="returns-5"></a>

| **Field**   | **Type**       | **Description**                                            |
| ----------- | -------------- | ---------------------------------------------------------- |
| name        | String         | Name for this key                                          |
| fingerprint | String         | Key fingerprint                                            |
| key         | String         | OpenSSH formatted public key                               |
| attested    | Boolean        | Indicates if the key has a hardware device attestation     |
| multifactor | Array\[String] | Lists any additional factors required to use (if attested) |

Possible `multifactor` values:

| **Value** | **Meaning**                                                                       |
| --------- | --------------------------------------------------------------------------------- |
| pin       | Input of a PIN or password is required for key use                                |
| touch     | Touch input (not authenticated -- i.e. not a fingerprint) is required for key use |

#### Errors <a href="#errors-5" id="errors-5"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                      |
| ---------------- | ------------------------------------ |
| ResourceNotFound | If `:login` or `:key` does not exist |

#### CLI Command <a href="#cli-command-4" id="cli-command-4"></a>

```
triton key get barbar
```

or

```
sdc-getkey barbar
```

#### Example Request <a href="#example-request-5" id="example-request-5"></a>

```
GET /my/keys/barbar HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-5" id="example-response-5"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 830
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: p8gjrCZqMiZbD15TA9ymEQ==
Date: Tue, 22 Dec 2015 13:26:17 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 94423be0-a8af-11e5-a95f-e74285cfeb5b
Response-Time: 999

{
  "name": "barbar",
  "fingerprint": "03:7f:8e:ef:da:3d:3b:9e:a4:82:67:71:8c:35:2c:aa",
  "key": "<...>",
  "attested": true,
  "multifactor": ["pin"]
}
```

### CreateKey (POST /:login/keys) <a href="#createkey" id="createkey"></a>

Uploads a new OpenSSH key to Triton for use in HTTP signing and SSH.

#### Inputs <a href="#inputs-6" id="inputs-6"></a>

| **Field**   | **Type**        | **Description**                        |
| ----------- | --------------- | -------------------------------------- |
| name        | String          | Name for this key (optional)           |
| key         | String          | OpenSSH formatted public key           |
| attestation | Array of String | PEM formatted attestation certificates |

#### Returns <a href="#returns-6" id="returns-6"></a>

| **Field**   | **Type**       | **Description**                                            |
| ----------- | -------------- | ---------------------------------------------------------- |
| name        | String         | Name for this key                                          |
| fingerprint | String         | Key fingerprint                                            |
| key         | String         | OpenSSH formatted public key                               |
| attested    | Boolean        | Indicates if the key has a hardware device attestation     |
| multifactor | Array\[String] | Lists any additional factors required to use (if attested) |

#### Errors <a href="#errors-6" id="errors-6"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                         |
| ---------------- | --------------------------------------- |
| InvalidArgument  | If name or key is invalid (usually key) |
| MissingParameter | If you didn't send a key                |
| ResourceNotFound | If `:login` does not exist              |

#### CLI Command <a href="#cli-command-5" id="cli-command-5"></a>

```
triton key add --name=barbardos ~/.ssh/id_rsa.pub
```

or

```
sdc-createkey --name=barbardos ~/.ssh/id_rsa.pub
```

#### Example Request <a href="#example-request-6" id="example-request-6"></a>

```
POST /my/keys HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 455
Content-Type: application/json
Api-Version: ~8

{
  "name": "barbardos",
  "fingerprint": "03:7f:8e:ef:da:3d:3b:9e:a4:82:67:71:8c:35:2c:aa",
  "key": "ssh-rsa AAA..."
}
```

#### Example Response <a href="#example-response-6" id="example-response-6"></a>

```
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 830
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: p8gjrCZqMiZbD15TA9ymEQ==
Date: Tue, 22 Dec 2015 13:26:17 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 94423be0-a8af-11e5-a95f-e74285cfeb5b
Response-Time: 999

{
  "name": "barbardos",
  "fingerprint": "03:7f:8e:ef:da:3d:3b:9e:a4:82:67:71:8c:35:2c:aa",
  "key": "<...>"
}
```

### DeleteKey (DELETE /:login/keys/:key) <a href="#deletekey" id="deletekey"></a>

Deletes a single SSH key, by name or fingerprint.

#### Inputs <a href="#inputs-7" id="inputs-7"></a>

* None

#### Returns <a href="#returns-7" id="returns-7"></a>

* None

#### Errors <a href="#errors-7" id="errors-7"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                      |
| ---------------- | ------------------------------------ |
| ResourceNotFound | If `:login` or `:key` does not exist |

#### CLI Command <a href="#cli-command-6" id="cli-command-6"></a>

```
triton key delete barbados
```

or

```
sdc-deletekey barbados
```

**Example Request**

```
DELETE /my/keys/barbardos HTTP/1.1
Host: api.example.com
Accept: application/json
Api-Version: ~8
Content-Length: 0
```

**Example Response**

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Tue, 22 Dec 2015 13:31:43 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 5677a420-a8b0-11e5-8702-0daf2c627de5
Response-Time: 829
```


# Users

These are users (also known as sub-users); additional users who are authorized to use the same account, but are subject to the RBAC system. See the RBAC section for more details.

### ListUsers (GET /:account/users) <a href="#listusers" id="listusers"></a>

Returns a list of an account's user objects. These have the same format as the main [account](https://apidocs.joyent.com/cloudapi/#account) object.

#### Inputs <a href="#inputs-8" id="inputs-8"></a>

* None

#### Returns <a href="#returns-8" id="returns-8"></a>

Array of user objects. Each user object has the following fields:

| **Field**   | **Type**     | **Description**                           |
| ----------- | ------------ | ----------------------------------------- |
| id          | UUID         | Unique id for this user                   |
| login       | String       | Sub-user login name                       |
| email       | String       | Email address                             |
| companyName | String       | ...                                       |
| firstName   | String       | ...                                       |
| lastName    | String       | ...                                       |
| address     | String       | ...                                       |
| postalCode  | String       | ...                                       |
| city        | String       | ...                                       |
| state       | String       | ...                                       |
| country     | String       | ...                                       |
| phone       | String       | ...                                       |
| created     | ISO8601 date | When this user was created                |
| updated     | ISO8601 date | When this user's details was last updated |

#### Errors <a href="#errors-8" id="errors-8"></a>

| **Error Code**   | **Description**              |
| ---------------- | ---------------------------- |
| ResourceNotFound | If `:account` does not exist |

#### CLI Command: <a href="#cli-command-7" id="cli-command-7"></a>

```
sdc-user list
```

#### Example Request <a href="#example-request-8" id="example-request-8"></a>

```
GET /my/users HTTP/1.1
Accept: application/json
Host: api.example.com
Api-Version: ~8
Authorization: Signature keyId...
```

#### Example Response <a href="#example-response-8" id="example-response-8"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 503
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 6csVzj9aNZWB5/ZW9JsD8w==
Date: Wed, 23 Dec 2015 06:42:20 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 50182970-a940-11e5-af28-0b661ec813b9
Response-Time: 1051

[
  {
    "id": "4fc13ac6-1e7d-cd79-f3d2-96276af0d638",
    "login": "barbar",
    "email": "barbar@example.com",
    "companyName": "Example",
    "firstName": "BarBar",
    "lastName": "Jinks",
    "phone": "(123)457-6890",
    "updated": "2015-12-23T06:41:11.032Z",
    "created": "2015-12-23T06:41:11.032Z"
  },
  {
    "id": "332ce629-fcc5-45c3-e34f-e7cfbeab1327",
    "login": "san",
    "email": "san@example.com",
    "companyName": "Example Inc",
    "firstName": "San",
    "lastName": "Holo",
    "phone": "(123)456-0987",
    "updated": "2015-12-23T06:41:56.102Z",
    "created": "2015-12-23T06:41:56.102Z"
  }
]
```

### GetUser (GET /:account/users/:user) <a href="#getuser" id="getuser"></a>

Get one user for an account.

#### Inputs <a href="#inputs-9" id="inputs-9"></a>

| **Field**  | **Type** | **Description**                                  |
| ---------- | -------- | ------------------------------------------------ |
| membership | Boolean  | When given, the user roles will also be returned |

#### Returns <a href="#returns-9" id="returns-9"></a>

An array of user objects. Each user object has the following fields:

| **Field**      | **Type**     | **Description**                                                              |
| -------------- | ------------ | ---------------------------------------------------------------------------- |
| id             | UUID         | Unique id for this user                                                      |
| login          | String       | Sub-user login name                                                          |
| email          | String       | Email address                                                                |
| companyName    | String       | ...                                                                          |
| firstName      | String       | ...                                                                          |
| lastName       | String       | ...                                                                          |
| address        | String       | ...                                                                          |
| postalCode     | String       | ...                                                                          |
| city           | String       | ...                                                                          |
| state          | String       | ...                                                                          |
| country        | String       | ...                                                                          |
| phone          | String       | ...                                                                          |
| roles          | Array        | User role names (only when `membership` option is present in request)        |
| default\_roles | Array        | User active role names (only when `membership` option is present in request) |
| created        | ISO8601 date | When this user was created                                                   |
| updated        | ISO8601 date | When this user's details was last updated                                    |

#### Errors <a href="#errors-9" id="errors-9"></a>

| **Error Code**   | **Description**                         |
| ---------------- | --------------------------------------- |
| ResourceNotFound | When `:account` or `:user` do not exist |

#### CLI Command: <a href="#cli-command-8" id="cli-command-8"></a>

```
sdc-user get 4fc13ac6-1e7d-cd79-f3d2-96276af0d638
```

#### Example Request <a href="#example-request-9" id="example-request-9"></a>

```
GET /my/users/4fc13ac6-1e7d-cd79-f3d2-96276af0d638 HTTP/1.1
Accept: application/json
Host: api.example.com
Api-Version: ~8
Authorization: Signature keyId...
```

#### Example Response <a href="#example-response-9" id="example-response-9"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 253
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: p4/N2pQwLkNuvKTjaKJPOw==
Date: Wed, 23 Dec 2015 07:07:44 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: dc761fa0-a943-11e5-842f-87950f2a2edd
Response-Time: 961

{
  "id": "4fc13ac6-1e7d-cd79-f3d2-96276af0d638",
  "login": "barbar",
  "email": "barbar@example.com",
  "companyName": "Example",
  "firstName": "BarBar",
  "lastName": "Jinks",
  "phone": "(123)457-6890",
  "updated": "2015-12-23T06:41:11.032Z",
  "created": "2015-12-23T06:41:11.032Z"
}
```

### CreateUser (POST /:account/users) <a href="#createuser" id="createuser"></a>

Creates a new user under an account.

#### Inputs <a href="#inputs-10" id="inputs-10"></a>

| **Field**   | **Type** | **Description**          |
| ----------- | -------- | ------------------------ |
| email       | String   | (Required) Email address |
| login       | String   | (Required) Login         |
| password    | String   | (Required) Password      |
| companyName | String   | ...                      |
| firstName   | String   | ...                      |
| lastName    | String   | ...                      |
| address     | String   | ...                      |
| postalCode  | String   | ...                      |
| city        | String   | ...                      |
| state       | String   | ...                      |
| country     | String   | ...                      |
| phone       | String   | ...                      |

#### Returns <a href="#returns-10" id="returns-10"></a>

User object:

| **Field**   | **Type**     | **Description**                           |
| ----------- | ------------ | ----------------------------------------- |
| id          | UUID         | Unique id for this user                   |
| login       | String       | Sub-user `login` name                     |
| email       | String       | Email address                             |
| companyName | String       | ...                                       |
| firstName   | String       | ...                                       |
| lastName    | String       | ...                                       |
| address     | String       | ...                                       |
| postalCode  | String       | ...                                       |
| city        | String       | ...                                       |
| state       | String       | ...                                       |
| country     | String       | ...                                       |
| phone       | String       | ...                                       |
| created     | ISO8601 date | When this user was created                |
| updated     | ISO8601 date | When this user's details was last updated |

#### Errors <a href="#errors-10" id="errors-10"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                                                                                      |
| ---------------- | -------------------------------------------------------------------------------------------------------------------- |
| InvalidArgument  | If any of the parameters are invalid, e.g. you try to add a login name already taken by another user of your account |
| MissingParameter | If you didn't send a `login`, `email` or `password`                                                                  |
| ResourceNotFound | If `:account` does not exist                                                                                         |

#### CLI Command: <a href="#cli-command-9" id="cli-command-9"></a>

```
sdc-user create --login=bob --email=bob@test.joyent.com --password=123secret
```

#### Request: <a href="#request" id="request"></a>

```
POST /my/users HTTP/1.1
Host: api.example.com
accept: application/json
content-type: application/json
user-agent: restify/2.6.1 (x64-darwin; v8/3.14.5.9; OpenSSL/1.0.1e) node/0.10.26
accept-version: *
date: Thu, 01 May 2014 15:35:21 GMT
content-length: 79
content-md5: E9EmDJjKXMfIsi2mKbwoZA==

{
  "login": "varth",
  "email": "varth@example.com",
  "password": "123secret"
}
```

#### Response: <a href="#response" id="response"></a>

```
HTTP/1.1 201 Created
Location: /my/users/varth
Content-Type: application/json
Content-Length: 163
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: qC9LnijSqZ1I+zea5GQXvQ==
Date: Wed, 23 Dec 2015 09:42:36 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 7f1193b0-a959-11e5-9cdd-eb0b10bce309
Response-Time: 1229

{
  "id": "b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8",
  "login": "varth",
  "email": "varth@example.com",
  "updated": "2015-12-23T09:42:36.517Z",
  "created": "2015-12-23T09:42:36.517Z"
}
```

### UpdateUser (POST /:account/users/:id) <a href="#updateuser" id="updateuser"></a>

Update a user's modifiable properties.

Note: Password changes are not allowed using this endpoint; there is an additional endpoint ([ChangeUserPassword](https://apidocs.joyent.com/cloudapi/ChangeUserPassword)) for password changes so it can be selectively allowed/disallowed for users using policies.

#### Inputs <a href="#inputs-11" id="inputs-11"></a>

| **Field**   | **Type** | **Description** |
| ----------- | -------- | --------------- |
| login       | String   |                 |
| email       | String   |                 |
| companyName | String   |                 |
| firstName   | String   |                 |
| lastName    | String   |                 |
| address     | String   |                 |
| postalCode  | String   |                 |
| city        | String   |                 |
| state       | String   |                 |
| country     | String   |                 |
| phone       | String   |                 |

#### Returns <a href="#returns-11" id="returns-11"></a>

User object:

| **Field**   | **Type**     | **Description**                           |
| ----------- | ------------ | ----------------------------------------- |
| id          | UUID         | Unique id for this user                   |
| login       | String       | User login name                           |
| email       | String       | Email address                             |
| companyName | String       | ...                                       |
| firstName   | String       | ...                                       |
| lastName    | String       | ...                                       |
| address     | String       | ...                                       |
| postalCode  | String       | ...                                       |
| city        | String       | ...                                       |
| state       | String       | ...                                       |
| country     | String       | ...                                       |
| phone       | String       | ...                                       |
| created     | ISO8601 date | When this user was created                |
| updated     | ISO8601 date | When this user's details was last updated |

#### Errors <a href="#errors-11" id="errors-11"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                                                                                        |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| InvalidArgument  | If any of the parameters are invalid, e.g. you try to add a `login` name already taken by another user of your account |
| MissingParameter | If you didn't send a `login` or `email`                                                                                |
| ResourceNotFound | If `:account` or `:user` do not exist                                                                                  |

#### CLI Command: <a href="#cli-command-10" id="cli-command-10"></a>

```
sdc-user update b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8 --login=joe
```

#### Request: <a href="#request-2" id="request-2"></a>

```
POST /my/users/b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8 HTTP/1.1
Host: api.example.com
Api-Version: ~8
accept: application/json
content-type: application/json
user-agent: restify/2.6.1 (x64-darwin; v8/3.14.5.9; OpenSSL/1.0.1e) node/0.10.26
date: Thu, 24 Dec 2015 10:30:44 GMT
content-length: 79
content-md5: E9EmDJjKXMfIsi2mKbwoZA==

{
  "login": "joe",
}
```

#### Response: <a href="#response-2" id="response-2"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 161
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 4Sn7xQHfoc1+LvLkA2KbNA==
Date: Thu, 24 Dec 2015 10:30:45 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 63a27380-aa29-11e5-ace8-d79496f2469d
Response-Time: 1148

{
  "id": "b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8",
  "login": "joe",
  "email": "varth@example.com",
  "updated": "2015-12-24T10:28:59.634Z",
  "created": "2015-12-23T09:42:36.517Z"
}
```

### ChangeUserPassword (POST /:account/users/:user/change\_password) <a href="#changeuserpassword" id="changeuserpassword"></a>

This is a separate rule for password changes, so different policies can be used for an user trying to modify other data, or only their own password.

#### Inputs <a href="#inputs-12" id="inputs-12"></a>

| **Field**              | **Type** | **Description**              |
| ---------------------- | -------- | ---------------------------- |
| password               | String   | ...                          |
| password\_confirmation | String   | string must match `password` |

#### Returns <a href="#returns-12" id="returns-12"></a>

User object:

| **Field**   | **Type**       | **Description**                           |
| ----------- | -------------- | ----------------------------------------- |
| id          | UUID           | Unique id for the user                    |
| login       | String         | User login name                           |
| email       | String         | Email address                             |
| companyName | String         | ...                                       |
| firstName   | String         | ...                                       |
| lastName    | String         | ...                                       |
| address     | String         | ...                                       |
| postalCode  | String         | ...                                       |
| city        | String         | ...                                       |
| state       | String         | ...                                       |
| country     | String         | ...                                       |
| phone       | String         | ...                                       |
| created     | Date (ISO8601) | When this user was created                |
| updated     | Date (ISO8601) | When this user's details was last updated |

#### Errors <a href="#errors-12" id="errors-12"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                                      |
| ---------------- | -------------------------------------------------------------------- |
| InvalidArgument  | The provided `password` and `password\_confirmation` didn't match    |
| MissingParameter | Either `password` or `password\_confirmation` parameters are missing |
| ResourceNotFound | If `:account` or `:user` do not exist                                |

#### CLI Command: <a href="#cli-command-11" id="cli-command-11"></a>

```
sdc-user change-password b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8 --password=foo123bar --password-confirmation=foo123bar
```

#### Example Request <a href="#example-request-10" id="example-request-10"></a>

```
POST /my/users/b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8/change_password HTTP/1.1
Accept: application/json
Content-Type: application/json
Host: api.example.com
Api-Version: ~8
Content-Length: 40
Authorization: Signature keyId...

{
    "password": "foo123bar",
    "password_confirmation": "foo123bar"
}
```

#### Example Response <a href="#example-response-10" id="example-response-10"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 161
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: qU6CaBlWpuehWaj0IdtPCw==
Date: Thu, 24 Dec 2015 10:34:51 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: f6338220-aa29-11e5-8484-a9b10ef4e687
Response-Time: 1297

{
  "id": "b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8",
  "login": "joe",
  "email": "varth@example.com",
  "updated": "2015-12-24T10:34:51.790Z",
  "created": "2015-12-23T09:42:36.517Z"
}
```

### DeleteUser (DELETE /:account/users/:user) <a href="#deleteuser" id="deleteuser"></a>

Remove a user. They will no longer be able to use this API.

#### Inputs <a href="#inputs-13" id="inputs-13"></a>

* None

#### Returns <a href="#returns-13" id="returns-13"></a>

* None

#### Errors <a href="#errors-13" id="errors-13"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                                                                           |
| ---------------- | --------------------------------------------------------------------------------------------------------- |
| ResourceNotFound | If `:account` does not exist or there isn't a user with either the `login` or `id` given as `:user` value |

#### CLI Command: <a href="#cli-command-12" id="cli-command-12"></a>

```
sdc-user delete b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8
```

**Example Request**

```
DELETE /my/users/b5c9cf06-b7de-4c11-9b66-8ace6cb92ee8 HTTP/1.1
Host: api.example.com
Accept: application/json
Api-Version: ~8
Content-Length: 0
```

**Example Response**

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 24 Dec 2015 10:36:18 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 29bcb710-aa2a-11e5-b9f6-05ee86f81e61
Response-Time: 997
```


# Images

An image contains the software packages that will be available on newly-provisioned instance. In the case of hardware virtual machines, the image also includes the operating system.

### ListImages (GET /:login/images) <a href="#listimages" id="listimages"></a>

Provides a list of images available in this datacenter.

Note: Currently, *Docker* images are not included in this endpoint's responses. You must use `docker images` against the [docker](https://apidocs.joyent.com/docker) service for this datacenter.

#### Inputs <a href="#inputs-30" id="inputs-30"></a>

The following optional query parameters are available to filter the list of images:

| **Field** | **Type** | **Description**                                                                                                                                       |
| --------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| name      | String   | The "friendly" name for this image                                                                                                                    |
| os        | String   | The underlying operating system for this image                                                                                                        |
| version   | String   | The version for this image                                                                                                                            |
| public    | Boolean  | Filter public/private images                                                                                                                          |
| state     | String   | Filter on image [state](https://images.joyent.com/docs/#manifest-state). By default only active images are shown. Use `?state=all` to list all images |
| owner     | String   | Filter on owner UUID                                                                                                                                  |
| type      | String   | Filter on image type. The types changed in v8.0.0                                                                                                     |

#### Returns <a href="#returns-30" id="returns-30"></a>

An array of images. Image objects include the following fields:

| **Field**                | **Type**     | **Description**                                                                                                                                                                                                                                 |
| ------------------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                       | UUID         | Unique id for this image                                                                                                                                                                                                                        |
| name                     | String       | The "friendly" name for this image                                                                                                                                                                                                              |
| os                       | String       | The underlying operating system for this image                                                                                                                                                                                                  |
| version                  | String       | The version for this image                                                                                                                                                                                                                      |
| type                     | String       | What kind of image this is. The values differ after v8.0.0+                                                                                                                                                                                     |
| requirements             | Object       | Contains a grouping of various minimum requirements for provisioning an instance with this image. For example 'password' indicates that a password must be provided                                                                             |
| requirements.max\_ram    | String       | Indicates the maximum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.max\_memory | String       | Indicates the maximum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.min\_ram    | String       | Indicates the minimum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.min\_memory | String       | Indicates the minimum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.brand       | String       | Indicates which brand has to be used in the VM manifest to provision a VM based on this image.                                                                                                                                                  |
| homepage                 | String       | The URL for a web page with more detailed information for this image                                                                                                                                                                            |
| files                    | Array        | An array of image files that make up each image. Currently only a single file per image is supported                                                                                                                                            |
| files\[0].compression    | String       | The type of file compression used for the image file. One of 'bzip2', 'gzip', 'none'                                                                                                                                                            |
| files\[0].sha1           | String       | SHA-1 hex digest of the file content. Used for corruption checking                                                                                                                                                                              |
| files\[0].size           | Number       | File size in bytes                                                                                                                                                                                                                              |
| published\_at            | ISO8859 date | The time this image has been made publicly available                                                                                                                                                                                            |
| owner                    | String       | The UUID of the user who owns this image                                                                                                                                                                                                        |
| public                   | Boolean      | Indicates if this image is publicly available                                                                                                                                                                                                   |
| state                    | String       | The current state of the image. One of 'active', 'unactivated', 'disabled', 'creating', 'failed'                                                                                                                                                |
| tags                     | Object       | An object of key/value pairs that allows clients to categorize images by any given criteria                                                                                                                                                     |
| eula                     | String       | URL of the End User License Agreement (EULA) for the image                                                                                                                                                                                      |
| acl                      | Array        | Access Control List. An array of account UUIDs given access to a private image. The field is only relevant to private images.                                                                                                                   |
| error                    | Object       | If `state=="failed"`, resulting from [CreateImageFromMachine](https://apidocs.joyent.com/cloudapi/#CreateImageFromMachine) failure, then there may be an error object of the form `{"code": "<string error code>", "message": "<string desc>"}` |
| error.code               | String       | A CamelCase string code for this error, e.g. "PrepareImageDidNotRun". See [GetImage](https://apidocs.joyent.com/cloudapi/#GetImage) docs for a table of error.code values                                                                       |
| error.message            | String       | A short description of the image creation failure                                                                                                                                                                                               |

#### Errors <a href="#errors-30" id="errors-30"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**           |
| ---------------- | ------------------------- |
| ResourceNotFound | If `login` does not exist |

#### CLI Command <a href="#cli-command-33" id="cli-command-33"></a>

```
triton image list
```

or

```
sdc-listimages
```

#### Example Request <a href="#example-request-28" id="example-request-28"></a>

```
GET /my/images HTTP/1.1
Host: api.example.com
Authorization: Signature keyId...
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-28" id="example-response-28"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 611
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 9eDxMdIxc+3aED7Z3qyL8w==
Date: Thu, 21 Jan 2016 07:57:59 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: af34a510-c014-11e5-9c73-6767e338bf5d
Response-Time: 1506

[
  {
    "id": "2b683a82-a066-11e3-97ab-2faa44701c5a",
    "name": "base",
    "version": "13.4.0",
    "os": "smartos",
    "requirements": {},
    "type": "zone-dataset",
    "description": "A 32-bit SmartOS image with just essential packages installed. Ideal for users who are comfortable with setting up their own environment and tools.",
    "files": [
      {
        "compression": "gzip",
        "sha1": "3bebb6ae2cdb26eef20cfb30fdc4a00a059a0b7b",
        "size": 110742036
      }
    ],
    "tags": {
      "role": "os",
      "group": "base-32"
    },
    "homepage": "https://docs.joyent.com/images/smartos/base",
    "published_at": "2014-02-28T10:50:42Z",
    "owner": "930896af-bf8c-48d4-885c-6573a94b1853",
    "public": true,
    "state": "active"
  },
  ...
]
```

### GetImage (GET /:login/images/:id) <a href="#getimage" id="getimage"></a>

Gets an individual image by `id`.

#### Inputs <a href="#inputs-31" id="inputs-31"></a>

None

#### Returns <a href="#returns-31" id="returns-31"></a>

| **Field**                | **Type**     | **Description**                                                                                                                                                                                                                                 |
| ------------------------ | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                       | UUID         | Unique id for this image                                                                                                                                                                                                                        |
| name                     | String       | The "friendly" name for this image                                                                                                                                                                                                              |
| os                       | String       | The underlying operating system for this image                                                                                                                                                                                                  |
| version                  | String       | The version for this image                                                                                                                                                                                                                      |
| type                     | String       | What kind of image this is. The values differ after v8.0.0+                                                                                                                                                                                     |
| requirements             | Object       | Contains a grouping of various minimum requirements for provisioning an instance with this image. For example 'password' indicates that a password must be provided                                                                             |
| requirements.max\_ram    | String       | Indicates the maximum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.max\_memory | String       | Indicates the maximum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.min\_ram    | String       | Indicates the minimum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.min\_memory | String       | Indicates the minimum RAM requirement that must be provided in the VM manifest to provision a VM based on this image.                                                                                                                           |
| requirements.brand       | String       | Indicates which brand has to be used in the VM manifest to provision a VM based on this image.                                                                                                                                                  |
| homepage                 | String       | The URL for a web page with more detailed information for this image                                                                                                                                                                            |
| files                    | Array        | An array of image files that make up each image. Currently only a single file per image is supported                                                                                                                                            |
| files\[0].compression    | String       | The type of file compression used for the image file. One of 'bzip2', 'gzip', 'none'                                                                                                                                                            |
| files\[0].sha1           | String       | SHA-1 hex digest of the file content. Used for corruption checking                                                                                                                                                                              |
| files\[0].size           | Number       | File size in bytes                                                                                                                                                                                                                              |
| published\_at            | ISO8859 date | The time this image has been made publicly available                                                                                                                                                                                            |
| owner                    | String       | The UUID of the user who owns this image                                                                                                                                                                                                        |
| public                   | Boolean      | Indicates if this image is publicly available                                                                                                                                                                                                   |
| state                    | String       | The current state of the image. One of 'active', 'unactivated', 'disabled', 'creating', 'failed'                                                                                                                                                |
| tags                     | Object       | An object of key/value pairs that allows clients to categorize images by any given criteria                                                                                                                                                     |
| eula                     | String       | URL of the End User License Agreement (EULA) for the image                                                                                                                                                                                      |
| acl                      | Array        | Access Control List. An array of account UUIDs given access to a private image. The field is only relevant to private images.                                                                                                                   |
| error                    | Object       | If `state=="failed"`, resulting from [CreateImageFromMachine](https://apidocs.joyent.com/cloudapi/#CreateImageFromMachine) failure, then there may be an error object of the form `{"code": "<string error code>", "message": "<string desc>"}` |
| error.code               | String       | A CamelCase string code for this error, e.g. "PrepareImageDidNotRun". See [GetImage](https://apidocs.joyent.com/cloudapi/#GetImage) docs for a table of error.code values                                                                       |
| error.message            | String       | A short description of the image creation failure                                                                                                                                                                                               |

Possible `error.code` values:

| **error.code**        | **Details**                                                                                                                                                                                                                                                                                                                                                         |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PrepareImageDidNotRun | This typically means that the target harware virtual machine (e.g. Linux) has old guest tools that pre-date the image creation feature. Guest tools can be upgraded with installers at <https://download.joyent.com/pub/guest-tools/>. Other possibilities are: a boot time greater than the five-minute timeout, or a bug or crash in the image-preparation script |
| VmHasNoOrigin         | Origin image data could not be found for the instance. Typically this is for an instance *migrated* before image creation support was added                                                                                                                                                                                                                         |
| NotSupported          | Indicates an error due to functionality that isn't currently supported. One example is that custom image creation of an instance based on a custom image isn't currently supported                                                                                                                                                                                  |
| InternalError         | A catch-all error for unexpected or internal errors                                                                                                                                                                                                                                                                                                                 |

#### Errors <a href="#errors-31" id="errors-31"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

#### CLI Command <a href="#cli-command-34" id="cli-command-34"></a>

```
triton image get 2b683a82-a066-11e3-97ab-2faa44701c5a
```

or

```
sdc-getimage 2b683a82-a066-11e3-97ab-2faa44701c5a
```

**Example Request**

```
GET /my/images/2b683a82-a066-11e3-97ab-2faa44701c5a HTTP/1.1
Host: api.example.com
Authorization: Signature keyId...
Accept: application/json
Api-Version: ~8
```

**Example Response**

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 609
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 42n5PWY5xZP0lnjdMb7Omg==
Date: Thu, 21 Jan 2016 08:00:09 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: fd5679d0-c014-11e5-a8f8-951890fd520a
Response-Time: 876

{
  "id": "2b683a82-a066-11e3-97ab-2faa44701c5a",
  "name": "base",
  "version": "13.4.0",
  "os": "smartos",
  "requirements": {},
  "type": "zone-dataset",
  "description": "A 32-bit SmartOS image with just essential packages installed. Ideal for users who are comfortable with setting up their own environment and tools.",
  "files": [
    {
      "compression": "gzip",
      "sha1": "3bebb6ae2cdb26eef20cfb30fdc4a00a059a0b7b",
      "size": 110742036
    }
  ],
  "tags": {
    "role": "os",
    "group": "base-32"
  },
  "homepage": "https://docs.joyent.com/images/smartos/base",
  "published_at": "2014-02-28T10:50:42Z",
  "owner": "930896af-bf8c-48d4-885c-6573a94b1853",
  "public": true,
  "state": "active"
}
```

### DeleteImage (DELETE /:login/images/:id) <a href="#deleteimage" id="deleteimage"></a>

Delete an image. Caller must be the owner of the image to delete it.

#### Inputs <a href="#inputs-32" id="inputs-32"></a>

None

#### Returns <a href="#returns-32" id="returns-32"></a>

Responds with HTTP 204 'No Content'.

#### Errors <a href="#errors-32" id="errors-32"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-35" id="cli-command-35"></a>

```
triton image delete 2b683a82-a066-11e3-97ab-2faa44701c5a
```

or

```
sdc-deleteimage 2b683a82-a066-11e3-97ab-2faa44701c5a
```

**Example Request**

```
DELETE /my/images/2b683a82-a066-11e3-97ab-2faa44701c5a HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

**Example Response**

```
HTTP/1.1 204 No Content
Content-Type: application/json
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 83MuHssrpOMWvPXLB9stgg==
Date: Thu, 21 Jan 2016 08:02:08 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 440f5590-c015-11e5-b5f9-2b49303f7fc4
Response-Time: 1262
```

### ExportImage (POST /:login/images/:id?action=export) <a href="#exportimage" id="exportimage"></a>

Exports an image to the specified Manta path. Caller must be the owner of the image, and the correspondent Manta path prefix, in order to export it. Both the image manifest and the image file will be exported, and their filenames will default to the following format when the specified manta path is a directory:

```
<manta_path>/NAME-VER.imgmanifest
<manta_path>/NAME-VER.zfs.FILE-EXT
```

Where NAME is the image name and VER is the image version. FILE-EXT is the file extension of the image file. As an example, exporting a foo-1.0.0 image to /user/stor/cloudapi would result in the following files being exported:

```
/user/stor/cloudapi/foo-1.0.0.imgmanifest
/user/stor/cloudapi/foo-1.0.0.zfs.gz
```

By contrast, if the basename of the given prefix is not a directory, then "MANTA\_PATH.imgmanifest" and "MANTA\_PATH.zfs\[.EXT]" are created. As an example, the following shows how to export foo-1.0.0 with a custom name:

```
/my/images/<uuid>?action=export&manta_path=/user/stor/my-image

/user/stor/my-image.imgmanifest
/user/stor/my-image.zfs.gz
```

#### Inputs <a href="#inputs-33" id="inputs-33"></a>

| **Field**   | **Type** | **Description**                                 |
| ----------- | -------- | ----------------------------------------------- |
| manta\_path | String   | Manta path prefix used when exporting the image |

#### Returns <a href="#returns-33" id="returns-33"></a>

A Manta location response object. It provides the properties that allow a CloudAPI user to retrieve the image file and manifest from Manta: manta\_url, image\_path, manifest\_path.

#### Errors <a href="#errors-33" id="errors-33"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-36" id="cli-command-36"></a>

```
sdc-exportimage --mantaPath=/user/stor/my-image 0c428eb9-7f03-4bb0-ac9f-c0718945d604
```

**Example Request**

```
POST /my/images/e42f8c84-bbea-11e2-b920-078fab2aab1f?action=export&manta_path=/user/stor/my-image HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

**Example Response**

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 150
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST, DELETE
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: qSUhN+dwdJKEFlcyrUdBiw==
Date: Thu, 21 Jan 2016 08:00:09 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 8180ad80-14ef-11e3-a62d-89e8106c294e
Response-Time: 670

{
  "manta_url": "https://us-east.manta.joyent.com",
  "image_path": "/user/stor/my-image.zfs.gz",
  "manifest_path": "/user/stor/my-image.imgmanifest"
}
```

### CreateImageFromMachine (POST /:login/images) <a href="#createimagefrommachine" id="createimagefrommachine"></a>

Create a new custom image from an instance. The typical process is:

1. Customize an instance the way you want it.
2. Call this endpoint (CreateImageFromMachine) to create a new image.
3. Repeat from step 1 if more customizations are desired with different images.
4. Use the new image(s) for provisioning via [CreateMachine](https://apidocs.joyent.com/cloudapi/#CreateMachine).

#### Inputs <a href="#inputs-34" id="inputs-34"></a>

All inputs except `machine` are image manifest fields as defined by [the IMGAPI docs](https://images.joyent.com/docs/#image-manifests). Note that not all fields listed there can be specified here.

| **Field**   | **Type** | **Required?** | **Description**                                                                                                                    |
| ----------- | -------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| machine     | UUID     | Yes           | The prepared and stopped instance UUID from which the image is to be created                                                       |
| name        | String   | Yes           | The name of the custom image, e.g. "my-image". See the [IMGAPI docs](https://images.joyent.com/docs/#manifest-name) for details    |
| version     | String   | Yes           | The version of the custom image, e.g. "1.0.0". See the [IMGAPI docs](https://images.joyent.com/docs/#manifest-version) for details |
| description | String   | No            | The image [description](https://images.joyent.com/docs/#manifest-description)                                                      |
| homepage    | String   | No            | The image [homepage](https://images.joyent.com/docs/#manifest-homepage)                                                            |
| eula        | String   | No            | The image [eula](https://images.joyent.com/docs/#manifest-eula)                                                                    |
| acl         | String   | No            | The image [acl](https://images.joyent.com/docs/#manifest-acl)                                                                      |
| tags        | String   | No            | The image [tags](https://images.joyent.com/docs/#manifest-tags)                                                                    |

#### Returns <a href="#returns-34" id="returns-34"></a>

| **Field**             | **Type**     | **Description**                                                                                                                                                     |
| --------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                    | UUID         | Unique id for this image                                                                                                                                            |
| name                  | String       | The "friendly" name for this image                                                                                                                                  |
| os                    | String       | The underlying operating system for this image                                                                                                                      |
| version               | String       | The version for this image                                                                                                                                          |
| type                  | String       | What kind of image this is. The values differ after v8.0.0+                                                                                                         |
| requirements          | Object       | Contains a grouping of various minimum requirements for provisioning an instance with this image. For example 'password' indicates that a password must be provided |
| homepage              | String       | The URL for a web page with more detailed information for this image                                                                                                |
| files                 | Array        | An array of image files that make up each image. Currently only a single file per image is supported                                                                |
| files\[0].compression | String       | The type of file compression used for the image file. One of 'bzip2', 'gzip', 'none'                                                                                |
| files\[0].sha1        | String       | SHA-1 hex digest of the file content. Used for corruption checking                                                                                                  |
| files\[0].size        | Number       | File size in bytes                                                                                                                                                  |
| published\_at         | ISO8859 date | The time this image has been made publicly available                                                                                                                |
| owner                 | String       | The UUID of the user who owns this image                                                                                                                            |
| public                | Boolean      | Indicates if this image is publicly available                                                                                                                       |
| state                 | String       | The current state of the image. One of 'active', 'unactivated', 'disabled', 'creating', 'failed'                                                                    |
| tags                  | Object       | An object of key/value pairs that allows clients to categorize images by any given criteria                                                                         |
| eula                  | String       | URL of the End User License Agreement (EULA) for the image                                                                                                          |
| acl                   | Array        | Access Control List. An array of account UUIDs given access to a private image. The field is only relevant to private images                                        |

#### Errors <a href="#errors-34" id="errors-34"></a>

For general errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses). Some typical and specific errors for this endpoint:

| **Error Code**                 | **Description**                                                                                                |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| InsufficientServerVersionError | The `machine` given is running on a server that is too old                                                     |
| NotAvailable                   | Typically this indicates that image creation is not supported for the OS of the given hardware virtual machine |

#### Example CLI Command <a href="#example-cli-command" id="example-cli-command"></a>

```
triton image create a44f2b9b-e7af-f548-b0ba-4d9270423f1a my-custom-image 1.0.0
```

or

```
sdc-createimagefrommachine --machine=a44f2b9b-e7af-f548-b0ba-4d9270423f1a --name=my-custom-image --imageVersion=1.0.0
```

**Example HTTP Request**

```
POST /my/images HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8

{
  "machine": "a44f2b9b-e7af-f548-b0ba-4d9270423f1a",
  "name": "my-custom-image",
  "version": "1.0.0"
}
```

**Example HTTP Response**

```
HTTP/1.1 201 Created
x-joyent-jobid: 0b30ef20-d622-436a-9c30-7376ba7d904c
Location: /admin/images/b87616a2-7a49-4e02-a71d-2e0ce5a2f037
Content-Type: application/json
Content-Length: 125
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 2sEZ45LmhRiretMPn5sqVA==
Date: Thu, 21 Jan 2016 08:00:09 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 88af23b0-f952-11e2-8f2c-fff0ec35f4ce
Response-Time: 160

{
    "id": "62306cd7-7b8a-c5dd-d44e-8491c83b9974",
    "name": "my-custom-image",
    "version": "1.2.3",
    "requirements": {},
    "owner": "47034e57-42d1-0342-b302-00db733e8c8a",
    "public": false,
    "state": "creating"
}
```

### ImportImageFromDatacenter (POST /:login/images?action=import-from-datacenter) <a href="#importimagefromdatacenter" id="importimagefromdatacenter"></a>

This will copy the image with `id` from the source `datacenter` into this datacenter. The copied image will retain all fields (e.g. `id`, `published_at`) as the original image. All incremental images in the origin chain will also be copied.

You can use [triton datacenters](https://apidocs.joyent.com/cloudapi/#ListDatacenters) to view the list of datacenter names in the current cloud.

#### Inputs <a href="#inputs-35" id="inputs-35"></a>

The following query parameters are required, these parameters will be used to identify the image to be copied.

| **Field**  | **Type** | **Description**                                               |
| ---------- | -------- | ------------------------------------------------------------- |
| datacenter | String   | The datacenter name from where the image will be copied from. |
| id         | UUID     | The id of the image to be copied.                             |

#### Returns <a href="#returns-35" id="returns-35"></a>

On success, an Image object is returned. See [GetImage](https://apidocs.joyent.com/cloudapi/#GetImage) for the fields that are returned in the image object.

#### Errors <a href="#errors-35" id="errors-35"></a>

For general errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses). Some typical and specific errors for this endpoint:

| **Error Code**              | **Description**                                             |
| --------------------------- | ----------------------------------------------------------- |
| ImageUuidAlreadyExistsError | The image with `id` already exists in this datacenter.      |
| UnauthorizedError           | If the source image is owned by the admin.                  |
| OriginIsNotActiveError      | If one of the incremental (origin) images is not activated. |

#### Example CLI Command <a href="#example-cli-command-2" id="example-cli-command-2"></a>

```
triton image copy 7eed8e50-e452-428d-9131-bf056aa911bd us-west-1
```

**Example HTTP Request**

```
POST /my/images?action=import-from-datacenter&datacenter=us-west-1&id=7eed8e50-e452-428d-9131-bf056aa911bd HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~9

{}
```

**Example HTTP Response**

```
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 125
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 2sEZ45LmhRiretMPn5sqVA==
Date: Thu, 21 Jan 2018 08:00:09 GMT
Server: cloudapi/9.2.0
Api-Version: 9.0.0
Request-Id: 49af23b0-f952-11e2-8f2c-fff0ec35f4ce
Response-Time: 460

{
  "id": "7eed8e50-e452-428d-9131-bf056aa911bd",
  "name": "myimage",
  "version": "1.4.0",
  "os": "smartos",
  "requirements": {},
  "type": "zone-dataset",
  "description": "A custom image used to test stuff.",
  "files": [
    {
      "compression": "gzip",
      "sha1": "3bebb6ae2cdb26eef20cfb30fdc4a00a059a0b7b",
      "size": 110742036
    }
  ],
  "published_at": "2015-02-28T10:50:42Z",
  "owner": "930896af-bf8c-48d4-885c-6573a94b1853",
  "public": false,
  "state": "active"
}
```

### UpdateImage (POST /:login/images/:id?action=update) <a href="#updateimage" id="updateimage"></a>

Updates metadata about an image.

#### Inputs <a href="#inputs-36" id="inputs-36"></a>

Only the image attributes listed below can be updated.

| **Field**   | **Type** | **Description**                                                                                                                    |
| ----------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| name        | String   | The name of the custom image, e.g. "my-image". See the [IMGAPI docs](https://images.joyent.com/docs/#manifest-name) for details    |
| version     | String   | The version of the custom image, e.g. "1.0.0". See the [IMGAPI docs](https://images.joyent.com/docs/#manifest-version) for details |
| description | String   | The image [description](https://images.joyent.com/docs/#manifest-description)                                                      |
| homepage    | String   | The image [homepage](https://images.joyent.com/docs/#manifest-homepage)                                                            |
| eula        | String   | The image [eula](https://images.joyent.com/docs/#manifest-eula)                                                                    |
| acl         | String   | The image [acl](https://images.joyent.com/docs/#manifest-acl)                                                                      |
| tags        | String   | The image [tags](https://images.joyent.com/docs/#manifest-tags)                                                                    |

#### Returns <a href="#returns-36" id="returns-36"></a>

An updated image object.

| **Field**             | **Type**     | **Description**                                                                                                                                                     |
| --------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                    | UUID         | Unique id for this image                                                                                                                                            |
| name                  | String       | The "friendly" name for this image                                                                                                                                  |
| os                    | String       | The underlying operating system for this image                                                                                                                      |
| version               | String       | The version for this image                                                                                                                                          |
| type                  | String       | What kind of image this is. The values differ after v8.0.0+                                                                                                         |
| requirements          | Object       | Contains a grouping of various minimum requirements for provisioning an instance with this image. For example 'password' indicates that a password must be provided |
| homepage              | String       | The URL for a web page with more detailed information for this image                                                                                                |
| files                 | Array        | An array of image files that make up each image. Currently only a single file per image is supported                                                                |
| files\[0].compression | String       | The type of file compression used for the image file. One of 'bzip2', 'gzip', 'none'                                                                                |
| files\[0].sha1        | String       | SHA-1 hex digest of the file content. Used for corruption checking                                                                                                  |
| files\[0].size        | Number       | File size in bytes                                                                                                                                                  |
| published\_at         | ISO8859 date | The time this image has been made publicly available                                                                                                                |
| owner                 | String       | The UUID of the user who owns this image                                                                                                                            |
| public                | Boolean      | Indicates if this image is publicly available                                                                                                                       |
| state                 | String       | The current state of the image. One of 'active', 'unactivated', 'disabled', 'creating', 'failed'                                                                    |
| tags                  | Object       | An object of key/value pairs that allows clients to categorize images by any given criteria                                                                         |
| eula                  | String       | URL of the End User License Agreement (EULA) for the image                                                                                                          |
| acl                   | Array        | Access Control List. An array of account UUIDs given access to a private image. The field is only relevant to private images                                        |

#### Errors <a href="#errors-36" id="errors-36"></a>

For general errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses). Some typical and specific errors for this endpoint:

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### Example CLI Command <a href="#example-cli-command-3" id="example-cli-command-3"></a>

```
sdc-updateimage --name=my-renamed-image eca995fe-b904-11e3-b05a-83a4899322dc
```

**Example HTTP Request**

```
POST /my/images/eca995fe-b904-11e3-b05a-83a4899322dc?action=update HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8

{
  "name": "my-renamed-image",
}
```

**Example HTTP Response**

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 125
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 2sEZ45LmhRiretMPn5sqVA==
Date: Thu, 21 Jan 2016 08:00:09 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: b8e43c60-b904-11e3-93b7-1f685001b0c3
Response-Time: 135

{
  "id": "eca995fe-b904-11e3-b05a-83a4899322dc",
  "name": "my-renamed-image",
  "version": "1.0.0",
  "os": "smartos",
  "requirements": {},
  "type": "zone-dataset",
  "published_at": "2013-11-25T17:44:54Z",
  "owner": "47034e57-42d1-0342-b302-00db733e8c8a",
  "public": true,
  "state": "active"
}
```

### CloneImage (POST /:login/images/:id?action=clone) <a href="#cloneimage" id="cloneimage"></a>

Creates an independent copy of the source image. The `login` account must be on the source image ACL to be able to make an image clone.

The resulting cloned image will have the same properties as the source image, but the cloned image will have a different id, it will be owned by the `login` account and the image will have an empty ACL.

All incremental images in the image origin chain that are not operator images (i.e. are not owned by admin) will also be cloned, though all cloned incremental images will have state `disabled` so that they are not visible in the default image listings.

#### Inputs <a href="#inputs-37" id="inputs-37"></a>

None.

#### Returns <a href="#returns-37" id="returns-37"></a>

A cloned image object. See [GetImage](https://apidocs.joyent.com/cloudapi/#GetImage) docs for the image fields returned.

#### Errors <a href="#errors-37" id="errors-37"></a>

For general errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses). Some typical and specific errors for this endpoint:

| **Error Code**     | **Description**                                       |
| ------------------ | ----------------------------------------------------- |
| ResourceNotFound   | If `:login` or `:id` does not exist.                  |
| NotImageOwnerError | If your account is not the owner of the image.        |
| ImageNotShared     | When the given image is not shared with your account. |

#### Example CLI Command <a href="#example-cli-command-4" id="example-cli-command-4"></a>

```
triton image clone eca995fe-b904-11e3-b05a-83a4899322dc
```

**Example HTTP Request**

```
POST /my/images/eca995fe-b904-11e3-b05a-83a4899322dc?action=clone HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

**Example HTTP Response**

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 125
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD, POST
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 2sEZ45LmhRiretMPn5sqVA==
Date: Thu, 21 Jan 2016 08:00:09 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: f8e43c60-b904-11e3-93b7-1f685001b0c3
Response-Time: 135

{
  "id": "4ca995fe-b904-11e3-b05a-83a4899322dc",
  "name": "some-image",
  "version": "1.0.0",
  "os": "smartos",
  "requirements": {},
  "type": "zone-dataset",
  "published_at": "2017-11-25T17:44:54Z",
  "owner": "77034e57-42d1-0342-b302-00db733e8c8a",
  "public": true,
  "state": "active"
}
```


# Instances

Triton supports three different types of instances:Docker containers. OS-virtualized instances managed through the Docker client.Infrastructure containers. More traditional OS-virtualized instances

Triton supports three different types of instances:

* Docker containers. OS-virtualized instances managed through the Docker client.
* Infrastructure containers. More traditional OS-virtualized instances running SmartOS or more Linux distributions.
* Hardware-virtualized machines. Hardware-virtualized instances (KVM) for running legacy or special-purpose operating systems.

Infrastructure and Docker containers are lightweight, offering the most performance, observability and operational flexibility. Harware-virtualized machines are useful for non-SmartOS or non-Linux stacks.

### ListMachines (GET /:login/machines) <a href="#listmachines" id="listmachines"></a>

Lists all instances we have on record for your account. If you have a large number of instances, you can filter using the input parameters listed below. Note that deleted instances are returned only if the instance history has not been purged from Triton.

You can paginate this API by passing in `offset` and `limit`. HTTP responses will contain the additional headers `x-resource-count` and `x-query-limit`. If `x-resource-count` is less than `x-query-limit`, you're done, otherwise call the API again with `offset` set to `offset` + `limit` to fetch additional instances.

Note that there is a `HEAD /:login/machines` form of this API, so you can retrieve the number of instances without retrieving a JSON describing the instances themselves.

#### Inputs <a href="#inputs-40" id="inputs-40"></a>

| **Field**   | **Type** | **Description**                                                                                                     |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| type        | String   | (deprecated) The type of instance (virtualmachine or smartmachine)                                                  |
| brand       | String   | (v8.0+) The type of instance (e.g. lx)                                                                              |
| name        | String   | Machine name to find (will make your list size 1, or 0 if nothing found)                                            |
| image       | String   | Image id; returns instances provisioned with that image                                                             |
| state       | String   | The current state of the instance (e.g. running)                                                                    |
| memory      | Number   | The current size of the RAM deployed for the instance (in MiB)                                                      |
| tombstone   | Boolean  | Include destroyed and failed instances available in instance history                                                |
| limit       | Number   | Return a max of N instances; default is 1000 (which is also the maximum allowable result set size)                  |
| offset      | Number   | Get a `limit` number of instances starting at this `offset`                                                         |
| tag.$name   | String   | An arbitrary set of tags can be used for querying, assuming they are prefixed with "tag."                           |
| docker      | Boolean  | Whether to only list Docker instances, or only non-Docker instances, if present. Defaults to showing all instances. |
| credentials | Boolean  | Whether to include the generated credentials for instances, if present. Defaults to false                           |

Note that if the special input `tags=*` is provided, any other input will be completely ignored and the response will return all instances with any tag.

Be aware that in the case of instances created with vmadm directly (i.e. not through CloudAPI), ips, networks, primaryIp and package may be in a different format than expected. The `ips` array can contain the value "dhcp", not just IP strings, the `networks` array can contain null values for networks that CloudAPI was unable to determine (e.g. as a result of a "dhcp" IP), `primaryIp` too can have the value of "dhcp", and the package string can be empty instead of a UUID. Unless ops is bypassing CloudAPI and creating instances directly, it is unlikely you need concern yourself with this caveat.

#### Returns <a href="#returns-40" id="returns-40"></a>

An array of instance objects, which contain:

| **Field**            | **Type**                  | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id                   | UUID                      | Unique id for this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| name                 | String                    | The "friendly" name for this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| type                 | String                    | (deprecated) The type of instance (virtualmachine or smartmachine)                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| brand                | String                    | (v8.0+) The type of instance (e.g. lx)                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| state                | String                    | The current state of this instance (e.g. running)                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| image                | String                    | The image id this instance was provisioned with                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| memory               | Number                    | The amount of RAM this instance has (in MiB)                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| disk                 | Number                    | The amount of disk this instance has (in MiB)                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| disks                | Array                     | An array of disk objects (bhyve)                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| metadata             | Object\[String => String] | Any additional metadata this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| tags                 | Object\[String => String] | Any tags this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| created              | ISO8601 date              | When this instance was created                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| updated              | ISO8601 date              | When this instance's details was last updated                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| docker               | Boolean                   | Whether this instance is a Docker container, if present                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ips                  | Array\[String]            | The IP addresses this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| networks             | Array\[String]            | The network UUIDs of the nics this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| primaryIp            | String                    | The IP address of the primary NIC of this instance. The "primary" NIC is used to determine the default gateway for an instance. Commonly it is also on an external network (i.e. accessible on the public internet) and hence usable for SSH'ing into an instance, but not always. (Note: In future Triton versions it will be possible to have multiple IPv4 and IPv6 addresses on a particular NIC, at which point the current definition of `primaryIp` will be ambiguous and will need to change.) |
| firewall\_enabled    | Boolean                   | Whether firewall rules are enforced on this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| deletion\_protection | Boolean                   | Whether an instance is destroyable. See [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection)                                                                                                                                                                                                                                                                                                                                                                                |
| compute\_node        | String                    | UUID of the server on which the instance is located                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| package              | String                    | The id or name of the package used to create this instance                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| flexible             | Boolean                   | Whether this instance uses the flexible disk space feature (bhyve)                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| free\_space          | Number                    | The amount of space (MiB) that is not allocated to disks nor in use by snapshots of those disks. If snapshots are present, writes to disks may reduce this value (bhyve)                                                                                                                                                                                                                                                                                                                               |

#### Errors <a href="#errors-40" id="errors-40"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                            |
| ---------------- | ------------------------------------------ |
| ResourceNotFound | If `:login` does not exist                 |
| InvalidArgument  | If one of the input parameters was invalid |

#### CLI Command <a href="#cli-command-39" id="cli-command-39"></a>

Get all instance:

```
triton instance list
```

or

```
sdc-listmachines
```

Get all LX instance:

```
triton instance list brand=lx
```

or

```
sdc-listmachines --brand lx
```

Get all LX machines that are currently running:

```
triton instance list brand=lx state=running
```

or

```
sdc-listmachines --brand lx --state running
```

Get all LX instances that are currently running, and have 256 MiB of memory:

```
triton instance list brand=lx state=running memory=256
```

or

```
sdc-listmachines --brand lx --state running --memory 256
```

Get all LX instances that are currently running, with 256 MiB of RAM, tagged as 'test':

```
sdc-listmachines --brand lx --state running --memory 256 --tag group=test
```

Get all tagged instances:

```
sdc-listmachines --tag \*
```

Beware that depending on your shell you may need to escape the asterisk character. E.g. Bash requires it escaped.

The CLI has parameters that let you filter on most things in the API, and you can combine them. Run `triton instance list --help` or `sdc-listmachines --help` to see all the options.

#### Example Request <a href="#example-request-34" id="example-request-34"></a>

```
GET /my/machines HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-34" id="example-response-34"></a>

```
HTTP/1.1 200 OK
x-query-limit: 1000
x-resource-count: 1
Content-Type: application/json
Content-Length: 1310
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: w5wJLKlhDzPpC6zKjtqaCw==
Date: Thu, 21 Jan 2016 10:55:25 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 779b5cc0-c02d-11e5-a7d2-fdf229d32220
Response-Time: 3444

[
  {
    "id": "b6979942-7d5d-4fe6-a2ec-b812e950625a",
    "name": "test",
    "type": "smartmachine",
    "brand": "joyent",
    "state": "running",
    "image": "2b683a82-a066-11e3-97ab-2faa44701c5a",
    "ips": [
      "10.88.88.26",
      "192.168.128.5"
    ],
    "memory": 128,
    "disk": 12288,
    "metadata": {
      "root_authorized_keys": "..."
    },
    "tags": {},
    "created": "2016-01-04T12:55:50.539Z",
    "updated": "2016-01-21T08:56:59.000Z",
    "networks": [
      "a9c130da-e3ba-40e9-8b18-112aba2d3ba7",
      "45607081-4cd2-45c8-baf7-79da760fffaa"
    ],
    "primaryIp": "10.88.88.26",
    "firewall_enabled": false,
    "compute_node": "564d0b8e-6099-7648-351e-877faf6c56f6",
    "package": "sdc_128"
  }
]
```

### GetMachine (GET /:login/machines/:id) <a href="#getmachine" id="getmachine"></a>

Gets the details for an individual instance.

Deleted instances are returned only if the instance history has not been purged from Triton.

#### Inputs <a href="#inputs-41" id="inputs-41"></a>

| **Field**   | **Type** | **Description**                                                                            |
| ----------- | -------- | ------------------------------------------------------------------------------------------ |
| credentials | Boolean  | Whether to include the generated credentials for instances, if present. Defaults to false. |

#### Returns <a href="#returns-41" id="returns-41"></a>

| **Field**         | **Type**                  | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ----------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id                | UUID                      | Unique id for this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| name              | String                    | The "friendly" name for this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| type              | String                    | (deprecated) The type of instance (virtualmachine or smartmachine)                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| brand             | String                    | (v8.0+) The type of instance (e.g. lx)                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| state             | String                    | The current state of this instance (e.g. running)                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| image             | String                    | The image id this instance was provisioned with                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| memory            | Number                    | The amount of RAM this instance has (in MiB)                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| disk              | Number                    | The amount of disk this instance has (in MiB)                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| disks             | Array                     | An array of disk objects (bhyve)                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| metadata          | Object\[String => String] | Any additional metadata this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| tags              | Object\[String => String] | Any tags this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| created           | ISO8601 date              | When this instance was created                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| updated           | ISO8601 date              | When this instance's details was last updated                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| docker            | Boolean                   | Whether this instance is a Docker container, if present                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ips               | Array\[String]            | The IP addresses this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| networks          | Array\[String]            | The network UUIDs of the nics this instance has                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| primaryIp         | String                    | The IP address of the primary NIC of this instance. The "primary" NIC is used to determine the default gateway for an instance. Commonly it is also on an external network (i.e. accessible on the public internet) and hence usable for SSH'ing into an instance, but not always. (Note: In future Triton versions it will be possible to have multiple IPv4 and IPv6 addresses on a particular NIC, at which point the current definition of `primaryIp` will be ambiguous and will need to change.) |
| firewall\_enabled | Boolean                   | Whether firewall rules are enforced on this instance                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| compute\_node     | String                    | UUID of the server on which the instance is located                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| package           | String                    | The id or name of the package used to create this instance                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| dns\_names        | Array\[String]            | DNS names of the instance (if the instance is using [CNS](https://docs.joyent.com/public-cloud/network/cns))                                                                                                                                                                                                                                                                                                                                                                                           |
| flexible          | Boolean                   | Whether this instance uses the flexible disk space feature (bhyve)                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| free\_space       | Number                    | The amount of space (MiB) that is not allocated to disks nor in use by snapshots of those disks. If snapshots are present, writes to disks may reduce this value (bhyve)                                                                                                                                                                                                                                                                                                                               |

Be aware that in the case of instances created with vmadm directly (i.e. not through CloudAPI), ips, networks, primaryIp and package may be in a different format than expected. The `ips` array can contain the value "dhcp", not just IP strings, the `networks` array can contain null values for networks that CloudAPI was unable to determine (e.g. as a result of a "dhcp" IP), `primaryIp` too can have the value of "dhcp", and the package string can be empty instead of a UUID. Unless ops is bypassing CloudAPI and creating instances directly, it is unlikely you need concern yourself with this caveat.

#### Errors <a href="#errors-41" id="errors-41"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-40" id="cli-command-40"></a>

Get the details for the instance with id 75cfe125-a5ce-49e8-82ac-09aa31ffdf26:

```
triton instance get b6979942-7d5d-4fe6-a2ec-b812e950625a
```

or

```
sdc-getmachine b6979942-7d5d-4fe6-a2ec-b812e950625a
```

#### Example Request <a href="#example-request-35" id="example-request-35"></a>

```
GET /my/machines/b6979942-7d5d-4fe6-a2ec-b812e950625a HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-35" id="example-response-35"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1308
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: 0q2leQEqeZCNiznbZvKhZw==
Date: Thu, 21 Jan 2016 10:58:11 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: db0705c0-c02d-11e5-b1b7-65fab9169f0e
Response-Time: 3159

{
  "id": "b6979942-7d5d-4fe6-a2ec-b812e950625a",
  "name": "test",
  "type": "smartmachine",
  "brand": "joyent",
  "state": "running",
  "image": "2b683a82-a066-11e3-97ab-2faa44701c5a",
  "ips": [
    "10.88.88.26",
    "192.168.128.5"
  ],
  "memory": 128,
  "disk": 12288,
  "metadata": {
    "root_authorized_keys": "...",
  },
  "tags": {},
  "created": "2016-01-04T12:55:50.539Z",
  "updated": "2016-01-21T08:56:59.000Z",
  "networks": [
    "a9c130da-e3ba-40e9-8b18-112aba2d3ba7",
    "45607081-4cd2-45c8-baf7-79da760fffaa"
  ],
  "primaryIp": "10.88.88.26",
  "firewall_enabled": false,
  "compute_node": "564d0b8e-6099-7648-351e-877faf6c56f6",
  "package": "sdc_128"
}
```

### CreateMachine (POST /:login/machines) <a href="#createmachine" id="createmachine"></a>

Allows you to provision an instance.

If you do not specify a name, CloudAPI will generate a random one for you. If you have enabled Triton CNS on your account, this name will also be used in DNS to refer to the new instance (and must therefore consist of DNS-safe characters only).

Your instance will initially be not available for login (Triton must provision and boot it); you can poll [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) for its status. When the `state` field is equal to `running`, you can log in. If the instance is a `brand` other than `kvm` or `bhyve`, you can usually use any of the SSH keys managed under the [keys section](https://apidocs.joyent.com/cloudapi/#keys) of CloudAPI to login as any POSIX user on the OS. You can add/remove keys over time, and the instance will automatically work with that set.

If the the instance has a brand `kvm` or `bhyve`, and of a UNIX-derived OS (e.g. Linux), you *must* have keys uploaded before provisioning; that entire set of keys will be written out to `/root/.ssh/authorized_keys` in the new instance, and you can SSH in using one of those keys. Changing the keys over time under your account will not affect a running hardware virtual machine in any way; those keys are statically written at provisioning-time only, and you will need to manually manage them on the instance itself.

If the image you create an instance from is set to generate passwords for you, the username/password pairs will be returned in the metadata response as a nested object, like so:

```
"metadata": {
  "credentials": {
    "root": "s8v9kuht5e",
    "admin": "mf4bteqhpy"
  }
}
```

You cannot overwrite the `credentials` key in CloudAPI.

More generally, the metadata keys can be set either at the time of instance creation, or after the fact. You must either pass in plain-string values, or a JSON-encoded string. On metadata retrieval, you will get a JSON object back.

Networks can be specified using the networks attribute. It is possible to have an instance attached to an internal network, external network or both. If the networks attribute is absent from the input, the instance will be attached to one externally-accessible network (i.e. assigned a public IP), and any one of internal/private networks. If the account owns or has access to multiple private networks, it will be important to include the desired network(s) in the request payload instead of letting the system assign the network automatically.

Be aware that CreateMachine does not return IP addresses or networks. To obtain the IP addresses and networks of a newly-provisioned instance, poll [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) until the instance state is `running`.

Typically, Triton will allocate the new instance somewhere reasonable within the cloud. See [affinity rules](https://apidocs.joyent.com/cloudapi/#affinity-rules) below for options on controlling server placement of new instances.

When Triton CNS is enabled, the DNS search domain of the new VM will be automatically set to the suffix of the "instance" record that is created for that VM. For example, if the full CNS name of the new VM would be "foo.inst.35ad1ec4-2eab-11e6-ac02-8f56c66976a1.us-west-1.triton.zone", its automatic DNS search path would include "inst.35ad1ec4-2eab-11e6-ac02-8f56c66976a1.us-west-1.triton.zone". This can be changed later within the instance, if desired.

#### Inputs <a href="#inputs-42" id="inputs-42"></a>

| **Field**             | **Type** | **Description**                                                                                                                                                                                                                                                                               |
| --------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                  | String   | Friendly name for this instance; default is the first 8 characters of the machine id. If the name includes the string {{shortId}}, any instances of that tag within the name will be replaced by the first 8 characters of the machine id.                                                    |
| package               | String   | Id of the package to use on provisioning, obtained from [ListPackages](https://apidocs.joyent.com/cloudapi/#ListPackages)                                                                                                                                                                     |
| image                 | String   | The image UUID (the "id" field in [ListImages](https://apidocs.joyent.com/cloudapi/#ListImages))                                                                                                                                                                                              |
| networks              | Array    | Array of [network objects](https://apidocs.joyent.com/cloudapi/#network-objects), or an array of network UUIDs obtained from [ListNetworks](https://apidocs.joyent.com/cloudapi/#ListNetworks). See the note about network pools under [AddNic](https://apidocs.joyent.com/cloudapi/#AddNic). |
| affinity              | Array    | (Added in CloudAPI v8.3.0.) Optional array of [affinity rules](https://apidocs.joyent.com/cloudapi/#affinity-rules).                                                                                                                                                                          |
| locality              | Object   | (Deprecated in CloudAPI v8.3.0.) Optionally object of [locality hints](https://apidocs.joyent.com/cloudapi/#locality-hints), specify which instances the new instance should be near or far from.                                                                                             |
| metadata.$name        | String   | An arbitrary set of metadata key/value pairs can be set at provision time, but they must be prefixed with "metadata."                                                                                                                                                                         |
| tag.$name             | String   | An arbitrary set of tags can be set at provision time, but they must be prefixed with "tag."                                                                                                                                                                                                  |
| firewall\_enabled     | Boolean  | Completely enable or disable firewall for this instance. Default is false                                                                                                                                                                                                                     |
| deletion\_protection  | Boolean  | Whether an instance is destroyable. See [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection). Default is false                                                                                                                                                     |
| allow\_shared\_images | Boolean  | Whether to allow provisioning from a shared image. Default is false                                                                                                                                                                                                                           |
| volumes               | Array    | A list of objects representing volumes to mount when the newly created machine boots                                                                                                                                                                                                          |
| disks                 | Array    | An array of disk objects to be created (bhyve)                                                                                                                                                                                                                                                |

**volumes**

The `volumes` input parameter allows users to specify a list of volumes to mount in the new machine when it boots:

&#x20;`"volumes": [ { "name": "volume-name-1", "type": "tritonnfs", "mode": "rw", "mountpoint": "/foo" }, { "name": "volume-name-2", "mode": "ro", "mountpoint": "/bar" } ]`

Each object of the `volumes` array has the following layout:

| **Field**  | **Type** | **Description**                                                                                                                                                                   |
| ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name       | String   | The name of the volume to mount                                                                                                                                                   |
| type       | String   | The type of the volume to mount (currently only `"tritonnfs"` is supported)                                                                                                       |
| mode       | String   | Determines the read/write mode for the volume to mount. Accepted values are `"ro"` (for read-only) and `"rw"` (for read-write). The default value is `"rw"`.                      |
| mountpoint | String   | Specifies where the volume is mounted in the newly created machine's filesystem. It must start with a slash (`"/"`) and it must contain at least one character that is not `'/'`. |

**disks**

The `disks` input parameter allows users to specify a list of disks to be provisioned when creating a bhyve instance. This parameter can only be specified if the package has its `flexible_disk` attribute set to `true`. The sum of the sizes of the disks may be no greater than the package quota.

&#x20;`"disks": [ { "id": "eea4e223-dee6-44dc-a7e1-71f996e534f0", "boot": true }, { "id": "dea91a7f-5fe3-4408-b25a-994c97a7975e", "size": 512 }, { "id": "c41ce11e-bed2-45d2-bdb8-8dc889ed8ced", "size": "remaining" } ]`

Each object of the `disks` array has the following layout

| **Field** | **Type** | **Description**                                                                                                                                            |
| --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id        | UUID     | Unique id for this disk                                                                                                                                    |
| boot      | Boolean  | If `true`, this is the boot disk                                                                                                                           |
| image     | UUID     | The image from which the disk was created                                                                                                                  |
| size      | Integer  | The size of the disk in mebibytes or "remaining". If "remaining", size will be set to the difference between the package quota and sum of the other disks. |

#### Returns <a href="#returns-42" id="returns-42"></a>

| **Field**   | **Type**                  | **Description**                                                                                                                                                          |
| ----------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id          | UUID                      | Unique id for this instance                                                                                                                                              |
| name        | String                    | The "friendly" name for this instance                                                                                                                                    |
| type        | String                    | (deprecated) The type of instance (virtualmachine or smartmachine)                                                                                                       |
| brand       | String                    | (v8.0+) The type of instance (e.g. lx)                                                                                                                                   |
| state       | String                    | The current state of this instance (e.g. running)                                                                                                                        |
| memory      | Number                    | The amount of RAM this instance has (in MiB)                                                                                                                             |
| disk        | Number                    | The amount of disk this instance has (in MiB)                                                                                                                            |
| disks       | Array                     | (v9.4.0+) One disk object per disk in the VM (bhyve only)                                                                                                                |
| ips         | Array\[String]            | The IP addresses this instance has                                                                                                                                       |
| metadata    | Object\[String => String] | Any additional metadata this instance has                                                                                                                                |
| package     | String                    | The id or name of the package used to create this instance                                                                                                               |
| image       | String                    | The image id this instance was provisioned with                                                                                                                          |
| docker      | Boolean                   | Whether this instance is a Docker container, if present                                                                                                                  |
| flexible    | Boolean                   | Whether this instance uses the flexible disk space feature (bhyve)                                                                                                       |
| free\_space | Number                    | The amount of space (MiB) that is not allocated to disks nor in use by snapshots of those disks. If snapshots are present, writes to disks may reduce this value (bhyve) |
| created     | ISO8601 date              | When this instance was created                                                                                                                                           |
| updated     | ISO8601 date              | When this instance's details was last updated                                                                                                                            |

#### Errors <a href="#errors-42" id="errors-42"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**       | **Description**                                |
| -------------------- | ---------------------------------------------- |
| ResourceNotFound     | If `:login` does not exist                     |
| InsufficientCapacity | There isn't enough capacity in this datacenter |
| InvalidArgument      | If one of the input parameters was invalid     |
| MissingParameter     | If one of the input parameters was missing     |

#### CLI Command <a href="#cli-command-41" id="cli-command-41"></a>

```
triton instance create 2b683a82-a066-11e3-97ab-2faa44701c5a 7b17343c-94af-6266-e0e8-893a3b9993d0
```

or

```
sdc-createmachine --image=2b683a82-a066-11e3-97ab-2faa44701c5a --package=7b17343c-94af-6266-e0e8-893a3b9993d0
```

#### Example Request <a href="#example-request-36" id="example-request-36"></a>

```
POST /my/machines HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 455
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

{
  "image": "2b683a82-a066-11e3-97ab-2faa44701c5a",
  "package": "7b17343c-94af-6266-e0e8-893a3b9993d0"
}
```

#### Example Response <a href="#example-response-36" id="example-response-36"></a>

```
HTTP/1.1 201 Created
Location: /my/machines/e8622950-af78-486c-b682-dd147c938dc6
Content-Type: application/json
Content-Length: 1151
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: s5ROP0dBDWlf5X1drujDvg==
Date: Thu, 21 Jan 2016 12:57:52 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 9283ba80-c03e-11e5-b1b7-65fab9169f0e
Response-Time: 4655

{
  "id": "e8622950-af78-486c-b682-dd147c938dc6",
  "name": "e8622950",
  "type": "smartmachine",
  "brand": "joyent",
  "state": "provisioning",
  "image": "2b683a82-a066-11e3-97ab-2faa44701c5a",
  "ips": [],
  "memory": 128,
  "disk": 12288,
  "metadata": {
    "root_authorized_keys": "..."
  },
  "tags": {},
  "created": "2016-01-21T12:57:52.759Z",
  "updated": "2016-01-21T12:57:52.979Z",
  "networks": [],
  "firewall_enabled": false,
  "compute_node": null,
  "package": "sdc_128"
}
```

#### More Examples <a href="#more-examples" id="more-examples"></a>

Create instance with multiple nics

```
triton instance create --network=42325ea0-eb62-44c1-8eb6-0af3e2f83abc --network=c8cde927-6277-49ca-82a3-741e8b23b02f 2b683a82-a066-11e3-97ab-2faa44701c5a 7b17343c-94af-6266-e0e8-893a3b9993d0
```

or

```
sdc-createmachine --image=2b683a82-a066-11e3-97ab-2faa44701c5a --package=7b17343c-94af-6266-e0e8-893a3b9993d0 --networks=42325ea0-eb62-44c1-8eb6-0af3e2f83abc --networks=c8cde927-6277-49ca-82a3-741e8b23b02f
```

Create instance with tags

```
triton instance create -t foo=bar -t group=test 2b683a82-a066-11e3-97ab-2faa44701c5a 7b17343c-94af-6266-e0e8-893a3b9993d0
```

or

```
sdc-createmachine --image=2b683a82-a066-11e3-97ab-2faa44701c5a --package=7b17343c-94af-6266-e0e8-893a3b9993d0 -t foo=bar -t group=test
```

#### Network objects <a href="#network-objects" id="network-objects"></a>

As of CloudAPI v8.5.0 the networks parameter to CreateMachine takes an array of network objects to add flexibility and more control. It is also still possible to pass in an array of network UUID strings instead of the new network object format.

At a minimum the network object must contain an `ipv4_uuid` parameter that is the UUID of the network you wish the machine to have a NIC on. In addition you may pass in a `ipv4_ips` property that is an array made up of a single IP on that network's subnet.

When specifying an `ipv4_ips` array, the `ipv4_uuid` cannot be the UUID of a network pool, or a public network.

Here are some examples of possible network objects:

```
[
  {
    "ipv4_uuid": "f65153df-edf5-11e7-bb45-54e1adb5aaf3",
    "ipv4_ips": [
      "10.0.1.50"
    ]
  },
  {
    "ipv4_uuid": "6fa58531-edf6-11e7-bb45-54e1adb5aaf3"
  }
]
```

#### Affinity rules <a href="#affinity-rules" id="affinity-rules"></a>

As of CloudAPI v8.3.0 an "affinity" field can be specified with CreateMachine. It is an array of "affinity rules" to specify rules (or hints, "soft rules") for placement of the new instance.

By default, Triton makes a reasonable attempt to spread all containers (and non-Docker containers and VMs) owned by a single account across separate physical servers.

Affinity rules are of one of the following forms:

```
instance<op><value>
container<op><value>
<tagName><op><value>
```

is one of:

* `==`: The new instance must be on the same node as the instance(s) identified by .
* `!=`: The new instance must be on a different node to the instance(s) identified by .
* `==~`: The new instance should be on the same node as the instance(s) identified by . I.e. this is a best effort or "soft" rule.
* `!=~`: The new instance should be on a different node to the instance(s) identified by . I.e. this is a best effort or "soft" rule.

is an exact string, simple \*-glob, or regular expression to match against instance names or IDs, or against the named tag's value. Some examples:

```
# Run on the same node as instance silent_bob.
triton instance create -a instance==silent_bob ...

# Run on a different node to all instances tagged with 'role=database'.
triton instance create -a 'role!=database' ...

# Run on a different node to all instances with names starting with "foo".
triton instance create -a 'instance!=foo*' ...

# Same, using a regular expression.
triton instance create -a 'instance!=/^foo/' ...
```

#### Locality hints <a href="#locality-hints" id="locality-hints"></a>

(Deprecated in CloudAPI v8.3.0.)

You may want this instance to be placed on the same server as another instance you have, or have it placed on an entirely different server from your existing instances so that you can spread them out. In either case, you can provide locality hints to CloudAPI.

Here is an example of a locality hint:

```
"locality": {
  "strict": false,
  "near": ["af7ebb74-59be-4481-994f-f6e05fa53075"],
  "far": ["da568166-9d93-42c8-b9b2-bce9a6bb7e0a", "d45eb2f5-c80b-4fea-854f-32e4a9441e53"]
}
```

UUIDs provided should be the ids of instances belonging to you. If there is only a single UUID entry in an array, you can omit the array and provide the UUID string directly as the value to a near/far key.

`strict` defaults to false, meaning that Triton will attempt to meet all the `near` and/or `far` criteria but will still provision the instance when no server fits all the requirements. If `strict` is set to true, the creation of the new instance will fail if the affinity criteria cannot be met.

#### User-script <a href="#user-script" id="user-script"></a>

The special value `metadata.user-script` can be specified to provide a custom script which will be executed by the instance right after creation, and on every instance reboot. This script can be specified using the command-line option `--script`, which should be an absolute path to the file you want to upload to the instance.

### StopMachine (POST /:login/machines/:id?action=stop) <a href="#stopmachine" id="stopmachine"></a>

Allows you to shut down an instance. POST to the instance name with an `action` of `stop`.

You can poll on [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) until the state is `stopped`.

#### Inputs <a href="#inputs-43" id="inputs-43"></a>

| **Field** | **Type** | **Description**             |
| --------- | -------- | --------------------------- |
| action    | String   | Use the exact string "stop" |

#### Returns <a href="#returns-43" id="returns-43"></a>

* None

#### Errors <a href="#errors-43" id="errors-43"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                  |
| ---------------- | ------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist              |
| InvalidState     | The instance is in the wrong state to be stopped |
| InvalidArgument  | If `action` was invalid                          |
| MissingParameter | If `action` wasn't provided                      |

#### CLI Command <a href="#cli-command-42" id="cli-command-42"></a>

```
triton instance stop c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

or

```
sdc-stopmachine c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-37" id="example-request-37"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=stop
```

#### Example Response <a href="#example-response-37" id="example-response-37"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:05:58 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: b49ae1b0-c03f-11e5-a7d2-fdf229d32220
Response-Time: 3175
Transfer-Encoding: chunked
```

### StartMachine (POST /:login/machines/:id?action=start) <a href="#startmachine" id="startmachine"></a>

Allows you to boot up an instance. POST to the instance name with an `action` of `start`.

You can poll on [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) until the state is `running`.

#### Inputs <a href="#inputs-44" id="inputs-44"></a>

| **Field** | **Type** | **Description**              |
| --------- | -------- | ---------------------------- |
| action    | String   | Use the exact string "start" |

#### Returns <a href="#returns-44" id="returns-44"></a>

* None

#### Errors <a href="#errors-44" id="errors-44"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                  |
| ---------------- | ------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist              |
| InvalidState     | The instance is in the wrong state to be started |
| InvalidArgument  | If `action` was invalid                          |
| MissingParameter | If `action` wasn't provided                      |

#### CLI Command <a href="#cli-command-43" id="cli-command-43"></a>

```
triton instance start c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

or

```
sdc-startmachine c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-38" id="example-request-38"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=start
```

#### Example Response <a href="#example-response-38" id="example-response-38"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:07:24 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: e7fda2e0-c03f-11e5-a64c-d133f917673f
Response-Time: 3487
Transfer-Encoding: chunked
```

### RebootMachine (POST /:login/machines/:id?action=reboot) <a href="#rebootmachine" id="rebootmachine"></a>

Allows you to reboot an instance. POST to the instance name with an `action` of `reboot`.

You can poll on [GetMachine](https://apidocs.joyent.com/cloudapi/#GetMachine) until the state is `running`.

#### Inputs <a href="#inputs-45" id="inputs-45"></a>

| **Field** | **Type** | **Description**               |
| --------- | -------- | ----------------------------- |
| action    | String   | Use the exact string "reboot" |

#### Returns <a href="#returns-45" id="returns-45"></a>

* None

#### Errors <a href="#errors-45" id="errors-45"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                  |
| ---------------- | ------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist              |
| InvalidState     | The instance is in the wrong state to be stopped |
| InvalidArgument  | If `action` was invalid                          |
| MissingParameter | If `action` wasn't provided                      |

#### CLI Command <a href="#cli-command-44" id="cli-command-44"></a>

```
triton instance reboot c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

or

```
sdc-rebootmachine c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-39" id="example-request-39"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=reboot
```

#### Example Response <a href="#example-response-39" id="example-response-39"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:09:34 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 35679950-c040-11e5-b1b7-65fab9169f0e
Response-Time: 3124
Transfer-Encoding: chunked
```

### ResizeMachine (POST /:login/machines/:id?action=resize) <a href="#resizemachine" id="resizemachine"></a>

Resize an instance to a new [package](https://apidocs.joyent.com/cloudapi/#packages) (a.k.a. instance type).

Note that KVM instances (with `brand=kvm`) cannot be resized, and bhyve instances (`brand=bhyve`) only allow resizing to a package that uses flexible\_disk.

Resizing is not guaranteed to work, especially when resizing upwards in resources. It is best-effort, and may fail. Resizing downwards will usually succeed.

#### Inputs <a href="#inputs-46" id="inputs-46"></a>

| **Field** | **Type** | **Description**                                                                                  |
| --------- | -------- | ------------------------------------------------------------------------------------------------ |
| action    | String   | Use the exact string "resize"                                                                    |
| package   | String   | A package id, as returned from [ListPackages](https://apidocs.joyent.com/cloudapi/#ListPackages) |

#### Returns <a href="#returns-46" id="returns-46"></a>

* None

#### Errors <a href="#errors-46" id="errors-46"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                                 |
| ---------------- | --------------------------------------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist                             |
| InvalidState     | The instance is in the wrong state to be resized                |
| InvalidArgument  | If `action` was invalid, or `package` wasn't a valid id or name |
| MissingParameter | If `action` or `package` wasn't provided                        |

#### CLI Command <a href="#cli-command-45" id="cli-command-45"></a>

```
sdc-resizemachine --package=7041ccc7-3f9e-cf1e-8c85-a9ee41b7f968 c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-40" id="example-request-40"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=resize&package=7041ccc7-3f9e-cf1e-8c85-a9ee41b7f968
```

#### Example Response <a href="#example-response-40" id="example-response-40"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:12:06 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 8fa7d8d0-c040-11e5-9100-a95edd60134e
Response-Time: 161
```

### RenameMachine (POST /:login/machines/:id?action=rename) <a href="#renamemachine" id="renamemachine"></a>

Allows you to rename an instance. POST to the instance `id` with an action of `rename`. You must additionally include a new name for the instance.

#### Inputs <a href="#inputs-47" id="inputs-47"></a>

| **Field** | **Type** | **Description**                           |
| --------- | -------- | ----------------------------------------- |
| action    | String   | Use the exact string "rename"             |
| name      | String   | The new "friendly" name for this instance |

#### Returns <a href="#returns-47" id="returns-47"></a>

* None

#### Errors <a href="#errors-47" id="errors-47"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                        |
| ---------------- | ------------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist                    |
| InvalidState     | The instance is in the wrong state to be stopped       |
| InvalidArgument  | If `action` was invalid, or `name` wasn't a valid name |
| MissingParameter | If `action` or `name` wasn't provided                  |

#### CLI Command <a href="#cli-command-46" id="cli-command-46"></a>

```
sdc-renamemachine --name=new_friendly_name c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-41" id="example-request-41"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=rename&name=new_friendly_name
```

#### Example Response <a href="#example-response-41" id="example-response-41"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:14:17 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: dda360e0-c040-11e5-a64c-d133f917673f
Response-Time: 3768
Transfer-Encoding: chunked
```

### EnableMachineFirewall (POST /:login/machines/:id?action=enable\_firewall) <a href="#enablemachinefirewall" id="enablemachinefirewall"></a>

Allows you to enable the firewall for an instance.

#### Inputs <a href="#inputs-48" id="inputs-48"></a>

| **Field** | **Type** | **Description**                         |
| --------- | -------- | --------------------------------------- |
| action    | String   | Use the exact string "enable\_firewall" |

#### Returns <a href="#returns-48" id="returns-48"></a>

* None

#### Errors <a href="#errors-48" id="errors-48"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                       |
| ---------------- | ----------------------------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist                   |
| InvalidState     | The instance is in the wrong state to enable firewall |
| InvalidArgument  | If `action` was invalid                               |
| MissingParameter | If `action` wasn't provided                           |

#### CLI Command <a href="#cli-command-47" id="cli-command-47"></a>

```
triton instance enable-firewall c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

or

```
sdc-enablemachinefirewall c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-42" id="example-request-42"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=enable_firewall
```

#### Example Response <a href="#example-response-42" id="example-response-42"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:16:00 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 1b1e83a0-c041-11e5-b1b7-65fab9169f0e
Response-Time: 3594
Transfer-Encoding: chunked
```

### DisableMachineFirewall (POST /:login/machines/:id?action=disable\_firewall) <a href="#disablemachinefirewall" id="disablemachinefirewall"></a>

Allows you to completely disable the firewall of an instance.

#### Inputs <a href="#inputs-49" id="inputs-49"></a>

| **Field** | **Type** | **Description**                          |
| --------- | -------- | ---------------------------------------- |
| action    | String   | Use the exact string "disable\_firewall" |

#### Returns <a href="#returns-49" id="returns-49"></a>

* None

#### Errors <a href="#errors-49" id="errors-49"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                        |
| ---------------- | ------------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist                    |
| InvalidState     | The instance is in the wrong state to disable firewall |
| InvalidArgument  | If `action` was invalid                                |
| MissingParameter | If `action` wasn't provided                            |

#### CLI Command <a href="#cli-command-48" id="cli-command-48"></a>

```
triton instance disable-firewall c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

or

```
sdc-disablemachinefirewall c2855c3a-a91d-46b8-9da6-6d7ab1bc6962
```

#### Example Request <a href="#example-request-43" id="example-request-43"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=disable_firewall
```

#### Example Response <a href="#example-response-43" id="example-response-43"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:23:39 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 2c74e120-c042-11e5-9100-a95edd60134e
Response-Time: 4178
Transfer-Encoding: chunked
```

### EnableMachineDeletionProtection (POST /:login/machines/:id?action=enable\_deletion\_protection) <a href="#enablemachinedeletionprotection" id="enablemachinedeletionprotection"></a>

Enable [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection) on an instance. An instance can no longer be destroyed until the protection is disabled.

#### Inputs <a href="#inputs-50" id="inputs-50"></a>

| **Field** | **Type** | **Description**                                     |
| --------- | -------- | --------------------------------------------------- |
| action    | String   | Use the exact string "enable\_deletion\_protection" |

#### Returns <a href="#returns-50" id="returns-50"></a>

* None

#### Errors <a href="#errors-50" id="errors-50"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                       |
| ---------------- | ----------------------------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist                   |
| InvalidState     | The instance is in the wrong state to enable firewall |
| InvalidArgument  | If `action` was invalid                               |
| MissingParameter | If `action` wasn't provided                           |

#### Example Request <a href="#example-request-44" id="example-request-44"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=enable_deletion_protection
```

#### Example Response <a href="#example-response-44" id="example-response-44"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2017 13:16:00 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 1b1e83a0-c041-11e5-b1b7-65fab9169f0e
Response-Time: 3594
Transfer-Encoding: chunked
```

### DisableMachineDeletionProtection (POST /:login/machines/:id?action=disable\_deletion\_protection) <a href="#disablemachinedeletionprotection" id="disablemachinedeletionprotection"></a>

Disable [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection) on an instance. An instance can be destroyed after it is disabled.

#### Inputs <a href="#inputs-51" id="inputs-51"></a>

| **Field** | **Type** | **Description**                                      |
| --------- | -------- | ---------------------------------------------------- |
| action    | String   | Use the exact string "disable\_deletion\_protection" |

#### Returns <a href="#returns-51" id="returns-51"></a>

* None

#### Errors <a href="#errors-51" id="errors-51"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                        |
| ---------------- | ------------------------------------------------------ |
| ResourceNotFound | If `:login` or `:id` does not exist                    |
| InvalidState     | The instance is in the wrong state to disable firewall |
| InvalidArgument  | If `action` was invalid                                |
| MissingParameter | If `action` wasn't provided                            |

#### Example Request <a href="#example-request-45" id="example-request-45"></a>

```
POST /my/machines/c2855c3a-a91d-46b8-9da6-6d7ab1bc6962 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

action=disable_deletion_protection
```

#### Example Response <a href="#example-response-45" id="example-response-45"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: POST, GET, HEAD, DELETE, PUT
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Date: Thu, 21 Jan 2016 13:23:39 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 2c74e120-c042-11e5-9100-a95edd60134e
Response-Time: 4178
Transfer-Encoding: chunked
```

### CreateMachineSnapshot (POST /:login/machines/:id/snapshots) <a href="#createmachinesnapshot" id="createmachinesnapshot"></a>

Allows you to take a snapshot of an instance. Once you have one or more snapshots, you can boot the instance from a previous snapshot.

Snapshots are not usable with other instances; they are a point-in-time snapshot of the current instance. Snapshots can be taken of instances that are SmartOS, Docker, and bhyve, but not of brand 'kvm'.

Since instance instances use a copy-on-write filesystem, snapshots take up increasing amounts of space as the filesystem changes over time. There is a limit to how much space snapshots are allowed to take. Plan your snapshots accordingly.

You can poll on [GetMachineSnapshot](https://apidocs.joyent.com/cloudapi/#GetMachineSnapshot) until the `state` is `created`.

#### Inputs <a href="#inputs-52" id="inputs-52"></a>

| **Field** | **Type** | **Description**                        |
| --------- | -------- | -------------------------------------- |
| name      | String   | The name to assign to the new snapshot |

#### Returns <a href="#returns-52" id="returns-52"></a>

| **Field** | **Type** | **Description**                   |
| --------- | -------- | --------------------------------- |
| name      | String   | The name of this snapshot         |
| state     | String   | The current state of the snapshot |

#### Errors <a href="#errors-52" id="errors-52"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |
| InvalidArgument  | If `name` was invalid               |

#### CLI Command <a href="#cli-command-49" id="cli-command-49"></a>

```
triton instance snapshot create 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

or

```
sdc-createmachinesnapshot --name=just-booted 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-46" id="example-request-46"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

name=just-booted
```

#### Example Response <a href="#example-response-46" id="example-response-46"></a>

```
HTTP/1.1 201 Created
Location: /mark/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots/just-booted
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 116

{
  "name": "just-booted",
  "state": "queued",
  "created": "2011-07-05T17:19:26+00:00",
  "updated": "2011-07-05T17:19:26+00:00"
}
```

### StartMachineFromSnapshot (POST /:login/machines/:id/snapshots/:name) <a href="#startmachinefromsnapshot" id="startmachinefromsnapshot"></a>

If an instance is in the 'stopped' state, you can choose to start the instance from the referenced snapshot. This is effectively a means to roll back instance state.

#### Inputs <a href="#inputs-53" id="inputs-53"></a>

* None

#### Returns <a href="#returns-53" id="returns-53"></a>

* None

#### Errors <a href="#errors-53" id="errors-53"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                              |
| ---------------- | -------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:name` does not exist |

#### CLI Command <a href="#cli-command-50" id="cli-command-50"></a>

```
triton instance start --snapshot=just-booted 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

or

```
sdc-startmachinefromsnapshot --snapshot=just-booted 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-47" id="example-request-47"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots/just-booted HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8
```

#### Example Response <a href="#example-response-47" id="example-response-47"></a>

```
HTTP/1.1 202 Accepted
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE
Connection: close
Date: Tue, 05 Jul 2011 17:26:56 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: af79d9cd-68c5-4002-95c6-af4c3ff0f1e4
Response-Time: 297
Content-Length: 0
```

### ListMachineSnapshots (GET /:login/machines/:id/snapshots) <a href="#listmachinesnapshots" id="listmachinesnapshots"></a>

Lists all snapshots taken for a given instance. There are no filtration parameters for this API.

#### Inputs <a href="#inputs-54" id="inputs-54"></a>

* None

#### Returns <a href="#returns-54" id="returns-54"></a>

An array of snapshots:

| **Field** | **Type** | **Description**                   |
| --------- | -------- | --------------------------------- |
| name      | String   | The name of this snapshot         |
| state     | String   | The current state of the snapshot |
| size      | Number   | The size of the snapshot (MiB)    |

#### Errors <a href="#errors-54" id="errors-54"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-51" id="cli-command-51"></a>

```
triton instance snapshot list 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

or

```
sdc-listmachinesnapshots 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-48" id="example-request-48"></a>

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8
```

#### Example Response <a href="#example-response-48" id="example-response-48"></a>

```
HTTP/1.1 200 Ok
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 06a57272-9238-4276-951b-4123fbfdb948
Response-Time: 66
Content-Type: application/json
Content-MD5: UYdtqgRjRZVikfCM5Uf4XQ==
Content-Length: 119

[
  {
    "name": "just-booted",
    "state": "queued",
    "created": "2011-07-05T17:19:26+00:00",
    "updated": "2011-07-05T17:19:26+00:00"
  }
]
```

### GetMachineSnapshot (GET /:login/machines/:id/snapshots/:name) <a href="#getmachinesnapshot" id="getmachinesnapshot"></a>

Gets the state of the named snapshot.

#### Inputs <a href="#inputs-55" id="inputs-55"></a>

* None

#### Returns <a href="#returns-55" id="returns-55"></a>

| **Field** | **Type** | **Description**                                               |
| --------- | -------- | ------------------------------------------------------------- |
| name      | String   | The name of this snapshot                                     |
| state     | String   | The current state of the snapshot (poll until it's "created") |

#### Errors <a href="#errors-55" id="errors-55"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                              |
| ---------------- | -------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:name` does not exist |

#### CLI Command <a href="#cli-command-52" id="cli-command-52"></a>

```
triton instance snapshot get 5e42cd1e-34bb-402f-8796-bf5a2cae47db just-booted
```

or

```
sdc-getmachinesnapshot --snapshot=just-booted 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-49" id="example-request-49"></a>

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots/just-booted HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8
```

#### Example Response <a href="#example-response-49" id="example-response-49"></a>

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE
Connection: close
Date: Tue, 05 Jul 2011 17:26:56 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: af79d9cd-68c5-4002-95c6-af4c3ff0f1e4
Response-Time: 297
Content-Type: application/json
Content-MD5: VoPeS9cac4YMBIs8gUkd/A==
Content-Length: 117

{
  "name": "just-booted",
  "state": "queued",
  "created": "2011-07-05T17:19:26+00:00",
  "updated": "2011-07-05T17:19:26+00:00"
}
```

### DeleteMachineSnapshot (DELETE /:login/machines/:id/snapshots/:name) <a href="#deletemachinesnapshot" id="deletemachinesnapshot"></a>

Deletes the specified snapshot of an instance.

#### Inputs <a href="#inputs-56" id="inputs-56"></a>

* None

#### Returns <a href="#returns-56" id="returns-56"></a>

* None

#### Errors <a href="#errors-56" id="errors-56"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                              |
| ---------------- | -------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:name` does not exist |

#### CLI Command <a href="#cli-command-53" id="cli-command-53"></a>

```
triton instance snapshot delete 5e42cd1e-34bb-402f-8796-bf5a2cae47db just-booted
```

or

```
sdc-deletemachinesnapshot --snapshot=just-booted 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-50" id="example-request-50"></a>

```
DELETE /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/snapshots/just-booted HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8
```

#### Example Response <a href="#example-response-50" id="example-response-50"></a>

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE
Connection: close
Date: Tue, 05 Jul 2011 17:26:56 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: af79d9cd-68c5-4002-95c6-af4c3ff0f1e4
Response-Time: 297
Content-Length: 0
```

### CreateMachineDisk (POST /:login/machines/:id/disks) <a href="#createmachinedisk" id="createmachinedisk"></a>

**Interface is experimental; details may change in the future**

Create a new disk for a bhyve VM.

The sum of all disk sizes on a VM is limited by flexible disk space. This operation only applies for VMs that are currently stopped.

#### Inputs <a href="#inputs-57" id="inputs-57"></a>

| **Field** | **Type** | **Description**                                                                |
| --------- | -------- | ------------------------------------------------------------------------------ |
| pci\_slot | String   | Optional, PCI slot that the disk will fill                                     |
| size      | Number   | Size in MiB, or the string "remaining" to use up all remaining available space |

#### Returns <a href="#returns-57" id="returns-57"></a>

If no `pci_slot` argument was provided, then only a 202 (and no object) will be returned. You will need to poll [ListMachineDisks](https://apidocs.joyent.com/cloudapi/#list-machine-disks) until a new disk appears (if successful). `pci_slot` will be automatically assigned in this case.

If a `pci_slot` argument was provided, the `Location` header will be set, and 200 (with object) will be returned:

| **Field** | **Type** | **Description**                         |
| --------- | -------- | --------------------------------------- |
| id        | String   | This disk's UUID                        |
| pci\_slot | String   | This disk's PCI slot                    |
| size      | Number   | Size in MiB (before resize)             |
| boot      | Boolean  | If this is the VM's boot disk           |
| state     | String   | Current state of disk (i.e. 'creating') |

#### Errors <a href="#errors-57" id="errors-57"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |
| InvalidArgument  | If `size` or `pci_slot` was invalid |

#### CLI Command <a href="#cli-command-54" id="cli-command-54"></a>

```
triton cloudapi /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks \
  -X POST -d '{"pci_slot":"0:4:1", "size": 1024}'
```

#### Example Request <a href="#example-request-51" id="example-request-51"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~9

pci_slot=0:4:1
size=1024
```

#### Example Response <a href="#example-response-51" id="example-response-51"></a>

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Dec 2018 17:19:26 GMT
Server: Joyent Triton 9.4.0
Api-Version: 9.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-Length: 0

{
  "id": "21f04764-1db8-47dc-acfd-2215f2b842e9",
  "pci_slot": "0:4:1",
  "size": 1024,
  "boot": false,
  "state": "creating"
}
```

### ResizeMachineDisk (POST /:login/machines/:id/disks/:disk\_id) <a href="#resizemachinedisk" id="resizemachinedisk"></a>

**Interface is experimental; details may change in the future**

Asynchronously resize an existing disk on a bhyve VM.

The sum of all disk sizes on a VM is limited by flexible disk space. This operation only applies for VMs that are currently stopped.

When resizing down, `dangerous_allow_shrink` must be set to `true` otherwise the resize will be rejected. Since shrinking a disk truncates any data within that disk, it can cause filesystem corruption and data loss if the guest operating system does not handle it appropriately and data on the disk hasn't been prepared properly beforehand.

Since this is an asynchronous operation, resizing may take several seconds. Check the disk's state using [GetMachineDisk](https://apidocs.joyent.com/cloudapi/#GetMachineDisk).

#### Inputs <a href="#inputs-58" id="inputs-58"></a>

| **Field**                | **Type** | **Description**                          |
| ------------------------ | -------- | ---------------------------------------- |
| size                     | Number   | Size in MiB                              |
| dangerous\_allow\_shrink | Boolean  | Optional, whether a disk can reduce size |

#### Returns <a href="#returns-58" id="returns-58"></a>

| **Field** | **Type** | **Description**                         |
| --------- | -------- | --------------------------------------- |
| id        | String   | This disk's UUID                        |
| pci\_slot | String   | This disk's PCI slot                    |
| size      | Number   | Size in MiB (before resize)             |
| boot      | Boolean  | If this is the VM's boot disk           |
| state     | String   | Current state of disk (i.e. 'resizing') |

#### Errors <a href="#errors-58" id="errors-58"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                   |
| ---------------- | ------------------------------------------------- |
| ResourceNotFound | If `:login`, `:id`, or `:disk_id` does not exist  |
| InvalidArgument  | If `size` or `dangerous_allow_shrink` was invalid |

#### CLI Command <a href="#cli-command-55" id="cli-command-55"></a>

```
triton cloudapi /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9 \
  -X POST -d '{"size": 2048}'
```

#### Example Request <a href="#example-request-52" id="example-request-52"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9 HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~9

size=2048
```

#### Example Response <a href="#example-response-52" id="example-response-52"></a>

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Dec 2018 17:19:26 GMT
Server: Joyent Triton 9.4.0
Api-Version: 9.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 70

{
  "id": "21f04764-1db8-47dc-acfd-2215f2b842e9",
  "pci_slot": "0:4:1",
  "size": 1024,
  "boot": false,
  "state": "resizing"
}
```

### GetMachineDisk (GET /:login/machines/:id/disks/:disk\_id) <a href="#getmachinedisk" id="getmachinedisk"></a>

**Interface is experimental; details may change in the future**

Fetch a specific disk on a bhyve VM.

#### Inputs <a href="#inputs-59" id="inputs-59"></a>

* None

#### Returns <a href="#returns-59" id="returns-59"></a>

| **Field** | **Type** | **Description**               |
| --------- | -------- | ----------------------------- |
| id        | String   | This disk's UUID              |
| pci\_slot | String   | This disk's PCI slot          |
| size      | Number   | Size in MiB                   |
| boot      | Boolean  | If this is the VM's boot disk |
| state     | String   | Current state of disk         |

#### Errors <a href="#errors-59" id="errors-59"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                  |
| ---------------- | ------------------------------------------------ |
| ResourceNotFound | If `:login`, `:id`, or `:disk_id` does not exist |

#### CLI Command <a href="#cli-command-56" id="cli-command-56"></a>

```
triton cloudapi /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9
```

#### Example Request <a href="#example-request-53" id="example-request-53"></a>

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9 HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~9
```

#### Example Response <a href="#example-response-53" id="example-response-53"></a>

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Dec 2018 17:19:26 GMT
Server: Joyent Triton 9.4.0
Api-Version: 9.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 74

{
  "id": "21f04764-1db8-47dc-acfd-2215f2b842e9",
  "pci_slot": "0:4:1",
  "size": 2048,
  "boot": false,
  "state": "running",
}
```

### ListMachineDisks (GET /:login/machines/:id/disks) <a href="#listmachinedisks" id="listmachinedisks"></a>

**Interface is experimental; details may change in the future**

List all disk on a bhyve VM.

#### Inputs <a href="#inputs-60" id="inputs-60"></a>

* None

#### Returns <a href="#returns-60" id="returns-60"></a>

| **Field** | **Type** | **Description**               |
| --------- | -------- | ----------------------------- |
| id        | String   | This disk's UUID              |
| pci\_slot | String   | This disk's PCI slot          |
| size      | Number   | Size in MiB                   |
| boot      | Boolean  | If this is the VM's boot disk |
| state     | String   | Current state of disk         |

#### Errors <a href="#errors-60" id="errors-60"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-57" id="cli-command-57"></a>

```
triton cloudapi /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks
```

#### Example Request <a href="#example-request-54" id="example-request-54"></a>

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~9
```

#### Example Response <a href="#example-response-54" id="example-response-54"></a>

```
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Dec 2018 17:19:26 GMT
Server: Joyent Triton 9.4.0
Api-Version: 9.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 74

[
  {
    "id": "2bb08ea6-1da0-11e9-adaa-23f0e1aab5d7",
    "pci_slot": "0:4:0",
    "size": 10240,
    "boot": true,
    "state": "running",
  },
  {
    "id": "21f04764-1db8-47dc-acfd-2215f2b842e9",
    "pci_slot": "0:4:1",
    "size": 2048,
    "boot": false,
    "state": "running",
  }
]
```

### DeleteMachineDisk (DELETE /:login/machines/:id/disks/:disk\_id) <a href="#deletemachinedisk" id="deletemachinedisk"></a>

**Interface is experimental; details may change in the future**

Asynchronously delete a disk off a bhyve VM.

Since this is an asynchronous operation, deletion may take several seconds. You can check the disk's state using [GetMachineDisk](https://apidocs.joyent.com/cloudapi/#GetMachineDisk).

#### Inputs <a href="#inputs-61" id="inputs-61"></a>

* None

#### Returns <a href="#returns-61" id="returns-61"></a>

* None

#### Errors <a href="#errors-61" id="errors-61"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                                 |
| ---------------- | ----------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:disk_id` does not exist |

#### CLI Command <a href="#cli-command-58" id="cli-command-58"></a>

```
triton cloudapi /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9 -X DELETE
```

#### Example Request <a href="#example-request-55" id="example-request-55"></a>

```
DELETE /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/disks/21f04764-1db8-47dc-acfd-2215f2b842e9 HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~9
```

#### Example Response <a href="#example-response-55" id="example-response-55"></a>

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Dec 2018 17:19:26 GMT
Server: Joyent Triton 9.4.0
Api-Version: 9.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
```

### UpdateMachineMetadata (POST /:login/machines/:id/metadata) <a href="#updatemachinemetadata" id="updatemachinemetadata"></a>

Allows you to update the metadata for a given instance. Note that updating the metadata via CloudAPI will result in the metadata being updated in the running instance.

The semantics of this call are subtly different that the AddMachineTags call -- any metadata keys passed in here are created if they do not exist, and overwritten if they do.

#### Inputs <a href="#inputs-62" id="inputs-62"></a>

| **Field** | **Type** | **Description**                                                                                                            |
| --------- | -------- | -------------------------------------------------------------------------------------------------------------------------- |
| $key      | String   | You can assign any number of metadata keys in this call; the string can be either a plain string, or a JSON-encoded object |

#### Returns <a href="#returns-62" id="returns-62"></a>

Returns the current set of tags.

| **Field** | **Type** | **Description** |
| --------- | -------- | --------------- |
| $key      | Object   | Your value(s)   |

#### Errors <a href="#errors-62" id="errors-62"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-59" id="cli-command-59"></a>

```
sdc-updatemachinemetadata -m foo=bar -m group=test cf055959-d776-482e-bd71-ca510a04bdd7
```

#### Example Request <a href="#example-request-56" id="example-request-56"></a>

```
POST /my/machines/cf055959-d776-482e-bd71-ca510a04bdd7/metadata HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Api-Version: ~8

foo=bar&group=test
```

#### Example Response <a href="#example-response-56" id="example-response-56"></a>

```
HTTP/1.1 200 Ok
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 116

{
  "foo": "bar",
  "group": "test"
}
```

### ListMachineMetadata (GET /:login/machines/:id/metadata) <a href="#listmachinemetadata" id="listmachinemetadata"></a>

Returns the complete set of metadata associated with this instance.

#### Inputs <a href="#inputs-63" id="inputs-63"></a>

| **Field**   | **Type** | **Description**                                                  |
| ----------- | -------- | ---------------------------------------------------------------- |
| credentials | Boolean  | Whether or not to return instance credentials. Defaults to false |

#### Returns <a href="#returns-63" id="returns-63"></a>

Returns the current metadata object

| **Field** | **Type** | **Description** |
| --------- | -------- | --------------- |
| $name     | Object   | Your metadata   |

#### Errors <a href="#errors-63" id="errors-63"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-60" id="cli-command-60"></a>

```
sdc-listmachinemetadata cf055959-d776-482e-bd71-ca510a04bdd7
```

#### Example Request <a href="#example-request-57" id="example-request-57"></a>

```
GET /my/machines/cf055959-d776-482e-bd71-ca510a04bdd7/metadata?credentials=true HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-57" id="example-response-57"></a>

```
HTTP/1.1 200 Ok
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 116

{
  "foo": "bar",
  "group": "test",
  "credentials": {
    "root": "s8v9kuht5e",
    "admin": "mf4bteqhpy"
  }
}
```

### GetMachineMetadata (GET /:login/machines/:id/metadata/:key) <a href="#getmachinemetadata" id="getmachinemetadata"></a>

Returns a single metadata entry associated with this instance.

#### Inputs <a href="#inputs-64" id="inputs-64"></a>

| **Field** | **Type** | **Description**                    |
| --------- | -------- | ---------------------------------- |
| key       | String   | Name of metadata value to retrieve |

#### Returns <a href="#returns-64" id="returns-64"></a>

Returns metadata value as string.

#### Errors <a href="#errors-64" id="errors-64"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                             |
| ---------------- | ------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:key` does not exist |

#### CLI Command <a href="#cli-command-61" id="cli-command-61"></a>

```
sdc-getmachinemetadata --metadataId=foo cf055959-d776-482e-bd71-ca510a04bdd7
```

#### Example Request <a href="#example-request-58" id="example-request-58"></a>

```
GET /my/machines/cf055959-d776-482e-bd71-ca510a04bdd7/metadata/foo HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-58" id="example-response-58"></a>

```
HTTP/1.1 200 Ok
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2014 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 4

bar
```

### DeleteMachineMetadata (DELETE /:login/machines/:id/metadata/:key) <a href="#deletemachinemetadata" id="deletemachinemetadata"></a>

Deletes a single metadata key from this instance.

#### Inputs <a href="#inputs-65" id="inputs-65"></a>

* None

#### Returns <a href="#returns-65" id="returns-65"></a>

* None

#### Errors <a href="#errors-65" id="errors-65"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                             |
| ---------------- | ------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:key` does not exist |

#### CLI Command <a href="#cli-command-62" id="cli-command-62"></a>

```
sdc-deletemachinemetadata --metadata=foo cf055959-d776-482e-bd71-ca510a04bdd7
```

#### Example Request <a href="#example-request-59" id="example-request-59"></a>

```
DELETE /my/machines/cf055959-d776-482e-bd71-ca510a04bdd7/metadata/foo HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-59" id="example-response-59"></a>

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 0
```

### DeleteAllMachineMetadata (DELETE /:login/machines/:id/metadata) <a href="#deleteallmachinemetadata" id="deleteallmachinemetadata"></a>

Deletes all metadata keys from this instance.

#### Inputs <a href="#inputs-66" id="inputs-66"></a>

* None

#### Returns <a href="#returns-66" id="returns-66"></a>

* None

#### Errors <a href="#errors-66" id="errors-66"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-63" id="cli-command-63"></a>

```
sdc-deletemachinemetadata --metadata='*' cf055959-d776-482e-bd71-ca510a04bdd7
```

If you're running in a Unix-like environment, you may need to quote the wildcard to keep the shell from matching files in the current directory.

#### Example Request <a href="#example-request-60" id="example-request-60"></a>

```
DELETE /my/machines/cf055959-d776-482e-bd71-ca510a04bdd7/metadata HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-60" id="example-response-60"></a>

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Connection: close
Date: Tue, 05 Jul 2011 17:19:26 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
Response-Time: 754
Content-Type: application/json
Content-MD5: qKVbfrhXVqh7Oni6Pub9Pw==
Content-Length: 0
```

### AddMachineTags (POST /:login/machines/:id/tags) <a href="#addmachinetags" id="addmachinetags"></a>

Set tags on the given instance. A pre-existing tag with the same name as one given will be overwritten.

Note: This action is asynchronous. You can poll on `ListMachineTags` to wait for the update to be complete (the `triton instance tag set -w,--wait` option does this).

#### Inputs <a href="#inputs-67" id="inputs-67"></a>

Tag name/value pairs. Input data is typically as a application/json POST body. However, query params or `application/x-www-form-urlencoded`-encoded body also works. Tag values may be strings, numbers or booleans.

#### Returns <a href="#returns-67" id="returns-67"></a>

Returns the resultant set of tags as a JSON object.

#### Errors <a href="#errors-67" id="errors-67"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-64" id="cli-command-64"></a>

Using node-triton:

```
triton instance tag set -w 5e42cd1e foo=bar group=test
```

Using node-smartdc:

```
sdc-addmachinetags --tag='foo=bar' --tag='group=test' 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-61" id="example-request-61"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags HTTP/1.1
Host: us-east-3b.api.joyent.com
date: Thu, 11 Feb 2016 18:03:46 GMT
authorization: ...
accept: application/json
content-type: application/json
accept-version: ~8||~7
content-length: 28

{"foo":"bar","group":"test"}
```

#### Example Response <a href="#example-response-61" id="example-response-61"></a>

```
HTTP/1.1 200 OK
server: Joyent Triton 8.0.0
request-id: cb65c530-d0e9-11e5-ac0c-090497b36c30
date: Thu, 11 Feb 2016 18:03:46 GMT
response-time: 91
...
api-version: 8.0.0
content-length: 48

{"foo":"bar","group":"test","preexiting":"blah"}
```

### ReplaceMachineTags (PUT /:login/machines/:id/tags) <a href="#replacemachinetags" id="replacemachinetags"></a>

Fully replace all tags on an instance with the given tags.

Note: This action is asynchronous. You can poll on `ListMachineTags` to wait for the update to be complete (the `triton instance tag replace-all -w,--wait` option does this).

#### Inputs <a href="#inputs-68" id="inputs-68"></a>

Input data is typically as a application/json POST body. However, query params or `application/x-www-form-urlencoded`-encoded body also works. Tag values may be strings, numbers or booleans.

#### Returns <a href="#returns-68" id="returns-68"></a>

Returns the resultant set of tags as a JSON object.

#### Errors <a href="#errors-68" id="errors-68"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-65" id="cli-command-65"></a>

Using node-triton:

```
triton instance tag replace-all -w 5e42cd1e foo=bar group=test
```

Using node-smartdc:

```
sdc-replacemachinetags --tag='foo=bar' --tag='group=test' 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-62" id="example-request-62"></a>

```
POST /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags HTTP/1.1
Host: us-east-3b.api.joyent.com
date: Thu, 11 Feb 2016 18:03:46 GMT
authorization: ...
accept: application/json
content-type: application/json
accept-version: ~8||~7
content-length: 28

{"foo":"bar","group":"test"}
```

#### Example Response <a href="#example-response-62" id="example-response-62"></a>

```
HTTP/1.1 200 OK
server: Joyent Triton 8.0.0
request-id: cb65c530-d0e9-11e5-ac0c-090497b36c30
date: Thu, 11 Feb 2016 18:03:46 GMT
response-time: 91
...
api-version: 8.0.0
content-length: 28

{"foo":"bar","group":"test"}
```

### ListMachineTags (GET /:login/machines/:id/tags) <a href="#listmachinetags" id="listmachinetags"></a>

Returns the complete set of tags associated with this instance.

#### Inputs <a href="#inputs-69" id="inputs-69"></a>

None.

#### Returns <a href="#returns-69" id="returns-69"></a>

Returns the current set of tags as a JSON object.

#### Errors <a href="#errors-69" id="errors-69"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-66" id="cli-command-66"></a>

Using node-triton:

```
triton instance tag list 5e42cd1e
{
    "foo": "bar",
    "group": "test"
}
$ triton instance tags 5e42cd1e    # shortcut
{
    "foo": "bar",
    "group": "test"
}
```

Using node-smartdc:

```
sdc-listmachinetags 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-63" id="example-request-63"></a>

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags HTTP/1.1
Host: api.example.com
authorization: ...
accept: application/json
accept-version: ~8||~7
```

#### Example Response <a href="#example-response-63" id="example-response-63"></a>

```
HTTP/1.1 200 OK
server: Joyent Triton 8.0.0
request-id: 4bcf467e-4b88-4ab4-b7ab-65fad7464de9
date: Thu, 11 Feb 2016 18:03:46 GMT
response-time: 91
...
api-version: 8.0.0
content-length: 28

{"foo":"bar","group":"test"}
```

### GetMachineTag (GET /:login/machines/:id/tags/:tag) <a href="#getmachinetag" id="getmachinetag"></a>

Returns the value for a single tag on this instance.

Typically one calls CloudAPI endpoints with `Accept: application/json`. This endpoint can be called that way, or alternatively with `Accept: text/plain` to get the non-JSON value in the response.

#### Inputs <a href="#inputs-70" id="inputs-70"></a>

None.

#### Returns <a href="#returns-70" id="returns-70"></a>

The tag value.

#### Errors <a href="#errors-70" id="errors-70"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                             |
| ---------------- | ------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:tag` does not exist |

#### CLI Command <a href="#cli-command-67" id="cli-command-67"></a>

Using node-triton:

```
triton instance tag get 5e42cd1e foo
bar
$ triton instance tag get --json 5e42cd1e foo   # encoded as JSON
"bar"
```

Using node-smartdc:

```
sdc-getmachinetag --tag=foo 5e42cd1e-34bb-402f-8796-bf5a2cae47db
bar
```

#### Example Request/Response <a href="#example-requestresponse" id="example-requestresponse"></a>

Using `application/json`, the request:

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags/foo HTTP/1.1
Host: api.example.com
authorization: ...
accept: application/json
accept-version: ~8||~7
```

the response:

```
HTTP/1.1 200 OK
...
content-type: application/json
content-length: 5

"bar"
```

Using `text/plain`, the request:

```
GET /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags/foo HTTP/1.1
Host: api.example.com
authorization: ...
accept: text/plain
accept-version: ~8||~7
```

the response:

```
HTTP/1.1 200 OK
...
content-type: text/plain
content-length: 3

bar
```

### DeleteMachineTag (DELETE /:login/machines/:id/tags/:tag) <a href="#deletemachinetag" id="deletemachinetag"></a>

Deletes a single tag from this instance.

Note: This action is asynchronous. You can poll on `ListMachineTags` to wait for the update to be complete (the `triton instance tag delete -w,--wait` option does this).

#### Inputs <a href="#inputs-71" id="inputs-71"></a>

* None

#### Returns <a href="#returns-71" id="returns-71"></a>

* None

#### Errors <a href="#errors-71" id="errors-71"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                             |
| ---------------- | ------------------------------------------- |
| ResourceNotFound | If `:login`, `:id` or `:tag` does not exist |

#### CLI Command <a href="#cli-command-68" id="cli-command-68"></a>

Using node-triton:

```
triton instance tag delete -w 5e42cd1e foo
```

Using node-smartdc:

```
sdc-deletemachinetag --tag=foo 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-64" id="example-request-64"></a>

```
DELETE /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags/foo HTTP/1.1
Host: api.example.com
authorization: ...
accept: text/plain
accept-version: ~8||~7
```

#### Example Response <a href="#example-response-64" id="example-response-64"></a>

```
HTTP/1.1 204 No Content
...
```

### DeleteMachineTags (DELETE /:login/machines/:id/tags) <a href="#deletemachinetags" id="deletemachinetags"></a>

Deletes all tags from an instance.

Note: This action is asynchronous. You can poll on `ListMachineTags` to wait for the update to be complete (the `triton instance tag delete -w,--wait` option does this).

#### Inputs <a href="#inputs-72" id="inputs-72"></a>

* None

#### Returns <a href="#returns-72" id="returns-72"></a>

* None

#### Errors <a href="#errors-72" id="errors-72"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-69" id="cli-command-69"></a>

Using node-triton:

```
triton instance tag delete -w --all 5e42cd1e
```

Using node-smartdc:

```
# Remember to quote the `*` to avoid shell expansion.
$ sdc-deletemachinetag --tag='*' 5e42cd1e-34bb-402f-8796-bf5a2cae47db
```

#### Example Request <a href="#example-request-65" id="example-request-65"></a>

```
DELETE /my/machines/5e42cd1e-34bb-402f-8796-bf5a2cae47db/tags HTTP/1.1
Host: api.example.com
authorization: ...
accept: text/plain
accept-version: ~8||~7
```

#### Example Response <a href="#example-response-65" id="example-response-65"></a>

```
HTTP/1.1 204 No Content
...
```

### DeleteMachine (DELETE /:login/machines/:id) <a href="#deletemachine" id="deletemachine"></a>

Allows you to completely destroy an instance.

An instance cannot be destroyed so long as [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection) is enabled on that instance.

#### Inputs <a href="#inputs-73" id="inputs-73"></a>

* None

#### Returns <a href="#returns-73" id="returns-73"></a>

* None

#### Errors <a href="#errors-73" id="errors-73"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**       | **Description**                                                                                             |
| -------------------- | ----------------------------------------------------------------------------------------------------------- |
| ResourceNotFound     | If `:login` or `:id` does not exist                                                                         |
| InvalidState         | The instance is in the wrong state to be deleted                                                            |
| CannotDestroyMachine | [Deletion Protection](https://apidocs.joyent.com/cloudapi/#deletion-protection) is enabled on this instance |

#### CLI Command <a href="#cli-command-70" id="cli-command-70"></a>

```
triton instance delete 75cfe125-a5ce-49e8-82ac-09aa31ffdf26
```

or

```
sdc-deletemachine 75cfe125-a5ce-49e8-82ac-09aa31ffdf26
```

#### Example Request <a href="#example-request-66" id="example-request-66"></a>

```
DELETE /my/machines/75cfe125-a5ce-49e8-82ac-09aa31ffdf26 HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

**Example Response**

```
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE
Server: Joyent Triton 8.0.0
Connection: close
Date: Wed, 13 Apr 2011 23:38:03 GMT
Api-Version: 8.0.0
Request-Id: 762C3F37-8ACA-4A49-AF10-84CEC8137B1D
Response-Time: 72
Content-Length: 0
```

### MachineAudit (GET /:login/machines/:id/audit) <a href="#machineaudit" id="machineaudit"></a>

Provides a list of an instance's accomplished actions. Results are sorted from newest to oldest action.

Note that the complete audit trail is returned only if the instance history and job records have not been purged from Triton.

#### Inputs <a href="#inputs-74" id="inputs-74"></a>

* None

#### Returns <a href="#returns-74" id="returns-74"></a>

* An array of action objects, which contain:

| **Field** | **Type**       | **Description**                                         |
| --------- | -------------- | ------------------------------------------------------- |
| action    | String         | The name of the action                                  |
| success   | String         | Either "yes" or "no", depending on the action's success |
| caller    | Object         | Account requesting the action                           |
| time      | Date (ISO8601) | When the action finished                                |

Depending on the account requesting the action, `caller` can have the following members:

| **Field** | **Type** | **Description**                                                                                |
| --------- | -------- | ---------------------------------------------------------------------------------------------- |
| type      | String   | Authentication type for the action request. One of "basic", "operator", "signature" or "token" |
| user      | String   | When the authentication type is "basic", this member will be present and include user login    |
| ip        | String   | The IP addresses this from which the action was requested. Not present if type is "operator"   |
| keyId     | String   | When authentication type is either "signature" or "token", SSH key identifier                  |

#### Errors <a href="#errors-74" id="errors-74"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-71" id="cli-command-71"></a>

```
triton instance audit 75cfe125-a5ce-49e8-82ac-09aa31ffdf26
```

or

```
sdc-getmachineaudit 75cfe125-a5ce-49e8-82ac-09aa31ffdf26
```

#### Example Request <a href="#example-request-67" id="example-request-67"></a>

```
GET /my/machines/75cfe125-a5ce-49e8-82ac-09aa31ffdf26/audit HTTP/1.1
Authorization: ...
Host: api.example.com
Accept: application/json
Api-Version: ~8
```

**Example Response**

```
HTTP/1.1 200 OK
content-type: application/json
content-length: 191
access-control-allow-origin: *
access-control-allow-headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
access-control-allow-methods: GET
access-control-expose-headers: Api-Version, Request-Id, Response-Time
connection: Keep-Alive
content-md5: GRmOq/dAdKZJ4wVpEelRrQ==
date: Fri, 22 Feb 2013 15:19:37 GMT
server: Joyent Triton 8.0.0
api-version: 8.0.0
request-id: 453aee00-7d03-11e2-8048-5195b6159808
response-time: 34

[{
    "success": "yes",
    "time": "2013-02-22T15:19:32.522Z",
    "action": "provision",
    "caller": {
      "type": "signature",
      "ip": "127.0.0.1",
      "keyId": "/:login/keys/:fingerprint"
    }
  }, ...]
```

### Deletion Protection <a href="#deletion-protection" id="deletion-protection"></a>

If you want to decrease the risk of accidental instance destruction, it is possible to make instance destruction (e.g. through [DeleteMachine](https://apidocs.joyent.com/cloudapi/#DeleteMachine)) a two-step process.

Instances that have the attribute `deletion_protection` set to boolean `true` cannot be deleted, either through CloudAPI or SDC Docker. In order to delete such an instance, the above attribute needs to be set to false first.

The attribute can be set during instance creation (see [CreateMachine](https://apidocs.joyent.com/cloudapi/#CreateMachine)), or added later (see [EnableMachineDeletionProtection](https://apidocs.joyent.com/cloudapi/#EnableMachineDeletionProtection)). The instance then cannot be destroyed until the attribute is set to false, although all other operations will still work. To destroy the instance, first call [DisableMachineDeletionProtection](https://apidocs.joyent.com/cloudapi/#DisableMachineDeletionProtection)) on the instance.

#### CLI Commands <a href="#cli-commands" id="cli-commands"></a>

```
triton instance create 62aaa296 0ea54d9d --deletion-protection

$ triton instance disable-deletion-protection 9985bc81

$ triton instance enable-deletion-protection 9985bc81
```


# Packages

Packages are named collections of resources to describe the dimensions of either a container or a hardware virtual machine. These resources include (but are not limited to) RAM, DISK & CPU caps.

### ListPackages (GET /:login/packages) <a href="#listpackages" id="listpackages"></a>

Provides a list of packages available in this datacenter.

#### Inputs <a href="#inputs-38" id="inputs-38"></a>

* The following are all optional inputs:

| **Field**      | **Type** | **Description**                                            |
| -------------- | -------- | ---------------------------------------------------------- |
| name           | String   | The "friendly" name for this package                       |
| memory         | Number   | How much memory will by available (in MiB)                 |
| disk           | Number   | How much disk space will be available (in MiB)             |
| swap           | Number   | How much swap space will be available (in MiB)             |
| lwps           | Number   | Maximum number of light-weight processes (threads) allowed |
| vcpus          | Number   | Number of vCPUs for this package                           |
| version        | String   | The version of this package                                |
| group          | String   | The group this package belongs to                          |
| flexible\_disk | Boolean  | Whether this is a flexible\_disk package                   |

When any values are provided for one or more of the aforementioned inputs, the retrieved packages will match all of them.

When querying, wildcards (i.e. '*') are allowed for string fields. For example, to list all packages with a name that starts with "foo", give "foo*" as the package name.

#### Returns <a href="#returns-38" id="returns-38"></a>

An array of objects, of the form:

| **Field**      | **Type** | **Description**                                                         |
| -------------- | -------- | ----------------------------------------------------------------------- |
| id             | UUID     | Unique id for this package                                              |
| name           | String   | The "friendly" name for this package                                    |
| memory         | Number   | How much memory will by available (in MiB)                              |
| disk           | Number   | How much disk space will be available (in MiB)                          |
| swap           | Number   | How much swap space will be available (in MiB)                          |
| lwps           | Number   | Maximum number of light-weight processes (threads) allowed              |
| vcpus          | Number   | Number of vCPUs for this package                                        |
| version        | String   | The version of this package                                             |
| group          | String   | The group this package belongs to                                       |
| description    | String   | A human-friendly description about this package                         |
| disks          | Array    | The disks this package contains (Allowed when flexible\_disk is `true`) |
| flexible\_disk | Boolean  | Whether this is a flexible\_disk package (bhyve only)                   |
| default        | Boolean  | (deprecated) Whether this is the default package in this datacenter     |

#### Errors <a href="#errors-38" id="errors-38"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**            |
| ---------------- | -------------------------- |
| ResourceNotFound | If `:login` does not exist |

#### CLI Command <a href="#cli-command-37" id="cli-command-37"></a>

```
triton package list
```

or

```
sdc-listpackages
```

#### Example Request <a href="#example-request-32" id="example-request-32"></a>

```
GET /my/packages HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-32" id="example-response-32"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 314
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: u0+0E3G28WL4Y4K8p6+pIg==
Date: Thu, 21 Jan 2016 08:33:52 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: b24219e0-c019-11e5-99e1-8339f3270a9f
Response-Time: 1992

[
  {
    "id": "7b17343c-94af-6266-e0e8-893a3b9993d0",
    "name": "sdc_128",
    "memory": 128,
    "disk": 12288,
    "swap": 256,
    "vcpus": 1,
    "lwps": 1000,
    "default": false,
    "version": "1.0.0"
  },
  ...
]
```

### GetPackage (GET /:login/packages/:id) <a href="#getpackage" id="getpackage"></a>

Gets a package by `name` or `id`.

#### Inputs <a href="#inputs-39" id="inputs-39"></a>

* None

#### Returns <a href="#returns-39" id="returns-39"></a>

| **Field**      | **Type** | **Description**                                                         |
| -------------- | -------- | ----------------------------------------------------------------------- |
| id             | UUID     | Unique id for this package                                              |
| name           | String   | The "friendly" name for this package                                    |
| memory         | Number   | How much memory will by available (in MiB)                              |
| disk           | Number   | How much disk space will be available (in MiB)                          |
| swap           | Number   | How much swap space will be available (in MiB)                          |
| lwps           | Number   | Maximum number of light-weight processes (threads) allowed              |
| vcpus          | Number   | Number of vCPUs for this package                                        |
| version        | String   | The version of this package                                             |
| group          | String   | The group this package belongs to                                       |
| description    | String   | A human-friendly description about this package                         |
| disks          | Array    | The disks this package contains (Allowed when flexible\_disk is `true`) |
| flexible\_disk | Boolean  | Whether this is a flexible\_disk package (bhyve only)                   |
| default        | Boolean  | (deprecated) Whether this is the default package in this datacenter     |

#### Errors <a href="#errors-39" id="errors-39"></a>

For all possible errors, see [CloudAPI HTTP Responses](https://apidocs.joyent.com/cloudapi/#cloudapi-http-responses).

| **Error Code**   | **Description**                     |
| ---------------- | ----------------------------------- |
| ResourceNotFound | If `:login` or `:id` does not exist |

#### CLI Command <a href="#cli-command-38" id="cli-command-38"></a>

```
triton package get 7b17343c-94af-6266-e0e8-893a3b9993d0
```

or

```
sdc-getpackage 7b17343c-94af-6266-e0e8-893a3b9993d0
```

#### Example Request <a href="#example-request-33" id="example-request-33"></a>

```
GET /my/packages/7b17343c-94af-6266-e0e8-893a3b9993d0 HTTP/1.1
Host: api.example.com
Authorization: ...
Accept: application/json
Api-Version: ~8
```

#### Example Response <a href="#example-response-33" id="example-response-33"></a>

```
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 156
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, Api-Version, Response-Time
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Expose-Headers: Api-Version, Request-Id, Response-Time
Connection: Keep-Alive
Content-MD5: MEUpS89GsEaHBykatBp5rg==
Date: Thu, 21 Jan 2016 08:37:04 GMT
Server: Joyent Triton 8.0.0
Api-Version: 8.0.0
Request-Id: 253dd4c0-c01a-11e5-b5f9-2b49303f7fc4
Response-Time: 1482

{
  "id": "7b17343c-94af-6266-e0e8-893a3b9993d0",
  "name": "sdc_128",
  "memory": 128,
  "disk": 12288,
  "swap": 256,
  "vcpus": 1,
  "lwps": 1000,
  "default": false,
  "version": "1.0.0"
}
```


# Contacting Support

MNX offers several levels of support.

### [Information needed when contacting Support](/contacting-mnx-support#information-needed-when-contacting-support) <a href="#information-needed-when-contacting-support" id="information-needed-when-contacting-support"></a>

When contacting MNX support it is very helpful that you have the following information available.

This information is vital for MNX engineers to assist you quickly.

#### [IP address of system](/contacting-mnx-support#ip-address-of-system) <a href="#ip-address-of-system" id="ip-address-of-system"></a>

We need to know which system you are having an issue with.

Please make sure you give us the IP, hostname, and/or UUID of your system so that we can log into it. Read the directions on how to get your [instance IP address](/network/frequently-asked-questions#how-do-i-find-my-ip-addresses).

#### [Description of the issue](/contacting-mnx-support#description-of-the-issue) <a href="#description-of-the-issue" id="description-of-the-issue"></a>

Give as many details as possible to describe the issue you are having with your instance or system. This information could include what services are not working and exactly what steps you have taken to accomplish your goals. The more information the better.

For example:

> Webserver for [www.foo.com](http://www.foo.com) is not serving pages, and I am unable to ping the IP ( 123.456.123.456 ) from my home office workstation. I am accessing this webserver on macOS Sierra from Safari.

#### [Changes made to your system](/contacting-mnx-support#changes-made-to-your-system) <a href="#changes-made-to-your-system" id="changes-made-to-your-system"></a>

Please let us know if you have made any changes to your system prior to system failure. This can include package updates, new version of application code, changes to configuration files, and anything else that may have changed.

#### [Monitoring information](/contacting-mnx-support#monitoring-information) <a href="#monitoring-information" id="monitoring-information"></a>

We highly recommend setting up a monitoring and alerting system for your application and servers. Not only does monitoring assist you with capacity planning, but when issues happen, you can provide MNX support with access to your monitoring so that we can quickly assist you.

Send screen captures of the alerts that you receive from your systems.

#### [Traceroute from your workstation to your MNX host](/contacting-mnx-support#traceroute-from-your-workstation-to-your-joyent-host) <a href="#traceroute-from-your-workstation-to-your-joyent-host" id="traceroute-from-your-workstation-to-your-joyent-host"></a>

If you are having a network issue from your workstation to your server, please send up the output of traceroute (or mtr).

This helps us see if there is a network issue and where is may exist.

To run traceroute from macOS:

1. Open the Network Utility application.
2. Select the **Traceroute** tab and enter the hostname.
3. Open Terminal.
4. From Terminal, enter the command `traceroute <hostname>`.
5. You may have to wait up to a minute or more for the test to complete. This will generate alist of the connections along the way information about the speed of those steps.
6. Copy the complete results and include it in your email to support.

### [Email](/contacting-mnx-support#email) <a href="#email" id="email"></a>

Sending an email to <helpdesk@mnxsolutions.com> is the best way to get help.

This allows you to attache files and provide the above information we need to assist you.

When sending in a request that requires MNX to modify your account, you will need to send this email from an authorized email address.

{% hint style="info" %}
If we can not verify that you are authorized to make requests for that Triton account, we will have to email you back (causing a delay) to assist you. It is always best to send request from an authorized email for fastest service.
{% endhint %}

### [Phone](/contacting-mnx-support#phone) <a href="#phone" id="phone"></a>

For access to MNX support via phone, an extended support contract is needed.

Contact <info@mnx.io> for more information about getting an extended support contract.


# Linux

Overview of Linux Images

* [CentOS](/images/linux/centos)
* [Ubuntu](/images/linux/ubuntu)
* [Debian](/images/linux/debian)


# CentOS

### CentOS-8 - 20200528&#x20;

* A volume group named `rootvg` includes the base `/dev/vda` disk.
* &#x20;`/dev/vdb` is mounted by default to `/data` but can be added to `rootvg` so you can extend `rootlv` (the / mount point) as necessary.
* A base 15GB of storage is allocated to the OS volume (rootvg) in addition to the `/data` storage.

### CentOS-7 - 20200528&#x20;

* A volume group named `rootvg` includes the base `/dev/vda` disk.
* &#x20;`/dev/vdb` is mounted by default to `/data` but can be added to `rootvg` so you can extend `rootlv` (the / mount point) as necessary.
* A base 15GB of storage is allocated to the OS volume (rootvg) in addition to the `/data` storage.

### CentOS-7-cPanel - 20200528&#x20;

* A volume group named `rootvg` includes the base `/dev/vda` disk.
* &#x20;`/dev/vdb` is mounted by default to `/data` but can be added to `rootvg` so you can extend `rootlv` (the / mount point) as necessary.
* A base 15GB of storage is allocated to the OS volume (rootvg) in addition to the `/data` storage.
* The filesystem layout is well suited for cPanel as it includes the following base mount points as logical volumes:
  * `/`, `/usr`, `/var`, and `/home` which can all be extended because they are part of the `rootvg` volume group.


# Ubuntu


# 20.04

## 202104091913

### Changed

* Bhyve Based Image


# Debian


# FreeBSD

Details about the FreeBSD image type


# 12

FreeBSD-12

## 2021040791

FreeBSD  12.2-RELEASE-p6

### Changed

* ZFS based root volume (zroot)
* Bhyve based instance

#### Expanding zroot ZFS pool

By default, /data/ is mounted with the extra disk.  If you would like to add this to you zfs zroot pool you will need to make a few changes. &#x20;

* umount /data
* vi /etc/fstab . (and remove the /data/ mount point)
* Destry the gpt partitioning on /dev/vtbd1 by running:\
  \# gpart destroy -F /dev/vtbd1&#x20;
* Extend the zpool by running:\
  \# zpool add zroot vtbd1


