无服务器框架 - 我需要哪些权限才能使用AWS SSM参数存储?

7

我发布此问题是因为似乎没有相关文档,所以经过长时间的试错和浪费,我想提供答案。

背景介绍,Serverless框架[允许从AWS SSM参数存储区加载纯文本和SecureString值]。1

在执行无服务器部署时,需要哪些权限才能访问和加载这些SSM参数存储值?

3个回答

14
一般来说,要访问和解密AWS SSM参数存储值需要这3个权限:
  1. ssm:DescribeParameters
  2. ssm:GetParameters
  3. kms:Decrypt
以下是一个真实的例子,它只允许访问与我的Lambda函数相关的SSM参数(通过遵循通用的命名约定/模式进行区分)- 它适用于以下情况:
  1. 使用默认的AWS SSM加密密钥加密SecureString值。
  2. 所有参数都使用以下命名约定:
  3. a. /${app-name-or-app-namespace}/serverless/${lambda-function-name/then/whatever/else/you/want

    b.${lambda-function-name} 必须以 sls- 开头

例如,假设我有一个名为myCoolApp的应用程序,和一个名为sls-myCoolLambdaFunction 的Lambda函数。也许我想保存数据库配置值,如用户名和密码。
我会创建两个SSM参数:
  1. /myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/username (明文)

  2. /myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/password (SecureString)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:DescribeParameters"
            ],
            "Resource": [
                "arn:aws:ssm:${region-or-wildcard}:${aws-account-id-or-wildcard}:*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "ssm:GetParameter"
            ],
            "Resource": [
                "arn:aws:ssm:${region-or-wildcard}:${aws-account-id-or-wildcard}:parameter/myCoolApp/serverless/sls-*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:*:${aws-account-id}:key/alias/aws/ssm"
            ]
        }
    ]
}

然后在我的serverless.yml文件中,我可以像这样将这两个SSM值引用为函数级环境变量

environment:
      DATABASE_USERNAME: ${ssm:/myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/username}
      DATABASE_PASSWORD: ${ssm:/myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/password~true}

或者更好的是,如果我想要在不同的配置值情况下实现超级动态的效果,可以像这样设置环境变量

environment:
      DATABASE_USERNAME: ${ssm:/myCoolApp/serverless/sls-myCoolLambdaFunction/${self:provider.stage}/database/username}
      DATABASE_PASSWORD: ${ssm:/myCoolApp/serverless/sls-myCoolLambdaFunction/${self:provider.stage}/database/password~true}

通过上面的例子,如果我有两个阶段 - devprod,也许我会创建以下 SSM 参数:

  1. /myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/username (明文)

  2. /myCoolApp/serverless/sls-myCoolLambdaFunction/dev/database/password (SecureString)

  3. /myCoolApp/serverless/sls-myCoolLambdaFunction/prod/database/username (明文)

  4. /myCoolApp/serverless/sls-myCoolLambdaFunction/prod/database/password (SecureString)


你提供了一个很好的例子。然而,在serverless.yml中包含用户/密码部分并不好。因为最终它会被上传到S3,cloudformation将运行它,lambda将在其环境中具有用户/密码。 - Edmond
@Edmond,这是有关于构建时和运行时配置的古老问题。我同意你的看法,更安全的方式应该是在运行时使用Lambda代码通过其IAM角色从SSM(或其他数据存储)检索秘密信息。 - sudo soul

4

我建议在代码中使用AWS SDK获取SSM参数,而不是保存在环境文件中(即.env)。这样更加安全。您需要为使用的角色分配权限,将操作设置为ssm:GetParameter,并将资源指向SSM参数存储中的参数。我使用serverless框架进行部署。以下是我在serverless.yml中的内容,假设参数名称符合模式"{stage}-myproject-*"(例如dev-myproject-username,qa-myproject-password):

custom:
  myStage: ${opt:stage}
provider:
  name: aws
  runtime: nodejs10.x
  stage: ${self:custom.myStage}
  region: us-east-1
  myAccountId: <aws account id>
  iamRoleStatements:
    - Effect: Allow
      Action:
        - ssm:GetParameter
      Resource: "arn:aws:ssm:${self:provider.region}:${self:provider.myAccountId}:parameter/${self:provider.stage}-myproject-*"

以下是翻译的结果:

下面列出了两个有用的资源: 如何保存凭证? 无服务器框架IAM文档


iamRoleStatements在提供程序下如何应用于个别资源/ Lambda函数?这些语句最终与Lambda绑定在哪里? - Charlie Schliesser

0
如果您在CI/CD流水线中使用CodeBuild,请不要忘记将SSM授权策略添加到CodeBuild服务角色中。(当我们谈论SSM时,必须区分SecretsManager和ParameterStore)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接