如何将资源导入无服务器托管项目?

问题描述 投票:0回答:2

我正在使用

serverless
部署 AWS 资源。有时我会收到有关现有资源如何导致部署失败的错误。这可能是由于团队中的另一个开发人员部署了名称冲突的资源造成的。我想知道我应该如何处理这个问题
serverless

我之前使用过

terraform
,它支持
import
命令,用于将现有资源导入到我的项目中。
serverless
有类似的吗?如果不是,解决此问题的最佳实践是什么?我不想手动删除 AWS 上的资源。

amazon-web-services terraform serverless
2个回答
0
投票

如果您询问如何将现有资源导入无服务器

到目前为止,我对 AWS 和无服务器框架还没有丰富的经验(我最近才开始采用它们),但据我所知,导入现有的 AWS 资源并不是那么容易。

我最近必须将现有的手动创建的 DynamoDB 表添加到 Serverless (SLS),而不影响其中的数据。这个想法听起来很简单,直到我点击

sls deploy
时收到以下消息:

Resource of type 'AWS::DynamoDB::Table' with identifier 'myTable' already exists.

无服务器框架采用 CloudFormation Stacks 进行底层部署,因此我专注于此,最终在 AWS Docs 中找到了解决方案。

AWS 文档:将现有资源导入堆栈

我强烈建议成对执行此手动过程,您可能还想确保没有人并行修改堆栈和资源。

这是我所做的:

想象下面

serverless.yml

service: aws-node-project-1
frameworkVersion: '3'

provider:
  name: aws
  region: eu-west-1
  runtime: nodejs18.x

functions:
  function1:
    handler: index.handler

# The above was already deployed successfully.

# resources: # Here is the Resource we can't add to Serverless at this time. 
#   Resources:
#     myTable:
#       DeletionPolicy: Retain
#       Type: AWS::DynamoDB::Table
#       Properties:
#         TableName: myTable
#         AttributeDefinitions:
#           - AttributeName: id
#             AttributeType: S
#         KeySchema:
#           - AttributeName: id
#             KeyType: HASH
#         BillingMode: PAY_PER_REQUEST

1.获取堆栈模板

部署无服务器服务后,它会创建一个 CloudFormation 堆栈,其中包括它管理的资源。例如,如果服务的名称是

aws-node-project-1
,阶段是
dev
,那么默认情况下,堆栈的名称很可能是
aws-node-project-1-dev
。以下命令将帮助您在
template.json
文件中获取堆栈模板。

aws cloudformation get-template --stack-name aws-node-project-1-dev --output json > template.json

这应该如下所示:

{
    "TemplateBody": {
        "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "The AWS CloudFormation template for this Serverless application",
        "Resources": {
            // Your existing Resources in the Stack.
        },
        "Outputs": {
            // ...
        }
    },
    "StagesAvailable": [
        // ...
    ]
}

2.获取资源描述

获取您要导入的资源的描述。就我而言,它是一个 DynamoDB 表。

aws dynamodb describe-table --table-name myTable --output json > table.json

这应该如下所示:

{
    "Table": {
        "AttributeDefinitions": [
            // ...
        ],
        "TableName": "myTable",
        "KeySchema": [
            // ...
        ],
        "TableStatus": "ACTIVE",
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 44,
        "ItemCount": 3,
        "TableArn": "SOME_ARN",
        "TableId": "SOME_ID",
        "GlobalSecondaryIndexes": [
            // ...
        ],
        "TableClassSummary": {
            "TableClass": "STANDARD"
        },
        "DeletionProtectionEnabled": false

        // ...
    }
}

3.将资源添加到 template.json 文件中

将新资源添加到

template.json
文件中,而不删除任何现有资源。该文件应包含现有堆栈资源和您要导入的资源。

您还需要将

TemplateBody
移动到文件的根目录并删除
TemplateBody
StagesAvailable
字段。

