

终止支持通知：2026 年 5 月 31 日， AWS 将终止对的支持。 AWS Panorama 2026 年 5 月 31 日之后，您将无法再访问 AWS Panorama 控制台或 AWS Panorama 资源。有关更多信息，请参阅[AWS Panorama 终止支持](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 自动化应用程序部署
<a name="api-deploy"></a>

要部署应用程序，您可以同时使用 AWS Panorama 应用程序 CLI 和 AWS Command Line Interface。构建应用程序容器后，将其和其他资产上传到 Amazon S3 接入点。然后，您可以使用 [CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html)API 部署应用程序。

有关使用所示脚本的更多上下文和说明，请按照[示例应用程序自述文件](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/README.md)中的说明进行操作。

**Topics**
+ [构建容器](#api-deploy-build)
+ [上传容器并注册节点](#api-deploy-upload)
+ [部署应用程序](#api-deploy-deploy)
+ [监控部署](#api-deploy-monitor)

## 构建容器
<a name="api-deploy-build"></a>

若要生成应用程序容器，请使用 `build-container` 命令。此命令会构建一个 Docker 容器，并将其作为压缩文件系统保存在 `assets` 文件夹中。

**Example [3-build-container.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/3-build-container.sh)**  

```
CODE_PACKAGE=SAMPLE_CODE
ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account')
panorama-cli build-container --container-asset-name code_asset --package-path packages/${ACCOUNT_ID}-${CODE_PACKAGE}-1.0
```

还可以使用命令行完成来填充路径参数，方法是键入部分路径，然后按 TAB。

```
$ panorama-cli build-container --package-path packages/TAB
```

## 上传容器并注册节点
<a name="api-deploy-upload"></a>

要上传应用程序，请使用 `package-application` 命令。此命令会将资产从 `assets` 文件夹上传到 AWS Panorama 管理的 Amazon S3 接入点。

**Example [4-package-app.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/4-package-app.sh)**  

```
panorama-cli package-application
```

 AWS Panorama 应用程序 CLI 会上传每个软件包中软件包配置 (`package.json`) 引用的容器和描述符资产，并将软件包注册为 AWS Panorama 中的节点。然后，在应用程序清单 (`graph.json`) 中引用这些节点来部署应用程序。

## 部署应用程序
<a name="api-deploy-deploy"></a>

要部署应用程序，您可以使用 [CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html)API。除其他外，此操作采用以下参数。

****
+ `ManifestPayload` – 定义应用程序节点、包、边缘和参数的应用程序清单(`graph.json`)。
+ `ManifestOverridesPayload` – 第二个清单，覆盖第一个清单中的参数。应用程序清单可被视为应用程序源中的静态资源，其中覆盖清单提供了用于自定义部署的部署时设置。
+ `DefaultRuntimeContextDevice` – 目标设备。
+ `RuntimeRoleArn` – 应用程序用于访问 AWS 服务和资源的 IAM 角色的 ARN。
+ `ApplicationInstanceIdToReplace` – 要从设备中移除的现有应用程序实例的 ID。

清单和覆盖负载是 JSON 文档，必须作为嵌套在另一个文档中的字符串值提供。为此，脚本以字符串形式从文件中加载清单，并使用[jq 工具](https://stedolan.github.io/jq/)构造嵌套文档。

**Example [5-deploy.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/5-deploy.sh) – 撰写清单**  

```
GRAPH_PATH="graphs/my-app/graph.json"
OVERRIDE_PATH="graphs/my-app/override.json"
# application manifest
GRAPH=$(cat ${GRAPH_PATH} | tr -d '\n' | tr -d '[:blank:]')
MANIFEST="$(jq --arg value "${GRAPH}" '.PayloadData="\($value)"' <<< {})"
# manifest override
OVERRIDE=$(cat ${OVERRIDE_PATH} | tr -d '\n' | tr -d '[:blank:]')
MANIFEST_OVERRIDE="$(jq --arg value "${OVERRIDE}" '.PayloadData="\($value)"' <<< {})"
```

部署脚本使用 [ListDevices](https://docs.aws.amazon.com/panorama/latest/api/API_ListDevices.html)API 获取当前区域中已注册设备的列表，并将用户的选择保存到本地文件中以供后续部署。

**Example [5-deploy.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/5-deploy.sh) – 查找设备**  

```
    echo "Getting devices..."
    DEVICES=$(aws panorama list-devices)
    DEVICE_NAMES=($((echo ${DEVICES} | jq -r '.Devices |=sort_by(.LastUpdatedTime) | [.Devices[].Name] | @sh') | tr -d \'\"))
    DEVICE_IDS=($((echo ${DEVICES} | jq -r '.Devices |=sort_by(.LastUpdatedTime) | [.Devices[].DeviceId] | @sh') | tr -d \'\"))
    for (( c=0; c<${#DEVICE_NAMES[@]}; c++ ))
    do
        echo "${c}: ${DEVICE_IDS[${c}]}     ${DEVICE_NAMES[${c}]}"
    done
    echo "Choose a device"
    read D_INDEX
    echo "Deploying to device ${DEVICE_IDS[${D_INDEX}]}"
    echo -n ${DEVICE_IDS[${D_INDEX}]} > device-id.txt
    DEVICE_ID=$(cat device-id.txt)
```

应用程序角色由另一个脚本 ([1-create-role.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/1-create-role.sh)) 创建。部署脚本从中获取此角色的 ARN。 AWS CloudFormation如果应用程序已部署到设备上，则脚本会从本地文件中获取该应用程序实例的 ID。

**Example [5-deploy.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/5-deploy.sh) – 角色 ARN 和替换参数**  

```
# application role
STACK_NAME=panorama-${NAME}
ROLE_ARN=$(aws cloudformation describe-stacks --stack-name panorama-${PWD##*/} --query 'Stacks[0].Outputs[?OutputKey==`roleArn`].OutputValue' --output text)
ROLE_ARG="--runtime-role-arn=${ROLE_ARN}"

# existing application instance id
if [ -f "application-id.txt" ]; then
    EXISTING_APPLICATION=$(cat application-id.txt)
    REPLACE_ARG="--application-instance-id-to-replace=${EXISTING_APPLICATION}"
    echo "Replacing application instance ${EXISTING_APPLICATION}"
fi
```

最后，该脚本会将所有部分组合在一起，以创建应用程序实例并将应用程序部署到设备上。该服务以实例 ID 作为响应，脚本会存储该实例 ID 以供日后使用。

**Example [5-deploy.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/5-deploy.sh) – 部署应用程序**  

```
APPLICATION_ID=$(aws panorama create-application-instance ${REPLACE_ARG} --manifest-payload="${MANIFEST}" --default-runtime-context-device=${DEVICE_ID} --name=${NAME} --description="command-line deploy" --tags client=sample --manifest-overrides-payload="${MANIFEST_OVERRIDE}" ${ROLE_ARG} --output text)
echo "New application instance ${APPLICATION_ID}"
echo -n $APPLICATION_ID > application-id.txt
```

## 监控部署
<a name="api-deploy-monitor"></a>

要监控部署，请使用 [ListApplicationInstances](https://docs.aws.amazon.com/panorama/latest/api/API_ListApplicationInstances.html)API。监控脚本从应用程序目录中的文件获取设备 ID 和应用程序实例 ID，并使用它们构造 CLI 命令。然后它会循环调用。

**Example [6-monitor-deployment.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/6-monitor-deployment.sh)**  

```
APPLICATION_ID=$(cat application-id.txt)
DEVICE_ID=$(cat device-id.txt)
QUERY="ApplicationInstances[?ApplicationInstanceId==\`APPLICATION_ID\`]"
QUERY=${QUERY/APPLICATION_ID/$APPLICATION_ID}
MONITOR_CMD="aws panorama list-application-instances --device-id ${DEVICE_ID} --query ${QUERY}"
MONITOR_CMD=${MONITOR_CMD/QUERY/$QUERY}
while true; do
    $MONITOR_CMD
    sleep 60
done
```

部署完成后，您可以通过调用 Amazon 日志 API 来查看 CloudWatch 日志。查看日志脚本使用日 CloudWatch 志 `GetLogEvents` API。

**Example [view-logs.sh](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/util-scripts/view-logs.sh)**  

```
GROUP="/aws/panorama/devices/MY_DEVICE_ID/applications/MY_APPLICATION_ID"
GROUP=${GROUP/MY_DEVICE_ID/$DEVICE_ID}
GROUP=${GROUP/MY_APPLICATION_ID/$APPLICATION_ID}
echo "Getting logs for group ${GROUP}."
#set -x
while true
do
    LOGS=$(aws logs get-log-events --log-group-name ${GROUP} --log-stream-name code_node --limit 150)
    readarray -t ENTRIES < <(echo $LOGS | jq -c '.events[].message')
    for ENTRY in "${ENTRIES[@]}"; do
        echo "$ENTRY" | tr -d \"
    done
    sleep 20
done
```