> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elementum.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Apps between Environments

> Deploy apps from one organization environment to another, configure post-deployment data connections, and review deployment history

<Warning>
  **Labs feature.** Deployments depend on Environments, which is marked with the **Labs** badge in the Elementum UI because the feature is still being validated. Behavior, scope, and availability may change before the feature reaches General Availability, and not all Elementum customers have access yet. See [Upcoming Features](/release-notes/upcoming-features#labs-tag-in-the-platform) for what the Labs tag means.
</Warning>

**Deployment** copies an app and its configuration from a source environment to a target environment. Before deploying, make sure both environments exist and have CloudLink configured. See [Understand and Configure Environments](/administration/understand-organization-environments) for the prerequisites.

<Callout icon="shield-halved" color="#8B5CF6" iconType="solid">
  **Required Permission:** You must hold the **DEPLOY\_APPS** permission for the target environment to deploy an app to it. See [Who can deploy](#who-can-deploy) below.
</Callout>

## How deployment works

You can deploy in any direction: from a non-production environment to Production, from Production into another environment to test changes, or between non-production environments.

**What is included in a deployment**

Automations; record layouts, related views, and form builder configuration; Flow definitions; approval processes; assignment rules; and report and analytics configuration for that app.

**What is not included in a deployment**

Role membership — which users and groups are assigned to a role — is **not** part of deployment. Elementum never modifies role membership during any deployment — initial or subsequent. When you deploy an app, element, or task into an environment for the first time, role membership from the source does not carry over. The owner of the deployed object is responsible for configuring role membership in the target environment after the first deploy, directly on the object's **Roles & Permissions** page in that environment. No future redeployment of that object will ever overwrite membership settings that have been configured in the target environment.

<Note>
  Deployment is different from environment creation. When an environment is first created, roles and role membership are cloned from Production into the new environment as its starting state. After that, deploying an app, element, or task into the environment does not carry membership with it — see [Environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership).
</Note>

<Info>
  Deployment controls **what** an app does (configuration, automations, flows). **Who** can access it in each environment is always managed separately through [environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership).
</Info>

<Warning>
  Role membership is **not** part of the post-deployment **Configure** prompt. That prompt only handles Snowflake field mapping for Tables and Elements (see [Post-deployment configuration](#post-deployment-configuration)). Configure role membership separately on each object's **Roles & Permissions** page in the target environment.
</Warning>

The deployment is tracked with status and history on the app's **Deployments** page.

## Who can deploy

Promotion to each environment is gated by the **DEPLOY\_APPS** permission for **that environment**. Edit or admin rights on an app no longer imply the right to deploy it; users must hold DEPLOY\_APPS in the target environment to push an app there.

| Behavior                           | What it means                                                                                                                                                                                                                                                             |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Per-environment**                | DEPLOY\_APPS is granted independently in each environment. A user with DEPLOY\_APPS in Staging cannot promote to Production unless they also hold it in Production.                                                                                                       |
| **Decoupled from app edit rights** | Granting someone the ability to update an app's configuration does not give them the ability to promote that app. Configure who can build apps and who can release them as separate decisions.                                                                            |
| **Granted through roles**          | Admins assign DEPLOY\_APPS through a role (managed or custom) in the target environment. Role membership is environment-specific — see [Environment-specific role membership](/administration/understand-organization-environments#environment-specific-role-membership). |

<Info>
  A user typically needs DEPLOY\_APPS in every environment they release to. For a `Dev → Stage → Prod` pipeline, the same release engineer commonly holds DEPLOY\_APPS in both Stage and Prod, while developers hold it only in Dev.
</Info>

### Initial vs. subsequent deployments

The first time you deploy an app to a target environment, settings are copied from the source. On later deployments to the same target, most configuration is updated to match the source, but the following **destination** values are left as you set them in that environment:

| Configuration            | Initial deployment                                                             | Later deployments                                                      |
| ------------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| **AI Search target lag** | Copied from source                                                             | Target environment's value is kept                                     |
| **Access policies**      | Copied from source — only when the object does not already exist in the target | Target environment's policies are kept; deployment does not touch them |
| **Role membership**      | Not copied — must be configured manually                                       | Never overwritten by Elementum                                         |

<Info>
  After the first deployment, you can set AI Search target lag and access policies per environment; later deployments will not overwrite those choices. Role membership is never part of any deployment and must always be set up independently in each environment.
</Info>

### Access policy changes outside of a deployment

Changes you make to a Data Access policy (outside of a deployment) are scoped to the environment you are signed in to. They do **not** propagate to other environments.

* Removing a group's access to an app in one environment does not remove that group's access in any other environment.
* To remove or change access across all environments, repeat the change in each environment separately.

This is the same model used for role membership: the [environment indicator](/administration/understand-organization-environments#environment-categories) always shows which environment your change will apply to.

## Deploy an app

<Steps>
  <Step title="Navigate to the App">
    Open the <img src="https://mintcdn.com/elementum/qCzryjcKPIeW4b77/images/icons/apps.png?fit=max&auto=format&n=qCzryjcKPIeW4b77&q=85&s=c9636b6549744cccd29646e3723a299f" alt="Apps icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/apps.png" /> **app** you want to deploy in its **source environment** (the environment where the app currently exists).

    For example, to deploy an app from Development to Production, open the app in the Development environment.
  </Step>

  <Step title="Open Deployments">
    In the app's left navigation, under the **Configuration** section, click **Deployments**.

    The Deployments page shows all available environments with their deployment status.
  </Step>

  <Step title="View Environment Status">
    Each environment is displayed as a card showing:

    * **Environment name** and description
    * **Status indicator**: Deployed (green), Deploying (yellow), Failed (red), or Not Deployed (gray)
    * **Deploy button** to initiate deployment

    The right panel shows **Deployment History**. For what each record includes, see [Deployment history](#deployment-history) below.
  </Step>

  <Step title="Initiate Deployment">
    Find the target environment (where you want to deploy the app) and click the **Deploy** button on its card.

    A confirmation modal appears:

    * Title: "Deploy App To Environment"
    * Message: "Deployment will copy all app configurations and associated objects to the target environment."
    * Visual showing the deployment flow from source to target
    * Summary: "Deploy App from \[Source] to \[Target]"
  </Step>

  <Step title="Confirm and Deploy">
    Review the deployment details and click **Deploy** to proceed.

    The deployment process begins:

    * Status changes to "Deploying" (yellow)
    * Progress bar shows deployment progress
    * Upon completion, status changes to "Deployed" (green)

    <Info>
      Initial vs. subsequent deployments behave differently for some settings (for example AI Search target lag and Access Policies). See [Initial vs. subsequent deployments](#initial-vs-subsequent-deployments).
    </Info>
  </Step>

  <Step title="Monitor Deployment">
    Track deployment progress:

    | Status           | Description                                   |
    | ---------------- | --------------------------------------------- |
    | **Deploying**    | Deployment is in progress                     |
    | **Deployed**     | Deployment completed successfully             |
    | **Failed**       | Deployment encountered an error               |
    | **Not Deployed** | App has not been deployed to this environment |

    View the **Deployment History** panel for the full deployment log, including outcome and any error details for failed deployments.
  </Step>
</Steps>

## Post-deployment configuration

Apps whose <img src="https://mintcdn.com/elementum/qCzryjcKPIeW4b77/images/icons/tables.png?fit=max&auto=format&n=qCzryjcKPIeW4b77&q=85&s=30d253ecbf5bf015a9fa5def7cb769bc" alt="Tables icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/tables.png" /> **Tables** or <img src="https://mintcdn.com/elementum/qCzryjcKPIeW4b77/images/icons/elements.png?fit=max&auto=format&n=qCzryjcKPIeW4b77&q=85&s=1f6ffd07425e91ffc9c17b5885e300dd" alt="Elements icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/elements.png" /> **Elements** use Snowflake need extra steps in the **target** environment after deployment: pick database, schema, and table in that environment's CloudLink, and map fields. Apps with no Snowflake dependencies are ready once deployment finishes.

### Apps without external dependencies

For apps that don't connect to Snowflake data:

* Deployment completes immediately
* Environment card shows green "Deployed" status
* No additional configuration required
* App is ready to use in the target environment

### Apps with Snowflake dependencies

For apps with <img src="https://mintcdn.com/elementum/qCzryjcKPIeW4b77/images/icons/tables.png?fit=max&auto=format&n=qCzryjcKPIeW4b77&q=85&s=30d253ecbf5bf015a9fa5def7cb769bc" alt="Tables icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/tables.png" /> **Tables** or <img src="https://mintcdn.com/elementum/qCzryjcKPIeW4b77/images/icons/elements.png?fit=max&auto=format&n=qCzryjcKPIeW4b77&q=85&s=1f6ffd07425e91ffc9c17b5885e300dd" alt="Elements icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/elements.png" /> **Elements** linked to Snowflake, configure the data connections in the new environment.

<Steps>
  <Step title="Open configuration">
    After deployment completes, the **Deploy** button changes to **Configure**.

    The card shows:

    * Green "Deployed" status pill
    * "Complete" progress indicator
    * **Configure** button

    Click **Configure** to open the target environment.
  </Step>

  <Step title="Review Items Needing Configuration">
    The **Resolve Issues** modal appears with the message: "Review and resolve configuration issues before proceeding with deployment."

    The left panel lists all **Datasets** (Tables and Elements) that need configuration, each showing:

    * Dataset name
    * Configuration status ("Not configured")
    * Error count indicating fields needing mapping
  </Step>

  <Step title="Select a Dataset">
    Click on a Dataset in the left panel to configure it.

    The right panel shows:

    * Dataset name and error count
    * "Configure data source connection and field mappings"
    * Valid fields count and errors count
  </Step>

  <Step title="Configure Data Connection">
    The CloudLink is pre-selected. Configure the data source:

    1. **Database** - Select the database from the dropdown
    2. **Schema** - Select the schema containing your data
    3. **Table** - Select the table that corresponds to this dataset
  </Step>

  <Step title="Map Fields">
    After selecting the table, map each field:

    | Target Field                | Action                                                                     |
    | --------------------------- | -------------------------------------------------------------------------- |
    | Field from the deployed app | Select the corresponding **Source Field** from the new environment's table |

    For each Target Field listed:

    * Use the dropdown to select the matching Source Field
    * Ensure data types align (TEXT to TEXT, NUMBER to NUMBER, etc.)
    * Repeat for all fields in the dataset
  </Step>

  <Step title="Save Configuration">
    After mapping all fields for all datasets:

    1. Click **Configure Dataset** to save the configurations
    2. Configured items are removed from the list
    3. Continue until all items are configured
    4. When the list is empty, the modal closes

    The app is now fully configured and ready to use in the target environment.
  </Step>
</Steps>

## Deployment history

Each app keeps a log of deployments: who ran them, source and target environment, time, outcome (**Success** or **Failure**), and error details on failed runs. Error details stay on the record even after related background work is removed.

Any user who can open the app can open **Deployments** and read this history. It is paginated and includes the full history, not only recent entries.

| Field                  | Description                           |
| ---------------------- | ------------------------------------- |
| **Source environment** | Where the app was deployed from       |
| **Target environment** | Where it was deployed to              |
| **Initiated by**       | User who started the deployment       |
| **Timestamp**          | When the deployment started           |
| **Outcome**            | **Success** or **Failure**            |
| **Error details**      | On failures, shown on the same record |

## Example workflows

<AccordionGroup>
  <Accordion title="Develop, then release">
    1. Add a Development environment from Production.
    2. Deploy an app into Development and change it there.
    3. When satisfied, deploy from Development to Production.
  </Accordion>

  <Accordion title="Staging before production">
    1. Add Staging (and optionally Development).
    2. Move apps Development → Staging for review, then Staging → Production when approved.
  </Accordion>

  <Accordion title="Training">
    1. Add a Training environment and deploy the apps users will see in Production so they can practice without touching live data.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Deployment Fails Immediately">
    **Possible Causes:**

    * CloudLink not configured in target environment
    * CloudLink credentials invalid or expired
    * Network connectivity issues

    **Solutions:**

    1. Verify CloudLink is configured in the target environment
    2. Test CloudLink connection in <img src="https://mintcdn.com/elementum/TFCVHNVI8zhq54sg/images/icons/settings.svg?fit=max&auto=format&n=TFCVHNVI8zhq54sg&q=85&s=3ffc43e8a0875412cc27335241aeb4c8" alt="Settings icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/settings.svg" /> **Organization Settings**
    3. Check Snowflake service account permissions
  </Accordion>

  <Accordion title="Cannot See Target Environment">
    **Possible Causes:**

    * Environment not yet created
    * Insufficient permissions to view environments

    **Solutions:**

    1. Verify the environment exists in <img src="https://mintcdn.com/elementum/TFCVHNVI8zhq54sg/images/icons/settings.svg?fit=max&auto=format&n=TFCVHNVI8zhq54sg&q=85&s=3ffc43e8a0875412cc27335241aeb4c8" alt="Settings icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/settings.svg" /> Organization Settings > Environments
    2. Contact your administrator to check access permissions
  </Accordion>

  <Accordion title="Field Mapping Errors">
    **Possible Causes:**

    * Table structure differs between environments
    * Missing columns in target environment's table
    * Data type mismatches

    **Solutions:**

    1. Verify the target table exists and has the expected columns
    2. Check that column names match or can be mapped correctly
    3. Ensure data types are compatible between source and target
  </Accordion>

  <Accordion title="Configure Button Not Appearing">
    **Possible Causes:**

    * Deployment still in progress
    * App has no external dependencies (no configuration needed)

    **Solutions:**

    1. Wait for deployment to complete (status shows "Deployed")
    2. If no Configure button appears after deployment, the app has no Snowflake dependencies and is ready to use
  </Accordion>

  <Accordion title="Using the Same Snowflake User Across Environments in Different Organizations">
    **Scenario:**
    You need to use the same Snowflake user account with key-pair authentication for CloudLinks in environments that belong to **different organizations**.

    **Solution:**
    Snowflake supports key-pair rotation, which allows you to configure a second public key for the same user account. This enables environments in both organizations to authenticate simultaneously without disrupting existing connections.

    <Info>
      **Important:** Key-pair rotation is only required when using the same Snowflake user across environments in **different organizations**. If you are using the same Snowflake user across multiple environments within the **same organization**, key-pair rotation is not necessary because they share the same public key.
    </Info>

    **Steps:**

    1. **Obtain the Public Key from the Organization You Are Adding the CloudLink To:**
       * Navigate to <img src="https://mintcdn.com/elementum/TFCVHNVI8zhq54sg/images/icons/settings.svg?fit=max&auto=format&n=TFCVHNVI8zhq54sg&q=85&s=3ffc43e8a0875412cc27335241aeb4c8" alt="Settings icon" className="inline-ui-icon" width="24" height="24" data-path="images/icons/settings.svg" /> **Organization Settings** > **CloudLinks** in the organization where you want to add the CloudLink
       * Start creating a new Snowflake CloudLink
       * Select **Key-pair authentication** as the authentication method
       * Copy the public key displayed

    2. **Configure Key-Pair Rotation in Snowflake:**
       * Contact your Snowflake administrator to set the `RSA_PUBLIC_KEY_2` property for the Snowflake user
       * Provide the public key copied from the organization where you're adding the CloudLink
       * The Snowflake admin should run:
         ```sql theme={null}
         ALTER USER <username> SET RSA_PUBLIC_KEY_2='<public_key>';
         ```

    3. **Complete CloudLink Setup:**
       * After the second public key is configured in Snowflake, complete the CloudLink setup in the organization
       * Both organizations will now be able to authenticate with the same Snowflake user
       * The existing CloudLink in the other organization continues to work without interruption

    For detailed information on configuring key-pair rotation in Snowflake, see [Snowflake's key-pair authentication documentation](https://docs.snowflake.com/en/user-guide/key-pair-auth#configuring-key-pair-rotation).
  </Accordion>
</AccordionGroup>

## Deployment practices

* **Validate before Production** — Deploy and test changes in non-production environments before deploying to Production.
* **Deploy one app at a time** when practical so failures are easier to trace.
* **Use deployment history** to confirm what ran, when, and by whom.
* **Restrict who can deploy to Production** — Grant **DEPLOY\_APPS** in Production only to release-managers; review that role membership periodically. Because role membership is environment-specific, removing DEPLOY\_APPS in Production does not affect a user's ability to deploy in Development or Staging.

## Next steps

<CardGroup cols={2}>
  <Card title="Understand and Configure Environments" icon="sitemap" href="/administration/understand-organization-environments">
    Environment concepts, categories, CloudLink requirements, and setup steps
  </Card>

  <Card title="CloudLink Overview" icon="cloud" href="/administration/cloudlink-overview">
    Detailed CloudLink configuration options
  </Card>

  <Card title="Snowflake Connection" icon="snowflake" href="/administration/connect-snowflake-to-elementum">
    Complete Snowflake setup guide with scripts
  </Card>

  <Card title="Apps Overview" icon="grid-2" href="/getting-started/fundamentals/core-concepts#processes--apps">
    Understanding apps and their components
  </Card>
</CardGroup>