最终,文件应如下所示:

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "The AWS CloudFormation template for this Serverless application",
    "Resources": {
        
        // Your existing Resources in the Stack.
        // ...

        // The resource you want to import:
        "myTable": { // Don't forget: This field name is treated as the Logical Id.
            "Type": "AWS::DynamoDB::Table",
            "DeletionPolicy": "Retain", // You might need to add this.
            "Properties": {
                "AttributeDefinitions": [
                    {
                        "AttributeName": "id",
                        "AttributeType": "S"
                    }
                ],
                "TableName": "myTable",
                "KeySchema": [
                    {
                        "AttributeName": "id",
                        "KeyType": "HASH"
                    }
                ],
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 0,
                    "WriteCapacityUnits": 0
                }
            }
        }
    },
    "Outputs": {
        // ...
    }
}
4.创建变更集
aws cloudformation create-change-set \
--stack-name aws-node-project-1-dev --change-set-name ImportChangeSet \
--change-set-type IMPORT \
--resources-to-import "[{\"ResourceType\":\"AWS::DynamoDB::Table\",\"LogicalResourceId\":\"myTable\",\"ResourceIdentifier\":{\"TableName\":\"myTable\"}}]" \
--template-body file://template.json \
# --capabilities CAPABILITY_NAMED_IAM # You may need such Capabilities depending on your case. Use this field consciously.
5.查看更改集
aws cloudformation describe-change-set --change-set-name ImportChangeSet --stack-name aws-node-project-1-dev
6.执行更改集
aws cloudformation execute-change-set --change-set-name ImportChangeSet --stack-name aws-node-project-1-dev
7.查看活动。

如果成功,您应该会看到

"ResourceStatus": "IMPORT_COMPLETE"
(给 AWS 一些时间来进展)。

# In AWS Web Console: CloudFormation -> aws-node-project-1-dev -> Events
aws cloudformation describe-stack-events --stack-name aws-node-project-1-dev
8.检查堆栈资源

验证资源是否已按预期添加到堆栈中。

# In AWS Web Console: CloudFormation -> aws-node-project-1-dev -> Resources
aws cloudformation describe-stack-resources --stack-name aws-node-project-1-dev
9.检查是否有漂移

在此阶段,您应该能够将资源添加到

serverless.yml
并进行部署。但在执行此操作之前,我建议检查导入的资源是否存在漂移。

据我了解,术语

Drift
用于指出堆栈所需配置(如模板中所述)与实际资源状态之间的差异。

# Start detection. This is a background process therefore it will return
# a `Stack-Drift-Detection-Id` so you can check the status of this process later.
# In AWS Web Console: CloudFormation -> aws-node-project-1-dev -> Stack Actions > Detect drifts
aws cloudformation detect-stack-drift --stack-name aws-node-project-1-dev

# Check the detection status until `DetectionStatus` is `DETECTION_COMPLETE`.
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id YOUR_STACK_DRIFT_DETECTION_ID_HERE

# If `StackDriftStatus` is `DRIFTED`, check the Drifts with the following command and resolve accordingly.
# In AWS Web Console: CloudFormation -> aws-node-project-1-dev -> Stack Actions > View drift results
aws cloudformation describe-stack-resource-drifts --stack-name aws-node-project-1-dev

-2
投票

TL;DR: 无服务器框架不支持导入 CloudFormation 资源。但有办法解决所讨论的问题。

无服务器允许您使用现有 CloudFormation 资源的。先决条件是您的同事或至少 CloudFormation 堆栈将您依赖的资源描述为 “输出”

// in your colleagues serverless.yaml to export a VPC
resources:
   // ...
   Outputs:
     StackVPC:
       Description: The ID of the VPC
       Value: !Ref MyVPC
       Export:
         Name: !Sub "${AWS::StackName}-VPCID"

在您的 serverless.yaml 中,您可以导入/引用现有 VPC。有几种方法可以将资源导入到您的堆栈中。

var1: 'Fn::ImportValue': '${refSackName}-VPCID'
var2: ${cf:${refSackName}-VPCID}

对我来说,我主要使用

Fn::ImportValue

此处列出了此方法的优点和缺点https://dev.to/lambdasharp/dynamic-bindings-for-cloudformation-stacks-15l6

© www.soinside.com 2019 - 2024. All rights reserved.