

# Deploy AWS IoT Greengrass components to devices
<a name="manage-deployments"></a>

You can use AWS IoT Greengrass to deploy components to devices or groups of devices. You use *deployments* to define the components and configurations that are sent to the devices. AWS IoT Greengrass deploys to *targets*, AWS IoT things or thing groups that represent Greengrass core devices. AWS IoT Greengrass uses [AWS IoT Core jobs](https://docs.aws.amazon.com/iot/latest/developerguide/iot-jobs.html) to deploy to your core devices. You can configure how the job rolls out to your devices.

## Core device deployments
<a name="core-device-deployments"></a>

Each core device runs the components of the deployments for that device. A new deployment to the same target overwrites the previous deployment to the target. When you create a deployment, you define the components and configurations to apply to the core device's existing software.

When you revise a deployment for a target, you replace the components from the previous revision with the components in the new revision. For example, you deploy the [Log manager](log-manager-component.md) and [Secret manager](secret-manager-component.md) components to the thing group `TestGroup`. Then you create another deployment for `TestGroup` that specifies only the secret manager component. As a result, the core devices in that group no longer run the log manager.

## Platform dependency resolution
<a name="platform-dependency-resolution"></a>

When a core device receives a deployment, it checks to make sure that the components are compatible with the core device. For example, if you deploy the [Firehose](kinesis-firehose-component.md) to a Windows target, the deployment will fail.

## Component dependency resolution
<a name="component-dependency-resolution"></a>

During a component deployment, the core device verifies compatibility of all components' dependencies and version requirements across a thing group. This verification ensures that version contraints are satisfied for all components and their dependencies before proceeding with the deployment.

The dependency resolution process begins with identifying target components that have no dependencies in their recipes. Then, the system constructs a dependency tree using breadth-first search (BFS) which systematically explores each target node and finds their dependencies first before moving on to the next node. Each node includes the target component as the key and the version requirements as the value.

The version requirements combine three sets of constraints:
+ The version requirements that are already established in the existing thing group.
+ The component version required by the deployment. You must select a component version when you make or update a deployment.
+ Any component version constraints that are defined within the recipe's dependency section.

### Resolve component dependencies
<a name="resolving-dependencies"></a>

During a deployment, the Greengrass nucleus first attempts to find the local candidate currently running on the device that satisfies the requirements. If the running component satisfies the requirements, the nucleus gets the stored recipe path from the recipe folder and finds the latest local version in the local store.

For AWS Cloud deployments, the nucleus will then call the [ResolveComponentCandidates API](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_ResolveComponentCandidates.html). This API will start with the latest available version and check if it satisfies the dependencies and requirements. When the nucleus gets the response from the API, it selects that latest version. If there is no version found from the AWS Cloud that satisfies the requirements, the deployment fails. If the device is offline, it falls back to the original local candidate found. If there is no local candidate found that satisfies the requirements, the deployment fails.

For local deployments, the nucleus exclusively uses local candidates if they exist and if they satisfy the requirements without negotiating to AWS Cloud. If there is no such candidate, the deployment fails.

**Note**  
All resolved recipes are stored locally for future reference.

For more information, see the [dependency resolution](https://github.com/aws-greengrass/aws-greengrass-nucleus/wiki/Deployment#dependency-resolution) section in GitHub.

If the Greengrass nucleus is able to successfully resolve all components, the nucleus log will contain the following line.

```
resolve-all-group-dependencies-finish. Finish resolving all groups dependencies.
```

**Example**  
The following is an example of how the nucleus will resolve the component requirements.  
+ You deploy ComponentA which depends on ComponentC versions 1.0.0-1.9.0.
+ You also deploy ComponentB which depends on ComponentC versions 1.4.0-1.9.5.
With component dependency resolution, the nucleus will deploy the latest version of ComponentC version to satisfy the requirements of ComponentA and ComponentB. This latest version of ComponentC is version 1.9.0.

#### Common component dependency resolution failures
<a name="w2ab1c24c25b9c11c19"></a>

The component dependency resolution may fail for two main reasons: target version requirement conflict or component dependency requirement conflict.

##### Scenario 1: Target version requirement conflict
<a name="w2ab1c24c25b9c11c19b5"></a>
+ A thing exists in one thing group and you also want to add that thing to a new thing group. The deployment will fail if the new thing group requires a different thing version.
+ A deployment may also fail if a thing belongs to a thing group and wants to update the component version through a thing deployment.

![\[Component dependencies that result in a failed deployment.\]](http://docs.aws.amazon.com/greengrass/v2/developerguide/images/dependency-4.png)


*Failure log sample:*

```
2025-04-11T06:16:03.315Z [ERROR] (pool-3-thread-27) com.aws.greengrass.componentmanager.ComponentManager: Failed to negotiate version with cloud and no local version to fall back to. {componentName=ComponentC, versionRequirement={thing/ABC==2.0.0, thinggroup/ThingGroupA==1.0.0}}
2025-04-11T06:16:03.316Z [ERROR] (pool-3-thread-26) com.aws.greengrass.deployment.DeploymentService: Error occurred while processing deployment. {deploymentId=fbac24de-4ef9-44b0-a685-fdc63b0f02b8, serviceName=DeploymentService, currentState=RUNNING}
java.util.concurrent.ExecutionException: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentC version constraints: thing/ABC requires =2.0.0, thinggroup/ThingGroupA requires =1.0.0.
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:127)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:50)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentC version constraints: thing/ABC requires =2.0.0, thinggroup/ThingGroupA requires =1.0.0.
    at com.aws.greengrass.componentmanager.ComponentManager.negotiateVersionWithCloud(ComponentManager.java:232)
    at com.aws.greengrass.componentmanager.ComponentManager.resolveComponentVersion(ComponentManager.java:167)
    at com.aws.greengrass.componentmanager.DependencyResolver.lambda$resolveDependencies$0(DependencyResolver.java:134)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveComponentDependencies(DependencyResolver.java:231)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveDependencies(DependencyResolver.java:131)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.lambda$call$2(DefaultDeploymentTask.java:125)
    ... 4 more
```

The logs indicate a version conflict error because the nucleus can't find a component version that simultaneously meetings two conflicting requirements.

##### How to resolve it
<a name="w2ab1c24c25b9c11c19b5c13"></a>
+ If you want to keep the component in each thing group, select the same version of that component in each thing group.
+ Select a component version that meets the deployment requirement.
+ If you want to use a component version that doesn't meet both thing group requirements, select the component version that meets the thing group version requirement and use that component only in that thing group.

##### Scenario 2: Component dependency version requirement conflict
<a name="w2ab1c24c25b9c11c19b7"></a>

If a component is a dependency of different components and the components require different versions or different version ranges of that component, there a possibility that there are no available versions to satisfy all version requirements. In this scenario, the deployment will fail.

**Example**  
Deployment of ComponentA (v2.5.0), ComponentB (v1.3.0), and ComponentC (v1.0.0)  
+ ComponentA requires ComponentB version >=1.0.0.

  ```
  ---
  ...
  ComponentName: ComponentA
  ComponentVersion: "2.5.0"
  ComponentDependencies:
      ComponentB:
          VersionRequirement: ">=1.0.0"
          DependencyType: "HARD"
  ...
  ```
+ ComponentC requires ComponentA version <2.0.0.

  ```
  ---
  ...
  ComponentName: ComponentC
  ComponentVersion: "1.0.0"
  ComponentDependencies:
      ComponentA:
          VersionRequirement: "<2.0.0"
          DependencyType: "HARD"
  ...
  ```
There's a version conflict between two requirements for ComponentA:  
+ ComponentA requires version 2.5.0 in this deployment
+ ComponentC requires ComponentA versions lower than 2.0.0
These two requirements contradict each other, making it impossible for the nucleus to find a ComponentA version that satisfies both requirements. Therefore, the dependency resolution fails.

![\[Component dependencies that result in a failed deployment.\]](http://docs.aws.amazon.com/greengrass/v2/developerguide/images/dependency-3.png)


*Failure log sample:*

```
2025-04-11T06:07:18.291Z [ERROR] (pool-3-thread-25) com.aws.greengrass.componentmanager.ComponentManager: Failed to negotiate version with cloud and no local version to fall back to. {componentName=ComponentA, versionRequirement={ComponentC=<2.0.0, thinggroup/ThingGroupA==2.5.0}}
2025-04-11T06:07:18.292Z [ERROR] (pool-3-thread-24) com.aws.greengrass.deployment.DeploymentService: Error occurred while processing deployment. {deploymentId=2ffac4df-1ac9-405c-8c11-28494a1b4382, serviceName=DeploymentService, currentState=RUNNING}
java.util.concurrent.ExecutionException: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentA version constraints: ComponentC requires <2.0.0, thinggroup/ThingGroupA requires =2.5.0.
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:127)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.call(DefaultDeploymentTask.java:50)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.aws.greengrass.componentmanager.exceptions.NoAvailableComponentVersionException: No local or cloud component version satisfies the requirements Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component ComponentA version constraints: ComponentC requires <2.0.0, thinggroup/ThingGroupA requires =2.5.0.
    at com.aws.greengrass.componentmanager.ComponentManager.negotiateVersionWithCloud(ComponentManager.java:232)
    at com.aws.greengrass.componentmanager.ComponentManager.resolveComponentVersion(ComponentManager.java:167)
    at com.aws.greengrass.componentmanager.DependencyResolver.lambda$resolveDependencies$0(DependencyResolver.java:134)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveComponentDependencies(DependencyResolver.java:231)
    at com.aws.greengrass.componentmanager.DependencyResolver.resolveDependencies(DependencyResolver.java:131)
    at com.aws.greengrass.deployment.DefaultDeploymentTask.lambda$call$2(DefaultDeploymentTask.java:125)
    ... 4 more
```

The logs indicate that the nucleus can't find a version of ComponentA that satisfies the following requirements.
+ The requirements for ComponentA to be exactly version 2.5.0 (from ThingGroupA).
+ The requirement to work with ComponentC versions below 2.0.0.

##### How to resolve it
<a name="w2ab1c24c25b9c11c19b7c17"></a>
+ If you want to keep the component in each thing group, select the same version of that component in each thing group.
+ Select a component version that meets the deployment requirement.
+ If you want to use a component version that doesn't meet both thing group requirements, select the component version that meets the thing group version requirement and use that component only in that thing group.

**Tip**  
If you see this error on any AWS provided component, you can resolve it by updating the conflicted components to the latest version.

## Removing a device from a thing group
<a name="thing-group-removal-behavior"></a>

When you remove a core device from a thing group, the component deployment behavior depends on the version of the [Greengrass nucleus](greengrass-nucleus-component.md) that the core device runs.

------
#### [ 2.5.1 and later ]

When you remove a core device from a thing group, the behavior depends on whether the AWS IoT policy grants the `greengrass:ListThingGroupsForCoreDevice` permission. For more information about this permission and AWS IoT policies for core devices, see [Device authentication and authorization for AWS IoT Greengrass](device-auth.md).
+ **If the AWS IoT policy grants this permission**

  <a name="thing-group-removal-behavior-remove-components"></a>When you remove a core device from a thing group, AWS IoT Greengrass removes the thing group's components the next time a deployment is made to the device. If a component on the device is included in the next deployment, that component is not removed from the device.
+ **If the AWS IoT policy doesn't grant this permission**

  <a name="thing-group-removal-behavior-no-remove-components"></a>When you remove a core device from a thing group, AWS IoT Greengrass doesn't delete that thing group's components from the device.

  <a name="thing-group-removal-behavior-no-remove-components-how-to-remove"></a>To remove a component from a device, use the [deployment create](gg-cli-deployment.md#deployment-create) command of the Greengrass CLI. Specify the component to remove with the `--remove` argument, and specify the thing group with the `--groupId` argument.

------
#### [ 2.5.0 ]

<a name="thing-group-removal-behavior-remove-components"></a>When you remove a core device from a thing group, AWS IoT Greengrass removes the thing group's components the next time a deployment is made to the device. If a component on the device is included in the next deployment, that component is not removed from the device.

This behavior requires that the core device's AWS IoT policy grants the `greengrass:ListThingGroupsForCoreDevice` permission. If a core device doesn't have this permission, the core device fails to apply deployments. For more information, see [Device authentication and authorization for AWS IoT Greengrass](device-auth.md).

------
#### [ 2.0.x - 2.4.x ]

<a name="thing-group-removal-behavior-no-remove-components"></a>When you remove a core device from a thing group, AWS IoT Greengrass doesn't delete that thing group's components from the device.

<a name="thing-group-removal-behavior-no-remove-components-how-to-remove"></a>To remove a component from a device, use the [deployment create](gg-cli-deployment.md#deployment-create) command of the Greengrass CLI. Specify the component to remove with the `--remove` argument, and specify the thing group with the `--groupId` argument.

------

## Deployments
<a name="deployments"></a>

Deployments are continuous. When you create a deployment, AWS IoT Greengrass rolls out the deployment to target devices that are online. If a target device isn't online, then it receives the deployment the next time it connects to AWS IoT Greengrass. When you add a core device to a target thing group, AWS IoT Greengrass sends the device the latest deployment for that thing group.

Before a core device deploys a component, by default it notifies each component on the device. Greengrass components can respond to the notification to defer deployment. You might want to defer deployment if the device has a low battery level or is running a process that can't be interrupted. For more information, see [Tutorial: Develop a Greengrass component that defers component updates](defer-component-updates-tutorial.md). When you create a deployment you can configure it to deploy without notifying components.

Each target thing or thing group can have one deployment at a time. This means that when you create a deployment for a target, AWS IoT Greengrass no longer deploys the previous revision of that target's deployment.

## Deployment options
<a name="deployment-options"></a>

Deployments provide several options that let you control which devices receive an update and how the update deploys. When you create a deployment, you can configure the following options:
+ **AWS IoT Greengrass components**

  Define the components to install and run on the target devices. AWS IoT Greengrass components are software modules that you deploy and run on Greengrass core devices. Devices receive components only if the component supports the device's platform. This lets you deploy to groups of devices even if the target devices run on multiple platforms. If a component doesn't support the device's platform, the component doesn't deploy to the device.

  You can deploy custom components and AWS-provided components to your devices. When you deploy a component, AWS IoT Greengrass identifies any component dependencies and deploys them too. For more information, see [Develop AWS IoT Greengrass components](develop-greengrass-components.md) and [AWS-provided components](public-components.md).

  You define the version and configuration update to deploy for each component. The *configuration update* specifies how to modify the component's existing configuration on the core device, or the component's default configuration if the component doesn't exist on the core device. You can specify which configuration values to reset to default values and the new configuration values to merge onto the core device. When a core device receives deployments for different targets, and each deployment specifies compatible component versions, the core device applies configuration updates in order based on the timestamp of when you create the deployment. For more information, see [Update component configurations](update-component-configurations.md).
**Important**  <a name="component-patch-update-note"></a>
<a name="component-patch-update"></a>When you deploy a component, AWS IoT Greengrass installs the latest supported versions of all of that component's dependencies. Because of this, new patch versions of AWS-provided public components might be automatically deployed to your core devices if you add new devices to a thing group, or you update the deployment that targets those devices. Some automatic updates, such as a nucleus update, can cause your devices to restart unexpectedly.   
<a name="component-version-pinning"></a>To prevent unintended updates for a component that is running on your device, we recommend that you directly include your preferred version of that component when you [create a deployment](create-deployments.md). For more information about update behavior for AWS IoT Greengrass Core software, see [Update the AWS IoT Greengrass Core software (OTA)](update-greengrass-core-v2.md).
+ **Deployment policies**

  Define when it's safe to deploy a configuration and what to do if the deployment fails. You can specify whether or not to wait for components to report that they can update. You can also specify whether or not to roll back devices to their previous configuration if they apply a deployment that fails.
+ **Stop configuration**

  Define when and how to stop a deployment. The deployment stops and fails if the criteria that you define are met. For example, you can configure a deployment to stop if a percentage of devices fail to apply that deployment after a minimum number of devices receive it.
+ **Rollout configuration**

  Define the rate at which a deployments rolls out to the target devices. You can configure an exponential rate increase with minimum and maximum rate bounds.
+ **Timeout configuration**

  Define the maximum amount of time each device has to apply a deployment. If a device exceeds the duration that you specify, then the device fails to apply the deployment.

**Important**  
Custom components can define artifacts in S3 buckets. When the AWS IoT Greengrass Core software deploys a component, it downloads the component's artifacts from the AWS Cloud. Core device roles don't allow access to S3 buckets by default. To deploy custom components that define artifacts in an S3 bucket, the core device role must grant permissions to download artifacts from that bucket. For more information, see [Allow access to S3 buckets for component artifacts](device-service-role.md#device-service-role-access-s3-bucket).

**Topics**
+ [Core device deployments](#core-device-deployments)
+ [Platform dependency resolution](#platform-dependency-resolution)
+ [Component dependency resolution](#component-dependency-resolution)
+ [Removing a device from a thing group](#thing-group-removal-behavior)
+ [Deployments](#deployments)
+ [Deployment options](#deployment-options)
+ [Create deployments](create-deployments.md)
+ [Create subdeployments](create-subdeployments.md)
+ [Revise deployments](revise-deployments.md)
+ [Cancel deployments](cancel-deployments.md)
+ [Check deployment status](check-deployment-status.md)

# Create deployments
<a name="create-deployments"></a>

You can create a deployment that targets a thing or thing group.

When you create a deployment, you configure the software components to deploy and how the deployment job rolls out to target devices. You can define the deployment in the JSON file that you provide to the AWS CLI.

The deployment target determines the devices on which you want to run your components. To deploy to one core device, specify a thing. To deploy to multiple core devices, specify a thing group that includes those devices. For more information about how to configure thing groups, see [Static thing groups](https://docs.aws.amazon.com/iot/latest/developerguide/thing-groups.html) and [Dynamic thing groups](https://docs.aws.amazon.com/iot/latest/developerguide/dynamic-thing-groups.html) in the *AWS IoT Developer Guide*.

Follow the steps in this section to create a deployment to a target. For more information about how to update the software components on a target that has a deployment, see [Revise deployments](revise-deployments.md).

**Warning**  
The [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html) operation can uninstall components from core devices. If a component is present in the previous deployment and not the new deployment, the core device uninstalls that component. To avoid uninstalling components, first use the [ListDeployments](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_ListDeployments.html) operation to check if the target for the deployment already has an existing deployment. Then, use the [GetDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_GetDeployment.html) operation to start from that existing deployment when you create a new deployment.

**To create a deployment (AWS CLI)**

1. Create a file called `deployment.json`, and then copy the following JSON object into the file. Replace *targetArn* with the ARN of the AWS IoT thing or thing group to target for the deployment. Thing and thing group ARNs have the following format:
   + Thing: `arn:aws:iot:region:account-id:thing/thingName`
   + Thing group: `arn:aws:iot:region:account-id:thinggroup/thingGroupName`

   ```
   {
     "targetArn": "targetArn"
   }
   ```

1. Check if the deployment target has an existing deployment that you want to revise. Do the following:

   1. <a name="revise-deployment-list-deployments-intro"></a>Run the following command to list the deployments for the deployment target. Replace *targetArn* with the ARN of the target AWS IoT thing or thing group.

      ```
      aws greengrassv2 list-deployments --target-arn targetArn
      ```

      The response contains a list with the latest deployment for the target. If the response is empty, the target doesn't have an existing deployment, and you can skip to [Step 3](#create-deployment-define-name-step). Otherwise, copy the `deploymentId` from the response to use in the next step.
**Note**  <a name="revise-deployment-list-deployments-revision-note"></a>
You can also revise a deployment other than the latest revision for the target. Specify the `--history-filter ALL` argument to list all deployments for the target. Then, copy the ID of the deployment that you want to revise.

   1. <a name="revise-deployment-get-deployment"></a>Run the following command to get the deployment's details. These details include metadata, components, and job configuration. Replace *deploymentId* with the ID from the previous step.

      ```
      aws greengrassv2 get-deployment --deployment-id deploymentId
      ```

      The response contains the deployment's details.

   1. Copy any of the following key-value pairs from the previous command's response into `deployment.json`. You can change these values for the new deployment.
      + `deploymentName` – The deployment's name.
      + `components` – The deployment's components. To uninstall a component, remove it from this object.
      + `deploymentPolicies` – The deployment's policies.
      + `iotJobConfiguration` – The deployment's job configuration.
      + `tags` – The deployment's tags.

1. <a name="create-deployment-define-name-step"></a>(Optional) Define a name for the deployment. Replace *deploymentName* with the name of the deployment.

   ```
   {
     "targetArn": "targetArn",
     "deploymentName": "deploymentName"
   }
   ```

1. Add each component to deploy the target devices. To do so, add key-value pairs to the `components` object, where the key is the component name, and the value is an object that contains the details for that component. Specify the following details for each component that you add:
   + `version` – The component version to deploy.
   + `configurationUpdate` – The [configuration update](update-component-configurations.md) to deploy. The update is a patch operation that modifies the component's existing configuration on each target device, or the component's default configuration if it doesn't exist on the target device. You can specify the following configuration updates:
     + Reset updates (`reset`) – (Optional) A list of JSON pointers that define the configuration values to reset to their default values on the target device. The AWS IoT Greengrass Core software applies reset updates before it applies merge updates. For more information, see [Reset updates](update-component-configurations.md#reset-configuration-update).
     + Merge updates (`merge`) – (Optional) A JSON document that defines the configuration values to merge onto the target device. You must serialize the JSON document as a string. For more information, see [Merge updates](update-component-configurations.md#merge-configuration-update).
   + <a name="component-run-with-config"></a>`runWith` – (Optional) The system process options that the AWS IoT Greengrass Core software uses to run this component's processes on the core device. If you omit a parameter in the `runWith` object, the AWS IoT Greengrass Core software uses the default values that you configure on the [Greengrass nucleus component](greengrass-nucleus-component.md).

     You can specify any of the following options:
     + `posixUser` – The POSIX system user and, optionally, group to use to run this component on Linux core devices. The user, and group if specified, must exist on each Linux core device. Specify the user and group separated by a colon (`:`) in the following format: `user:group`. The group is optional. If you don't specify a group, the AWS IoT Greengrass Core software uses the primary group for the user. For more information, see [Configure the user that runs components](configure-greengrass-core-v2.md#configure-component-user).
     + `windowsUser` – The Windows user to use to run this component on Windows core devices. The user must exist on each Windows core device, and its name and password must be stored in the LocalSystem account's Credentials Manager instance. For more information, see [Configure the user that runs components](configure-greengrass-core-v2.md#configure-component-user).

       This feature is available for v2.5.0 and later of the [Greengrass nucleus component](greengrass-nucleus-component.md).
     + `systemResourceLimits` – The system resource limits to apply to this component's processes. You can apply system resource limits to generic and non-containerized Lambda components. For more information, see [Configure system resource limits for components](configure-greengrass-core-v2.md#configure-component-system-resource-limits).

       You can specify any of the following options:
       + `cpus` – <a name="system-resource-limits-cpu-definition-this"></a>The maximum amount of CPU time that this component's processes can use on the core device. A core device's total CPU time is equivalent to the device's number of CPU cores. For example, on a core device with 4 CPU cores, you can set this value to `2` to limit this component's processes to 50 percent usage of each CPU core. On a device with 1 CPU core, you can set this value to `0.25` to limit this component's processes to 25 percent usage of the CPU. If you set this value to a number greater than the number of CPU cores, the AWS IoT Greengrass Core software doesn't limit the component's CPU usage. 
       + `memory` – <a name="system-resource-limits-memory-definition-this"></a>The maximum amount of RAM (in kilobytes) that this component's processes can use on the core device. 

       This feature is available for v2.4.0 and later of the [Greengrass nucleus component](greengrass-nucleus-component.md). AWS IoT Greengrass doesn't currently support this feature on Windows core devices. 

      
**Example basic configuration update**  

   The following example `components` object specifies to deploy a component, `com.example.PythonRuntime`, that expects a configuration parameter named `pythonVersion`.

   ```
   {
     "targetArn": "targetArn",
     "deploymentName": "deploymentName",
     "components": {
       "com.example.PythonRuntime": {
         "componentVersion": "1.0.0",
         "configurationUpdate": {
           "merge": "{\"pythonVersion\":\"3.7\"}"
         }
       }
     }
   }
   ```  
**Example configuration update with reset and merge updates**  

   Consider an example industrial dashboard component, `com.example.IndustrialDashboard`, that has the following default configuration.

   ```
   {
     "name": null,
     "mode": "REQUEST",
     "network": {
       "useHttps": true,
       "port": {
         "http": 80,
         "https": 443
       },
     },
     "tags": []
   }
   ```

   The following configuration update specifies the following instructions:

   1. Reset the HTTPS setting to its default value (`true`).

   1. Reset the list of industrial tags to an empty list.

   1. Merge a list of industrial tags that identify temperature and pressure data streams for two boilers.

   ```
   {
     "reset": [
       "/network/useHttps",
       "/tags"
     ],
     "merge": {
       "tags": [
         "/boiler/1/temperature",
         "/boiler/1/pressure",
         "/boiler/2/temperature",
         "/boiler/2/pressure"
       ]
     }
   }
   ```

   The following example `components` object specifies to deploy this industrial dashboard component and configuration update.

   ```
   {
     "targetArn": "targetArn",
     "deploymentName": "deploymentName",
     "components": {
       "com.example.IndustrialDashboard": {
         "componentVersion": "1.0.0",
         "configurationUpdate": {
           "reset": [
             "/network/useHttps",
             "/tags"
           ],
           "merge": "{\"tags\":[\"/boiler/1/temperature\",\"/boiler/1/pressure\",\"/boiler/2/temperature\",\"/boiler/2/pressure\"]}"
         }
       }
     }
   }
   ```

1. (Optional) Define deployment policies for the deployment. You can configure when core devices can safely apply a deployment or what to do if a core device fails to apply the deployment. To do so, add a `deploymentPolicies` object to `deployment.json`, and then do any of the following:

   1. (Optional) Specify the component update policy (`componentUpdatePolicy`). This policy defines whether or not the deployment lets components defer an update until they are ready to update. For example, components may need to clean up resources or finish critical actions before they can restart to apply an update. This policy also defines the amount of time that components have to respond to an update notification.

      This policy is an object with the following parameters:
      + `action` – (Optional) Whether or not to notify components and wait for them to report when they're ready to update. Choose from the following options:
        + `NOTIFY_COMPONENTS` – The deployment notifies each component before it stops and updates that component. Components can use the [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates) IPC operation to receive these notifications.
        + `SKIP_NOTIFY_COMPONENTS` – The deployment doesn't notify components or wait for them to be safe to update.

        Defaults to `NOTIFY_COMPONENTS`.
      + `timeoutInSeconds` The amount of time in seconds that each component has to respond to an update notification with the [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate) IPC operation. If the component doesn't respond within this amount of time, then the deployment proceeds on the core device.

        Defaults to 60 seconds.

   1. (Optional) Specify the configuration validation policy (`configurationValidationPolicy`). This policy defines how long each component has to validate a configuration update from a deployment. Components can use the [SubscribeToValidateConfigurationUpdates](ipc-component-configuration.md#ipc-operation-subscribetovalidateconfigurationupdates) IPC operation to subscribe to notifications for their own configuration updates. Then, components can use the [SendConfigurationValidityReport](ipc-component-configuration.md#ipc-operation-sendconfigurationvalidityreport) IPC operation to tell the AWS IoT Greengrass Core software if the configuration update is valid. If the configuration update isn't valid, the deployment fails.

      This policy is an object with the following parameter:
      + `timeoutInSeconds` (Optional) The amount of time in seconds that each component has to validate a configuration update. If the component doesn't respond within this amount of time, then the deployment proceeds on the core device.

        Defaults to 30 seconds.

   1. (Optional) Specify the failure handling policy (`failureHandlingPolicy`). This policy is a string that defines whether or not to roll back devices if the deployment fails. Choose from the following options:
      + `ROLLBACK` – If the deployment fails on a core device, then the AWS IoT Greengrass Core software rolls back that core device to its previous configuration.
      + `DO_NOTHING` – If the deployment fails on a core device, then the AWS IoT Greengrass Core software keeps the new configuration. This can result in broken components if the new configuration isn't valid.

      Defaults to `ROLLBACK`.

   Your deployment in `deployment.json` may look similar to the following example:

   ```
   {
     "targetArn": "targetArn",
     "deploymentName": "deploymentName",
     "components": {
       "com.example.IndustrialDashboard": {
         "componentVersion": "1.0.0",
         "configurationUpdate": {
           "reset": [
             "/network/useHttps",
             "/tags"
           ],
           "merge": "{\"tags\":[\"/boiler/1/temperature\",\"/boiler/1/pressure\",\"/boiler/2/temperature\",\"/boiler/2/pressure\"]}"
         }
       }
     },
     "deploymentPolicies": {
       "componentUpdatePolicy": {
         "action": "NOTIFY_COMPONENTS",
         "timeoutInSeconds": 30
       },
       "configurationValidationPolicy": {
         "timeoutInSeconds": 60
       },
       "failureHandlingPolicy": "ROLLBACK"
     }
   }
   ```

1. (Optional) Define how the deployment stops, rolls out, or times out. AWS IoT Greengrass uses AWS IoT Core jobs to send deployments to core devices, so these options are identical to the configuration options for AWS IoT Core jobs. For more information, see [Job rollout and abort configuration](https://docs.aws.amazon.com/iot/latest/developerguide/job-rollout-abort.html) in the *AWS IoT Developer Guide*.

   To define the job options, add an `iotJobConfiguration` object to `deployment.json`. Then, define the options to configure.

   Your deployment in `deployment.json` may look similar to the following example:

   ```
   {
     "targetArn": "targetArn",
     "deploymentName": "deploymentName",
     "components": {
       "com.example.IndustrialDashboard": {
         "componentVersion": "1.0.0",
         "configurationUpdate": {
           "reset": [
             "/network/useHttps",
             "/tags"
           ],
           "merge": "{\"tags\":[\"/boiler/1/temperature\",\"/boiler/1/pressure\",\"/boiler/2/temperature\",\"/boiler/2/pressure\"]}"
         }
       }
     },
     "deploymentPolicies": {
       "componentUpdatePolicy": {
         "action": "NOTIFY_COMPONENTS",
         "timeoutInSeconds": 30
       },
       "configurationValidationPolicy": {
         "timeoutInSeconds": 60
       },
       "failureHandlingPolicy": "ROLLBACK"
     },
     "iotJobConfiguration": {
       "abortConfig": {
         "criteriaList": [
           {
             "action": "CANCEL",
             "failureType": "ALL",
             "minNumberOfExecutedThings": 100,
             "thresholdPercentage": 5
           }
         ]
       },
       "jobExecutionsRolloutConfig": {
         "exponentialRate": {
           "baseRatePerMinute": 5,
           "incrementFactor": 2,
           "rateIncreaseCriteria": {
             "numberOfNotifiedThings": 10,
             "numberOfSucceededThings": 5
           }
         },
         "maximumPerMinute": 50
       },
       "timeoutConfig":  {
         "inProgressTimeoutInMinutes": 5
       }
     }
   }
   ```

1. (Optional) Add tags (`tags`) for the deployment. For more information, see [Tag your AWS IoT Greengrass Version 2 resources](tag-resources.md).

1. Run the following command to create the deployment from `deployment.json`.

   ```
   aws greengrassv2 create-deployment --cli-input-json file://deployment.json
   ```

   <a name="check-new-deployment-status"></a>The response includes a `deploymentId` that identifies this deployment. You can use the deployment ID to check the status of the deployment. For more information, see [Check deployment status](check-deployment-status.md#check-cloud-deployment-status).

# Update component configurations
<a name="update-component-configurations"></a>

Component configurations are JSON objects that define the parameters for each component. Each component's recipe defines its default configuration, which you modify when you deploy components to core devices.

When you create a deployment, you can specify the *configuration update* to apply for each component. Configuration updates are patch operations, which means that the update modifies the component configuration that exists on the core device. If the core device doesn't have the component, then the configuration update modifies and applies the default configuration for that deployment.

The configuration update defines *reset* updates and *merge* updates. Reset updates define which configuration values to reset to their defaults or remove. Merge updates define the new configuration values to set for the component. When you deploy a configuration update, the AWS IoT Greengrass Core software runs the reset update before the merge update.

Components can validate the configuration updates that you deploy. The component subscribes to receive a notification when a deployment changes its configuration, and it can reject a configuration that it doesn't support. For more information, see [Interact with component configuration](ipc-component-configuration.md).

**Topics**
+ [Reset updates](#reset-configuration-update)
+ [Merge updates](#merge-configuration-update)
+ [Examples](#configuration-update-example)

## Reset updates
<a name="reset-configuration-update"></a>

Reset updates define which configuration values to reset to their default values on the core device. If a configuration value doesn't have a default value, then the reset update removes that value from the component's configuration. This can help you fix a component that breaks as the result of an invalid configuration.

Use a list of JSON pointers to define which configuration values to reset. JSON pointers start with a forward slash `/`. To identify a value in a nested component configuration, use forward slashes (`/`) to separate the keys for each level in the configuration. For more information, see the [JSON pointer specification](https://tools.ietf.org/html/rfc6901).

**Note**  
You can reset only an entire list to its default values. You can't use reset updates to reset an individual element in a list. 

To reset a component's entire configuration to its default values, specify a single empty string as the reset update.

```
"reset": [""]
```

## Merge updates
<a name="merge-configuration-update"></a>

Merge updates define the configuration values to insert into the component configuration on the core. The merge update is a JSON object that the AWS IoT Greengrass Core software merges after it resets the values in the paths that you specify in the reset update. When you use the AWS CLI or AWS SDKs, you must serialize this JSON object as a string.

You can merge a key-value pair that doesn't exist in the component's default configuration. You can also merge a key-value pair that has a different type than the value with the same key. The new value replaces the old value. This means that you can change the configuration object's structure.

You can merge null values and empty strings, lists, and objects.

**Note**  
You can't use merge updates for the purpose of inserting or appending an element to a list. You can replace an entire list, or you can define an object where each element has a unique key.  
<a name="configuration-value-type-note"></a>AWS IoT Greengrass uses JSON for configuration values. JSON specifies a number type but doesn't differentiate between integers and floats. As a result, configuration values might convert to floats in AWS IoT Greengrass. To ensure that your component uses the correct data type, we recommend that you define numeric configuration values as strings. Then, have your component parse them as integers or floats. This ensures that your configuration values have the same type in the configuration and on your core device.

### Use recipe variables in merge updates
<a name="merge-configuration-update-recipe-variables"></a>

This feature is available for v2.6.0 and later of the [Greengrass nucleus component](greengrass-nucleus-component.md).

If you set the Greengrass nucleus' [interpolateComponentConfiguration](greengrass-nucleus-component.md#greengrass-nucleus-component-configuration-interpolate-component-configuration) configuration option to `true`, you can use recipe variables, other than the `component_dependency_name:configuration:json_pointer` recipe variable, in merge updates. For example, you can use the `{iot:thingName}` recipe variable in a merge update to include the core device's AWS IoT thing name in a component configuration value, such as an [interprocess communication (IPC) authorization policy](interprocess-communication.md#ipc-authorization-policies).

## Examples
<a name="configuration-update-example"></a>

The following example demonstrates configuration updates for a dashboard component that has the following default configuration. This example component displays information about industrial equipment.

```
{
  "name": null,
  "mode": "REQUEST",
  "network": {
    "useHttps": true,
    "port": {
      "http": 80,
      "https": 443
    },
  },
  "tags": []
}
```

### Industrial dashboard component recipe
<a name="w2ab1c24c25c22c16c17b7b1"></a>

------
#### [ JSON ]

```
{
  "RecipeFormatVersion": "2020-01-25",
  "ComponentName": "com.example.IndustrialDashboard",
  "ComponentVersion": "1.0.0",
  "ComponentDescription": "Displays information about industrial equipment.",
  "ComponentPublisher": "Amazon",
  "ComponentConfiguration": {
    "DefaultConfiguration": {
      "name": null,
      "mode": "REQUEST",
      "network": {
        "useHttps": true,
        "port": {
          "http": 80,
          "https": 443
        },
      },
      "tags": []
    }
  },
  "Manifests": [
    {
      "Platform": {
        "os": "linux"
      },
      "Lifecycle": {
        "Run": "python3 -u {artifacts:path}/industrial_dashboard.py"
      }
    },
    {
      "Platform": {
        "os": "windows"
      },
      "Lifecycle": {
        "Run": "py -3 -u {artifacts:path}/industrial_dashboard.py"
      }
    }
  ]
}
```

------
#### [ YAML ]

```
---
RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.IndustrialDashboard
ComponentVersion: '1.0.0'
ComponentDescription: Displays information about industrial equipment.
ComponentPublisher: Amazon
ComponentConfiguration:
  DefaultConfiguration:
    name: null
    mode: REQUEST
    network:
      useHttps: true
      port:
        http: 80
        https: 443
    tags: []
Manifests:
  - Platform:
      os: linux
    Lifecycle:
      Run: |
        python3 -u {artifacts:path}/industrial_dashboard.py
  - Platform:
      os: windows
    Lifecycle:
      Run: |
        py -3 -u {artifacts:path}/industrial_dashboard.py
```

------

**Example 1: Merge update**  
You create a deployment that applies the following configuration update, which specifies a merge update but not a reset update. This configuration update tells the component to display the dashboard on HTTP port 8080 with data from two boilers.    
**Configuration to merge**  

```
{
  "name": "Factory 2A",
  "network": {
    "useHttps": false,
    "port": {
      "http": 8080
    }
  },
  "tags": [
    "/boiler/1/temperature",
    "/boiler/1/pressure",
    "/boiler/2/temperature",
    "/boiler/2/pressure"
  ]
}
```
The following command creates a deployment to a core device.  

```
aws greengrassv2 create-deployment --cli-input-json file://dashboard-deployment.json
```
The `dashboard-deployment.json` file contains the following JSON document.  

```
{
  "targetArn": "arn:aws:iot:us-west-2:123456789012:thing/MyGreengrassCore",
  "deploymentName": "Deployment for MyGreengrassCore",
  "components": {
    "com.example.IndustrialDashboard": {
      "componentVersion": "1.0.0",
      "configurationUpdate": {
        "merge": "{\"name\":\"Factory 2A\",\"network\":{\"useHttps\":false,\"port\":{\"http\":8080}},\"tags\":[\"/boiler/1/temperature\",\"/boiler/1/pressure\",\"/boiler/2/temperature\",\"/boiler/2/pressure\"]}"
      }
    }
  }
}
```
The following [Greengrass CLI](greengrass-cli-component.md) command creates a local deployment on a core device.  

```
sudo greengrass-cli deployment create \
  --recipeDir recipes \
  --artifactDir artifacts \
  --merge "com.example.IndustrialDashboard=1.0.0" \
  --update-config dashboard-configuration.json
```
The `dashboard-configuration.json` file contains the following JSON document.  

```
{
  "com.example.IndustrialDashboard": {
    "MERGE": {
      "name": "Factory 2A",
      "network": {
        "useHttps": false,
        "port": {
          "http": 8080
        }
      },
      "tags": [
        "/boiler/1/temperature",
        "/boiler/1/pressure",
        "/boiler/2/temperature",
        "/boiler/2/pressure"
      ]
    }
  }
}
```
After this update, the dashboard component has the following configuration.  

```
{
  "name": "Factory 2A",
  "mode": "REQUEST",
  "network": {
    "useHttps": false,
    "port": {
      "http": 8080,
      "https": 443
    }
  },
  "tags": [
    "/boiler/1/temperature",
    "/boiler/1/pressure",
    "/boiler/2/temperature",
    "/boiler/2/pressure"
  ]
}
```

**Example 2: Reset and merge updates**  
Then, you create a deployment that applies the following configuration update, which specifies a reset update and a merge update. These updates specify to display the dashboard on the default HTTPS port with data from different boilers. These updates modify the configuration that results from the configuration updates in the previous example.    
**Reset paths**  

```
[
  "/network/useHttps",
  "/tags"
]
```  
**Configuration to merge**  

```
{
  "tags": [
    "/boiler/3/temperature",
    "/boiler/3/pressure",
    "/boiler/4/temperature",
    "/boiler/4/pressure"
  ]
}
```
The following command creates a deployment to a core device.  

```
aws greengrassv2 create-deployment --cli-input-json file://dashboard-deployment2.json
```
The `dashboard-deployment2.json` file contains the following JSON document.  

```
{
  "targetArn": "arn:aws:iot:us-west-2:123456789012:thing/MyGreengrassCore",
  "deploymentName": "Deployment for MyGreengrassCore",
  "components": {
    "com.example.IndustrialDashboard": {
      "componentVersion": "1.0.0",
      "configurationUpdate": {
        "reset": [
          "/network/useHttps",
          "/tags"
        ],
        "merge": "{\"tags\":[\"/boiler/3/temperature\",\"/boiler/3/pressure\",\"/boiler/4/temperature\",\"/boiler/4/pressure\"]}"
      }
    }
  }
}
```
The following [Greengrass CLI](greengrass-cli-component.md) command creates a local deployment on a core device.  

```
sudo greengrass-cli deployment create \
  --recipeDir recipes \
  --artifactDir artifacts \
  --merge "com.example.IndustrialDashboard=1.0.0" \
  --update-config dashboard-configuration2.json
```
The `dashboard-configuration2.json` file contains the following JSON document.  

```
{
  "com.example.IndustrialDashboard": {
    "RESET": [
      "/network/useHttps",
      "/tags"
    ],
    "MERGE": {
      "tags": [
        "/boiler/3/temperature",
        "/boiler/3/pressure",
        "/boiler/4/temperature",
        "/boiler/4/pressure"
      ]
    }
  }
}
```
After this update, the dashboard component has the following configuration.  

```
{
  "name": "Factory 2A",
  "mode": "REQUEST",
  "network": {
    "useHttps": true,
    "port": {
      "http": 8080,
      "https": 443
    }
  },
  "tags": [
    "/boiler/3/temperature",
    "/boiler/3/pressure",
    "/boiler/4/temperature",
    "/boiler/4/pressure",
  ]
}
```

# Create subdeployments
<a name="create-subdeployments"></a>

**Note**  
The subdeployment feature is available on Greengrass nucleus version 2.9.0 and later. It is not possible to deploy a configuration to a subdeployment with earlier component versions of Greengrass nucleus.

A subdeployment is a deployment that targets a smaller subset of devices within a parent deployment. You can use subdeployments to deploy a configuration to a smaller subset of devices. You can also create subdeployments to retry an unsuccessful parent deployment when one or more devices in that parent deployment fails. With this feature, you can select devices that failed in that parent deployment and create a subdeployment to test configurations until the subdeployment is successful. Once the subdeployment is successful, you can redeploy that configuration to the parent deployment.

Follow the steps in this section to create a subdeployment and check its status. For more information about how to create deployments, see [Create deployments](https://docs.aws.amazon.com/greengrass/v2/developerguide/create-deployments.html).

**To create a subdeployment (AWS CLI)**

1. <a name="create-subdeployments-step1"></a>Run the following command to retrieve the latest deployments for a thing group. Replace the ARN in the command with the ARN of the thing group to query. Set `--history-filter` to **LATEST\$1ONLY** to see the latest deployment of that thing group.

   ```
   aws greengrassv2 list-deployments --target-arn arn:aws:iot:region:account-id:thinggroup/thingGroupName --history-filter LATEST_ONLY
   ```

1. Copy the `deploymentId` from the response to the **list-deployments** command to use in the next step.

1. Run the following command to retrieve the status of a deployment. Replace `deploymentId` with the ID of the deployment to query.

   ```
   aws greengrassv2 get-deployment --deployment-id deploymentId
   ```

1. Copy the `iotJobId` from the response to the **get-deployment** command to use in the following step.

1. Run the following command to retrieve the list of job executions for the specified job. Replace *jobID* with the `iotJobId` from the previous step. Replace *status* with the status you want to filter for. You can filter results with the following statuses:
   + `QUEUED`
   + `IN_PROGRESS`
   + `SUCCEEDED`
   + `FAILED`
   + `TIMED_OUT`
   + `REJECTED`
   + `REMOVED`
   + `CANCELED`

   ```
   aws iot list-job-executions-for-job --job-id jobID --status status
   ```

1. Create a new AWS IoT thing group, or use an existing thing group, for your subdeployment. Then, add an AWS IoT thing to this thing group. You use thing groups to manage fleets of Greengrass core devices. When you deploy software components to your devices, you can target either individual devices or groups of devices. You can add a device to a thing group with an active Greengrass deployment. Once added, you can then deploy that thing group's software components to that device.

   To create a new thing group and add your devices to it, do the following:

   1. Create an AWS IoT thing group. Replace *MyGreengrassCoreGroup* with the name for the new thing group. You can't use a colon (:) in a thing group name.
**Note**  
If a thing group for a subdeployment is used with one `parentTargetArn`, it can't be reused with a different parent fleet. If a thing group has already been used to create a subdeployment for another fleet, the API will return an error.

      ```
      aws iot create-thing-group --thing-group-name MyGreengrassCoreGroup
      ```

      If the request succeeds, the response looks similar to the following example:

      ```
      {
        "thingGroupName": "MyGreengrassCoreGroup",
        "thingGroupArn": "arn:aws:iot:us-west-2:123456789012:thinggroup/MyGreengrassCoreGroup",
        "thingGroupId": "4df721e1-ff9f-4f97-92dd-02db4e3f03aa"
      }
      ```

   1. Add a provisioned Greengrass core to your thing group. Run the following command with these parameters:
      + Replace *MyGreengrassCore* with the name of your provisioned Greengrass core.
      + Replace *MyGreengrassCoreGroup* with the name of your thing group.

      ```
      aws iot add-thing-to-thing-group --thing-name MyGreengrassCore --thing-group-name MyGreengrassCoreGroup
      ```

      The command doesn't have any output if the request succeeds.

1. Create a file called `deployment.json`, and then copy the following JSON object into the file. Replace *targetArn* with the ARN of the AWS IoT thing group to target for the subdeployment. A subdeployment target can only be a thing group. Thing group ARNs have the following format:
   + **Thing group** – `arn:aws:iot:region:account-id:thinggroup/thingGroupName`

   ```
   {
     "targetArn": "targetArn"
   }
   ```

1. Run the following command again to get the original deployment's details. These details include metadata, components, and job configuration. Replace *deploymentId* with the ID from [Step 1](#create-subdeployments-step1). You can use this deployment configuration to configure your subdeployment and make changes as needed.

   ```
   aws greengrassv2 get-deployment --deployment-id deploymentId
   ```

   The response contains the deployment's details. Copy any of the following key-value pairs from the **get-deployment** command's response into `deployment.json`. You can change these values for the subdeployment. For more information about the details of this command, see [GetDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_GetDeployment.html).
   + `components` – The deployment's components. To uninstall a component, remove it from this object. If the component defines an [uninstall lifecycle](component-recipe-reference.md#uninstall-lifecycle-definition) step, the AWS IoT Greengrass Core software runs the uninstall script before removing the component from the device.
   + `deploymentName` – The deployment's name.
   + `deploymentPolicies` – The deployment's policies.
   + `iotJobConfiguration` – The deployment's job configuration.
   + `parentTargetArn` – The target of the parent deployment.
   + `tags` – The deployment's tags.

1. Run the following command to create the subdeployment from `deployment.json`. Replace *subdeploymentName* with a name for the subdeployment.

   ```
   aws greengrassv2 create-deployment --deployment-name subdeploymentName --cli-input-json file://deployment.json
   ```

   The response includes a `deploymentId` that identifies this subdeployment. You can use the deployment ID to check the status of the deployment. For more information, see [Check deployment status](https://docs.aws.amazon.com/greengrass/v2/developerguide/check-deployment-status.html#check-cloud-deployment-status).

1. If the subdeployment is successful, you can use its configuration to revise the parent deployent. Copy the `deployment.json` that you used in the previous step. Replace the `targetArn` in the JSON file with the parent deployment's ARN and run the following command to create the parent deployment using this new configuration.
**Note**  
If you create a new deployment revision of the parent fleet, it replaces all deployment revisions and subdeployments for that parent deployment. For more information, see [Revise deployments](https://docs.aws.amazon.com/greengrass/v2/developerguide/revise-deployments.html).

   ```
   aws greengrassv2 create-deployment --cli-input-json file://deployment.json
   ```

   <a name="check-new-deployment-status"></a>The response includes a `deploymentId` that identifies this deployment. You can use the deployment ID to check the status of the deployment. For more information, see [Check deployment status](check-deployment-status.md#check-cloud-deployment-status).

# Revise deployments
<a name="revise-deployments"></a>

Each target thing or thing group can have one active deployment at a time. When you create a deployment for a target that already has a deployment, the software components in the new deployment replace those from the previous deployment. If the new deployment doesn't define a component that the previous deployment defines, the AWS IoT Greengrass Core software removes that component from the target core devices. You can revise an existing deployment so that you don't remove the components that run on core devices from a previous deployment to a target.

To revise a deployment, you create a deployment that starts from the same components and configurations that exist in a previous deployment. You use the [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html) operation, which is the same operation that you use to [create deployments](create-deployments.md).

**To revise a deployment (AWS CLI)**

1. <a name="revise-deployment-list-deployments-intro"></a>Run the following command to list the deployments for the deployment target. Replace *targetArn* with the ARN of the target AWS IoT thing or thing group.

   ```
   aws greengrassv2 list-deployments --target-arn targetArn
   ```

   The response contains a list with the latest deployment for the target. Copy the `deploymentId` from the response to use in the next step.
**Note**  <a name="revise-deployment-list-deployments-revision-note"></a>
You can also revise a deployment other than the latest revision for the target. Specify the `--history-filter ALL` argument to list all deployments for the target. Then, copy the ID of the deployment that you want to revise.

1. <a name="revise-deployment-get-deployment"></a>Run the following command to get the deployment's details. These details include metadata, components, and job configuration. Replace *deploymentId* with the ID from the previous step.

   ```
   aws greengrassv2 get-deployment --deployment-id deploymentId
   ```

   The response contains the deployment's details.

1. Create a file called `deployment.json` and copy the previous command's response into the file.

1. Remove the following key-value pairs from the JSON object in `deployment.json`:
   + `deploymentId`
   + `revisionId`
   + `iotJobId`
   + `iotJobArn`
   + `creationTimestamp`
   + `isLatestForTarget`
   + `deploymentStatus`

   The [CreateDeployment](https://docs.aws.amazon.com/greengrass/v2/APIReference/API_CreateDeployment.html) operation expects a payload with the following structure.

   ```
   {
     "targetArn": "String",
     "components": Map of components,
     "deploymentPolicies": DeploymentPolicies,
     "iotJobConfiguration": DeploymentIoTJobConfiguration,
     "tags": Map of tags
   }
   ```

1. In `deployment.json`, do any of the following:
   + Change the deployment's name (`deploymentName`).
   + Change the deployment's components (`components`).
   + Change the deployment's policies (`deploymentPolicies`).
   + Change the deployment's job configuration (`iotJobConfiguration`).
   + Change the deployment's tags (`tags`).

   For more information about how to define these deployment details, see [Create deployments](create-deployments.md).

1. Run the following command to create the deployment from `deployment.json`.

   ```
   aws greengrassv2 create-deployment --cli-input-json file://deployment.json
   ```

   <a name="check-new-deployment-status"></a>The response includes a `deploymentId` that identifies this deployment. You can use the deployment ID to check the status of the deployment. For more information, see [Check deployment status](check-deployment-status.md#check-cloud-deployment-status).

# Cancel deployments
<a name="cancel-deployments"></a>

You can cancel an active deployment to prevent its software components from installing on AWS IoT Greengrass core devices. If you cancel a deployment that targets a thing group, core devices that you add to the group won't receive that continuous deployment. If a core device already runs the deployment, you won't change the components on that device when you cancel the deployment. You must [create a new deployment](create-deployments.md) or [revise the deployment](revise-deployments.md) to modify the components that run on the core devices that received the canceled deployment.

**To cancel a deployment (AWS CLI)**

1. Run the following command to find the ID of the latest deployment revision for a target. The latest revision is the only deployment that can be active for a target, because previous deployments cancel when you create a new revision. Replace *targetArn* with the ARN of the target AWS IoT thing or thing group.

   ```
   aws greengrassv2 list-deployments --target-arn targetArn
   ```

   The response contains a list with the latest deployment for the target. Copy the `deploymentId` from the response to use in the next step.

1. Run the following command to cancel the deployment. Replace *deploymentId* with the ID from the previous step.

   ```
   aws greengrassv2 cancel-deployment --deployment-id deploymentId
   ```

   If the operation succeeds, the deployment status changes to `CANCELED`.

# Check deployment status
<a name="check-deployment-status"></a>

You can check the status of a deployment that you create in AWS IoT Greengrass. You can also check the status of the AWS IoT jobs that roll out the deployment to each core device. While a deployment is active, the AWS IoT job's status is `IN_PROGRESS`. After you create a new revision of a deployment, the status of the previous revision's AWS IoT job changes to `CANCELLED`.

**Topics**
+ [Check deployment status](#check-cloud-deployment-status)
+ [Check device deployment status](#check-device-deployment-status)

## Check deployment status
<a name="check-cloud-deployment-status"></a>

You can check the status of a deployment that you identify by its target or its ID.

**To check deployment status by target (AWS CLI)**
+ Run the following command to retrieve the status of the latest deployment for a target. Replace *targetArn* with the Amazon Resource Name (ARN) of the AWS IoT thing or thing group that the deployment targets.

  ```
  aws greengrassv2 list-deployments --target-arn targetArn
  ```

  The response contains a list with the latest deployment for the target. This deployment object includes the status of the deployment.

**To check deployment status by ID (AWS CLI)**
+ Run the following command to retrieve the status of a deployment. Replace *deploymentId* with the ID of the deployment to query.

  ```
  aws greengrassv2 get-deployment --deployment-id deploymentId
  ```

  The response contains the status of the deployment.

## Check device deployment status
<a name="check-device-deployment-status"></a>

You can check the status of a deployment job that applies to an individual core device. You can also check the status of a deployment job for a thing group deployment.

**To check deployment job statuses for a core device (AWS CLI)**
+ Run the following command to retrieve the status of all deployment jobs for a core device. Replace *coreDeviceName* with the name of the core device to query.

  ```
  aws greengrassv2 list-effective-deployments --core-device-thing-name coreDeviceName
  ```

  The response contains the list of deployment jobs for the core device. You can identify the job for a deployment by the job's `deploymentId` or `targetArn`. Each deployment job contains the status of the job on the core device.

**To check deployment statuses for a thing group (AWS CLI)**

1. Run the following command to retrieve the ID of an existing deployment. Replace *targetArn* with the ARN of the target thing group.

   ```
   aws greengrassv2 list-deployments --target-arn targetArn
   ```

   The response contains a list with the latest deployment for the target. Copy the `deploymentId` from the response to use in the next step.
**Note**  
You can also list a deployment other than the latest deployment for the target. Specify the `--history-filter ALL` argument to list all deployments for the target. Then, copy the ID of the deployment that you want to check the status of.

1. Run the following command to get the deployment's details. Replace *deploymentID* with the ID from the previous step.

   ```
   aws greengrassv2 get-deployment --deployment-id deploymentId
   ```

   The response contains information about the deployment. Copy the `iotJobId` from the response to use in the following step.

1. Run the following command to describe a core device's job execution for the deployment. Replace *iotJobId* and *coreDeviceThingName* with the job ID from the previous step and the core device you want to check the status for.

   ```
   aws iot describe-job-execution --job-id iotJobId --thing-name coreDeviceThingName
   ```

   The response contains the status of the core device's deployment job execution and details about the status. The `detailsMap` contains the following information:
   + `detailed-deployment-status` – The deployment result status, which can be one of the following values:
     + `SUCCESSFUL` – The deployment succeeded.
     + `FAILED_NO_STATE_CHANGE` – The deployment failed while the core device prepared to apply the deployment.
     + `FAILED_ROLLBACK_NOT_REQUESTED` – The deployment failed, and the deployment didn't specify to roll back to a previous working configuration, so the core device might not be functioning correctly.
     + `FAILED_ROLLBACK_COMPLETE` – The deployment failed, and the core device successfully rolled back to a previous working configuration.
     + `FAILED_UNABLE_TO_ROLLBACK` – The deployment failed, and the core device failed to roll back to a previous working configuration, so the core device might not be functioning correctly.

     If the deployment failed, check the `deployment-failure-cause` value and the core device's log files to identify the issue. For more information about how to access the core device's log files, see [Monitor AWS IoT Greengrass logs](monitor-logs.md).
   + `deployment-failure-cause` – An error message that provides additional details about why the job execution failed.

   The response looks similar to the following example.

   ```
   {
     "execution": {
       "jobId": "2cc2698a-5175-48bb-adf2-1dd345606ebd",
       "status": "FAILED",
       "statusDetails": {
         "detailsMap": {
           "deployment-failure-cause": "No local or cloud component version satisfies the requirements. Check whether the version constraints conflict and that the component exists in your AWS account with a version that matches the version constraints. If the version constraints conflict, revise deployments to resolve the conflict. Component com.example.HelloWorld version constraints: LOCAL_DEPLOYMENT requires =1.0.0, thinggroup/MyGreengrassCoreGroup requires =1.0.1.",
           "detailed-deployment-status": "FAILED_NO_STATE_CHANGE"
         }
       },
       "thingArn": "arn:aws:iot:us-west-2:123456789012:thing/MyGreengrassCore",
       "queuedAt": "2022-02-15T14:45:53.098000-08:00",
       "startedAt": "2022-02-15T14:46:05.670000-08:00",
       "lastUpdatedAt": "2022-02-15T14:46:20.892000-08:00",
       "executionNumber": 1,
       "versionNumber": 3
     }
   }
   ```