> For the complete documentation index, see [llms.txt](https://docs.keeper.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keeper.io/sso-connect-cloud/device-approvals/automator/azure-container-app.md).

# Azure Container App

Simple Deployment with Azure Container App

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FiyM8WoJ64cPCYwYOK5Ms%2FAzure%20Container%20Service.jpg?alt=media&#x26;token=232a22f7-8d04-455c-9e6d-fc4133d5ca45" alt=""><figcaption></figcaption></figure>

## Overview

This guide provides step-by-step instructions to publish Keeper Automator to the Azure Container App service. This provides a simple and straightforward way to host the Automator service in the cloud.

{% hint style="info" %}
For environments such as **Azure Government**, **GCC High** and **DoD**, use the [Azure App Services method](/sso-connect-cloud/device-approvals/automator/azure-app-services.md), since the Azure Container App service may not be available in those regions.
{% endhint %}

### (1) Create an Automator Config key

Open a command line interface and generate a 256-bit AES key in URL-encoded format using one of the methods below, depending on your operating system:

#### Generate a Key

{% tabs %}
{% tab title="Mac/Linux" %}

```
openssl rand -base64 32
```

{% endtab %}

{% tab title="Windows (PowerShell)" %}

```powershell
[Byte[]]$key = New-Object Byte[] 32; [System.Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key); [System.Convert]::ToBase64String($key)
```

{% endtab %}
{% endtabs %}

Save the resulting value produced by this command for **Step (3)**.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FG7t1VQUdCjutMBikVSzM%2FScreenshot%202023-12-12%20at%2012.39.19%20PM.png?alt=media&#x26;token=39ff6d4c-e0e3-4a5e-b4fc-56dac5799aeb" alt="" width="375"><figcaption><p>Example of generated key value in Mac/Linux</p></figcaption></figure>

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FZnls6xq1ILfPIShOzhz4%2Fpowershell_ise_CWVvD57ReW.png?alt=media&#x26;token=c88f625f-def8-4004-ac81-4f82c9dc5c52" alt=""><figcaption><p>Example of generated key value in PowerShell</p></figcaption></figure>

{% hint style="info" %}

### AUTOMATOR\_CONFIG\_KEY provides stable encryption key material. It does not replace Automator’s saved configuration. The /usr/mybin/config directory must use persistent storage.

{% endhint %}

### (2) Create a Container Registry

If you do not already have a container registry, you must create one and configure as you see fit, see the example below.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FX0sWfXD1OLOdsN6GOySS%2Fimage.png?alt=media&#x26;token=6cb2523e-bbda-427b-805b-ad1c597f10a7" alt=""><figcaption></figcaption></figure>

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FCz9C645mTtgysG4mORpE%2Fimage.png?alt=media&#x26;token=205f43ce-47f1-48e8-b892-b82b796d7620" alt=""><figcaption></figcaption></figure>

### (3) Create a Container App

From Azure, create a new Container App.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FW3LPFJ5buGX1dV0eHePh%2Fimage.png?alt=media&#x26;token=c7cfa00c-ec22-4ae7-a6a0-89e0af24de0e" alt=""><figcaption></figcaption></figure>

* Select or create a new Resource Group
* Set the Container App Name to "keeperautomator" or whatever you prefer
* Select "**Container Image**" as the Deployment Source
* Select the region where you would like the service hosted
* Create a new Apps Environment or select an existing environment
* Click "**Next: Container"**

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2F4tsoj3svGDp9OZYuN77y%2Fimage.png?alt=media&#x26;token=aa418c1e-2e3b-49b6-81c6-f92db78ad185" alt=""><figcaption></figcaption></figure>

### (4) Setup Container Details

In the "Container" step, make the following selections:

* Uncheck the "**Use quickstart image**"
* Select "**Docker Hub or other registries**"
* Select "**Public**"
* Select Registry login server as **`docker.io`**
* Set the Image and tag as **`keeper/automator:latest`**
* Skip to "Container resource allocation"
* For CPU and Memory, **0.5 CPU** cores and **1Gi** memory is sufficient, but this can be updated based on your volume of new device logins.
* Create an environment variable called **`AUTOMATOR_CONFIG_KEY`** with the value from Step 1 above of the setup guide.
* Create an environment variable called **`AUTOMATOR_PORT`** with the value of **`8089`**
* Create an environment variable called **`SSL_MODE`** with the value of **`none`**
* Click "**Next : Ingress >"**

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FNWrBajjoTL4A3kkhutyw%2Fimage.png?alt=media&#x26;token=a2327378-f24a-4d6c-9906-66635c9c725e" alt=""><figcaption></figcaption></figure>

### (5) Ingress Setup

On the Ingress setup screen, select the following:

* Enable "**Ingress**"
* For Ingress traffic, select "**Accepting traffic from anywhere"** (we'll modify this in a later step)
* For Ingress type, select "**HTTP**"
* Set Target port to "**8089"**

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2F6p7HI3bIhSIHLK0G7iln%2Fimage.png?alt=media&#x26;token=61efb806-b28d-44ce-bc0d-a16ab97ccb50" alt=""><figcaption></figcaption></figure>

### (6) Create Container App

Click "**Review + Create"** > "**Create"**

After a few minutes, the container app will be created and automatically start up.

Clicking on "**Go to Resource**" will take you to the container environment.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2Femv4RBoEMpo3oalntOvt%2Fimage.png?alt=media&#x26;token=b50742ae-1ffc-49fd-a519-91c87d0925d2" alt=""><figcaption></figcaption></figure>

### (7) Finish the Ingress Setup

{% hint style="danger" %}
**Important**: The Keeper Automator service must be deployed with [inbound firewall rules](/sso-connect-cloud/device-approvals/automator/ingress-requirements.md) to ensure that all inbound traffic is restricted to **ONLY** Keeper's infrastructure.
{% endhint %}

To restrict communications to the Keeper Automator service, click on the "Ingress" link on the left side of the screen under the "Network" section.

* Click on "**Ingress"**
* Select "**Allow traffic from IPs configured below, deny all other traffic**"
* Click "**Add**" to add [Keeper's IPs](/sso-connect-cloud/device-approvals/automator/ingress-requirements.md) as [documented here](/sso-connect-cloud/device-approvals/automator/ingress-requirements.md)
* Click "**Save"**

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2Fwztn8Q6tNSHScXtvYlYy%2Fimage.png?alt=media&#x26;token=85e33d55-b8f8-400a-837f-04759d5aa492" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you want to be able to run a health check, then consider adding your own IP address. Find your IP address at <https://checkip.amazonaws.com>
{% endhint %}

### (8) Set Scaling

* Select "**Application > Scale**" and set min and max replicas to "**1**"
* Click "**Save as a new revision**"

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FeXLMCCZt7ZfEvgoIuD8J%2Fimage.png?alt=media&#x26;token=e719180c-e414-48f9-97d1-e0ac790ac358" alt=""><figcaption></figcaption></figure>

### (9) Create or Select Azure Storage

{% hint style="warning" %}
Do not use Ephemeral Storage for /usr/mybin/config. If Automator loses this storage, device approval may fail and recovery may require automator setup and automator init. See [Troubleshooting](https://docs.keeper.io/sso-connect-cloud/device-approvals/automator/troubleshooting).
{% endhint %}

{% hint style="info" %}
Automator requires an Azure Files share for /usr/mybin/config.

If your organization already has a suitable storage account in the same Azure region, use that account and skip to Create the File Share.
{% endhint %}

* Open the Storage accounts in the Azure Portal.
* Click "**Create"**.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2F21wCXAnwjrtXxNXKn7qd%2Fimage.png?alt=media&amp;token=4203fd3d-98c0-4fd1-ad88-31f0038bfb9e" alt=""><figcaption></figcaption></figure>

* Select the same resource group and region as the Container Apps environment
* Select the redundancy, billing, and access tier required by your organization - what is shown is the minimum.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FmMU29xWjxG7C5r6IGVXr%2Fimage.png?alt=media&amp;token=d41e0be4-50cc-41aa-b5d9-eea45e4e4339" alt=""><figcaption></figcaption></figure>

* Create the storage account - remaining default options are acceptable, but if additional hardening is required by your organization follow those policies.

{% hint style="info" %}
For a Container Apps environment without custom VNet integration, leave the storage account public network access enabled so Azure Container Apps can mount the Azure Files share.

For production environments that require private storage access, configure the Container Apps environment with a custom VNet and restrict the storage account to the approved VNet or private endpoint. This requires additional Azure networking configuration.
{% endhint %}

### (10) Create the File Share

* Open the storage account

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FvZNh3G9PhR9H91bCFjOg%2Fimage.png?alt=media&amp;token=c6e16410-75e6-46f5-8bfa-509085a19321" alt=""><figcaption></figcaption></figure>

* Select "**Data Storage > Classic file share**".
* Click + "**Classic file Share"**.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FBbjcq5NSut6dP4EF4p3x%2Fimage.png?alt=media&amp;token=cac57365-ec7f-4cb7-9eeb-4f719fd15cbc" alt=""><figcaption></figcaption></figure>

* Create a share for Automator configuration
* Depending on your previous storage option, the file share configuration may differ - provisioned storage here, 32GiB is not required, 1GiB minimum (Automator config files & logs). Configure Backup according to your organization's policy.

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2Fz4YVqAI6mAx2SZ8B5WA6%2Fimage.png?alt=media&amp;token=a5b5dcbe-3130-4df6-9728-e245ecef154f" alt=""><figcaption></figcaption></figure>

### (11) Attach Storage to Container App

* Back in the container app configuration, under Application > Volumes click 'Add'
* Select Azure file volume, and select the previously created file share name

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FklEWZ6OflPk6keTAYfrN%2Fimage.png?alt=media&amp;token=69baf84e-dca6-44da-80d5-d5ab37ecfff7" alt=""><figcaption></figcaption></figure>

* Click 'Save as a new revision'

### (12) Set up Health Probes and Volume Mount

* Navigate to the "**Application > Revisions and Replicas**" section
* Click on "**Create new revision**"

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FuS8DD2RWzqD2pRa4xPrT%2Fimage.png?alt=media&#x26;token=398c7761-97ba-4d22-b4f6-930eb7fee054" alt=""><figcaption></figcaption></figure>

* Click on "**Application > Revisions**" and replicas an observe a new revision being activated
* Next, click on the "**Container**" tab
* Click on the container image name link, in this case "**keeperautomator**" at the bottom

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FMrGYBnDqhUCsKg0R1ERc%2FOpen%20Container%20to%20edit%20health%20and%20liveness%20probes.jpg?alt=media&#x26;token=e8470f07-6e03-4d7b-b6a3-bebdf13fdb19" alt=""><figcaption></figcaption></figure>

Navigate to Health Probes and enter the following under each section:

Under "Liveness probes"&#x20;

* Enable "liveness probes"
* Transport: **HTTP**
* Path: **/health**
* Port: **8089**
* Initial delay seconds: **5**
* Period seconds: **30**

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2F4kwBiw83kFwEbPComHYg%2Fchrome_oINWWurlIE.png?alt=media&#x26;token=a72780ce-2aec-4372-9c8c-41b01b9652b7" alt="" width="563"><figcaption><p>Liveness probes</p></figcaption></figure>

Under "Startup probes":

* Enable startup probes
* Transport: HTTP
* Path: /health
* Port: 8089
* Initial delay seconds: 5
* Period seconds: 30

Under "Volume Mounts" tab:

* Select "**+ Add**"
* Select the volume you created in a previous step and Add Mount Path as "/usr/mybin/config"

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FFMTQ8OrQWKcfmW8N6eVT%2Fimage.png?alt=media&#x26;token=df28de65-d05f-4ace-adec-4f16e066d5b8" alt=""><figcaption></figcaption></figure>

**Finish the configuration**

* Click on "**Save**"
* Then click on "**Create**" to build the new configuration
* After a few minutes, the new containers should start up

### (13) Retrieve the Application URL

* Wait until the revision is done activating.
* From the Overview section of the Container App, on the right side is the "Application URL" that was assigned. Copy that and use this Application URL in the next step. For example: <https://craigautomator1.xyx> -1234.azurecontainerapps.io

<figure><img src="https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MB_i6vKdtG6Z2n6zWgJ%2Fuploads%2FxM55uGuCaW5JpNYeAWwA%2F5-copy-url.png?alt=media&#x26;token=8302e2f2-b0e0-4553-8ec7-d92389302a17" alt=""><figcaption><p>Retrieve the Application URL</p></figcaption></figure>

### (14) Login to Keeper Commander

Keeper Commander is required to perform the final step of Automator configuration. This can be run from anywhere, it does not need to be installed on the server.

On your workstation or server, install Keeper Commander CLI. The installation instructions including binary installers are [here](/keeperpam/commander-cli/commander-installation-setup.md).\
\
After Commander is installed, launch Keeper Commander, or from an existing terminal you can type `keeper shell` to open the session, then login using the `login` command. In order to set up Automator, you must login as a Keeper Administrator, or an Admin with the ability to manage the SSO node.

```
$ keeper shell

My Vault> login admin@company.com

  _  __  
 | |/ /___ ___ _ __  ___ _ _ 
 | ' </ -_) -_) '_ \/ -_) '_|
 |_|\_\___\___| .__/\___|_|
 v16.x.xxx    |_|

 password manager & digital vault

Logging in to Keeper Commander
Enter password for admin@company.com
Password: ********************
Successfully authenticated with Master Password
Syncing...
Decrypted [58] record(s)

My Vault>
```

### (15) Create the Automator

Create the Automator using a series of commands, starting with `automator create` with your node name.

```
My Vault> automator create --name "My Automator" --node "Azure Cloud"
```

The Node Name (in this case "Azure Cloud") comes from the Admin Console UI as seen below.

![Automator Create](https://2503956294-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MB_i6vKdtG6Z2n6zWgJ%2F-MjGtCqu00Eduh1ZVB0V%2F-MjGwSk57QheWM55KqUd%2FScreen%20Shot%202021-09-10%20at%203.59.58%20PM.png?alt=media\&token=732b0e49-b10f-4718-a78e-f48af15ef50c)

The output of the command will display the Automator settings, including metadata from the identity provider.

```
                    Automator ID: 1477468749950
                            Name: My Automator
                             URL: 
                         Enabled: No
                     Initialized: No
                          Skills: Device Approval
```

Note that the "URL" is not populated yet. This is the Application URL from Step 8.

Run the "automator edit" command as displayed below, which sets the URL and also sets up the skills (`team`, `team_for_user` and `device`).

{% code overflow="wrap" %}

```
automator edit --url https://<application URL> --skill=team --skill=team_for_user --skill=device "My Automator"
```

{% endcode %}

Next we exchange keys: The enterprise private key encrypted with the Automator public key is provided to Automator:

```
automator setup "My Automator"
```

Initialize the Automator with the new configuration

```
automator init "My Automator"
```

Enable the service

```
automator enable "My Automator"
```

At this point, the configuration is complete.

For external health checks, you can use the below URL:

https\://\<server>/health

Example `curl` command:

```
$ curl https://craigautomator1.xyz.azurecontainerapps.io/health
OK
```

### Testing the User Experience

Now that Keeper Automator is deployed, you can test the end-user experience. No prompts for approval will be required after the user authenticates with the SSO identity provider.

The easiest way to test is to open an incognito mode window to the Keeper Web Vault and login with SSO Cloud. You will not be prompted for device approval.

### Advanced

Azure Container Apps have many advanced capabilities that are beyond the scope of this documentation. A few of the capabilities are provided below.

#### Scaling with Multiple Containers

If you would like to have multiple containers running the Keeper Automator service:

* Click on "**Scale and replicas**"
* Click "**Edit and deploy**"
* Click on the "**Scale**" tab
* Select the min and max number of containers. The minimum should be at least 1.
* Click **Create**
* After a minute, the new version will deploy
* Run `automator setup xxx` multiple times (one for each container)
* Run `automator init xxx` multiple times (one for each container)

#### Logging

The Keeper Automator logs can be viewed and monitored using the "Console" or "Log stream" section.

For example, to tail the log file of a running Automator service:

* Click on Console
* Select "/bin/sh"
* Click Connect
* At the prompt, type: `tail -f logs/keeper-automator.log`

#### Advanced Settings

Environment variables can be passed into the Container to turn on/off features of the runtime environment. The variables with their description can be found at the [Advanced Settings](/sso-connect-cloud/device-approvals/automator/advanced-settings.md) page.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.keeper.io/sso-connect-cloud/device-approvals/automator/azure-container-app.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
