

# 使用 AWS CLI 将本地构件上传到 S3 存储桶
<a name="using-cfn-cli-package"></a>

现在，您可以使用 AWS CLI 命令将 CloudFormation 模板引用的本地构件上传到 Amazon S3 存储桶。本地构件是您在模板中引用的文件。您可以在模板中指定本地构件，然后使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) 命令快速上传它们，而不是将文件手动上传到 S3 存储桶，然后向模板添加其位置。

本地项目是 **package** 命令将向 Amazon S3 上传的文件或文件夹的路径。例如，构件可以是 AWS Lambda 函数的源代码或 Amazon API Gateway REST API 的 OpenAPI 文件的本地路径。

使用 **package** 命令时：
+ 如果您指定一个文件，此命令会将该文件直接上传到 S3 存储桶。
+ 如果您指定一个文件夹，则命令将为该文件夹创建一个 `.zip` 文件，然后上传该 `.zip` 文件。
+ 如果您未指定路径，则命令将为工作目录创建一个 `.zip` 文件，然后上传该文件。

您可指定绝对路径或相对路径，其中相对路径相对于模板的位置。

在上传项目之后，此命令将返回模板的副本，并将对本地项目的引用替换为命令已将项目上传到的 S3 位置。然后，您可使用返回的模板创建或更新堆栈。

**注意**  
您只能对 **package** 命令支持的资源属性使用本地项目。有关此命令的更多信息和支持的资源属性的列表，请参阅 [AWS CLI 命令参考](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/index.html)中的 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) 文档。



## 先决条件
<a name="using-cfn-cli-package-prerequisites"></a>

在开始之前，您必须有一个现有的 Amazon S3 存储桶。

## 打包并部署包含本地构件的模板
<a name="package-and-deploy-a-template-with-local-artifacts"></a>

以下模板指定 Lambda 函数的源代码的本地项目。此源代码存储在 `/home/user/code/lambdafunction` 文件夹中。

**原始模板**

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Resources": {
    "MyFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "nodejs18.x",
        "CodeUri": "/home/user/code/lambdafunction"
      }
    }
  }
}
```

以下 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) 命令创建函数源代码文件夹的 `.zip` 文件，然后将该文件上传到指定存储桶的根目录。

```
aws cloudformation package \
  --s3-bucket amzn-s3-demo-bucket \
  --template /path_to_template/template.json \
  --output-template-file packaged-template.json \
  --output json
```

该命令在 `--output-template-file` 指定的路径上生成一个新模板。它将构件引用替换为 Amazon S3 位置，如下图所示。`.zip` 文件是使用文件夹内容的 MD5 校验和命名的，而不是使用文件夹名称本身。

**结果模板**

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Resources": {
    "MyFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "nodejs18.x",
        "CodeUri": "s3://amzn-s3-demo-bucket/md5 checksum"
      }
    }
  }
}
```

打包模板的构件后，使用 [https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/) 命令部署已处理的模板。

```
aws cloudformation deploy \
  --template-file packaged-template.json \
  --stack-name stack-name
```

部署大于 51200 字节的模板时，使用带有 `--s3-bucket` 选项的 **deploy** 命令将模板上传到 S3，如下例所示。

```
aws cloudformation deploy \
  --template-file packaged-template.json \
  --stack-name stack-name \
  --s3-bucket amzn-s3-demo-bucket
```

**注意**  
有关使用 **package** 命令上传本地构件的另一个示例，请参阅[使用嵌套堆栈将模板拆分为可重复使用的部分](using-cfn-nested-stacks.md)。