如何在 Cloudformation 脚本执行期间将 Cognito UserPoolID、客户端密码传递给 AWS Lambda?

Posted

技术标签:

【中文标题】如何在 Cloudformation 脚本执行期间将 Cognito UserPoolID、客户端密码传递给 AWS Lambda?【英文标题】:How to pass Cognito UserPoolID, client secret to AWS Lambda during Cloudformation script execution? 【发布时间】:2020-11-27 12:23:21 【问题描述】:

我创建了 Cloudformation 脚本,该脚本创建了 AWS Cognito 并部署了一组 AWS Lambda。 Cloudformation yaml 如下所示:

  UserPool:
    Type: "AWS::Cognito::UserPool"
    Properties:
      UserPoolName:  !Sub $EnvPrefix-smartshoesuserpool
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireUppercase: true
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true
          TemporaryPasswordValidityDays: 7
      AutoVerifiedAttributes:
        - email
      AliasAttributes:
        - email
      EmailVerificationMessage: 'Your verification code is ####. '
      EmailVerificationSubject: Your verification code
      VerificationMessageTemplate:
        EmailMessage: 'Your verification code is ####. '
        EmailSubject: Your verification code
        DefaultEmailOption: CONFIRM_WITH_CODE
      MfaConfiguration: 'OFF'
      EmailConfiguration:
        EmailSendingAccount: COGNITO_DEFAULT
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: false
        InviteMessageTemplate:
          SMSMessage: 'Your username is username and temporary password is ####. '
          EmailMessage: 'Your username is username and temporary password is ####. '
          EmailSubject: Your temporary password
      UsernameConfiguration:
        CaseSensitive: false
      AccountRecoverySetting:
        RecoveryMechanisms:
        - Priority: 1
          Name: verified_email
        - Priority: 2
          Name: verified_phone_number
      UserPoolTags:
        Creator: !Ref CreatorUsername
        Environment:  !Ref EnvPrefix
      
  # User Pool client  
  # eksport z uzyciem: aws cognito-idp describe-user-pool-client --user-pool-id eu-central-1_E5ZQHWb1N --client-id 7oasfnq1cld9sh4jajjap2g80p
  UserPoolClient:
    Type: "AWS::Cognito::UserPoolClient"
    Properties:
      UserPoolId: !Ref UserPool
      ClientName: !Sub $EnvPrefix-smartshoesuserpoolclient
      RefreshTokenValidity: 30
      ReadAttributes:
      - email
      - email_verified
      WriteAttributes:
      - email
      ExplicitAuthFlows:
      - ALLOW_ADMIN_USER_PASSWORD_AUTH
      - ALLOW_CUSTOM_AUTH
      - ALLOW_REFRESH_TOKEN_AUTH
      - ALLOW_USER_PASSWORD_AUTH
      - ALLOW_USER_SRP_AUTH
      AllowedOAuthFlowsUserPoolClient: false
      PreventUserExistenceErrors: ENABLED

只需创建 UserPool 和 UserPoolClient。 但是我有一个问题,因为在 Lambda 函数中我必须知道 UserPoolId、UserClientId 和 ClientSecret,而且我还没有找到在 Clorudformation yaml 中获取这些值的方法。 我可以使用 Boto3 编写简短的 Python 程序来搜索 UserPool 和其他值,但我无法在 yaml 中执行它。在部署阶段如何获取这些参数并“注入”到 Lambda 函数?

.....
def initiate_auth(client, username, password):
  secret_hash = get_secret_hash(username)
    try:
      resp = client.admin_initiate_auth(
                 UserPoolId=USER_POOL_ID,
                 ClientId=CLIENT_ID,
                 AuthFlow='ADMIN_NO_SRP_AUTH',
                 AuthParameters=
                     'USERNAME': username,
                     'SECRET_HASH': secret_hash,
                     'PASSWORD': password,
                  ,
                ClientMetadata=
                  'username': username,
                  'password': password,
              )
....

【问题讨论】:

【参考方案1】:

我可以使用 Boto3 编写简短的 Python 程序来搜索 UserPool 和其他值,但我无法在 yaml 中执行它

您可以考虑在 CloudFormation 中开发custom resource。资源将是一个 lambda 函数,它可以执行您的 python 脚本,并将任何需要的值返回给模板中的其他资源。

但是,如果您还在同一模板中创建 lambda 函数,则可以使用函数的 Environment 属性传递 ID:

在执行期间可从函数代码访问的环境变量。

【讨论】:

谢谢,这是一个很好的解决方案,但这个问题很普遍,我很惊讶它没有以一般方式解决。或者baybe我错了,人们以其他方式解决了这个问题。

以上是关于如何在 Cloudformation 脚本执行期间将 Cognito UserPoolID、客户端密码传递给 AWS Lambda?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CloudFormation 中启用 VirtualMFADevice?

如何通过 cloudformation 部署 opsworks 应用程序?

如何检查 CloudFormation 脚本中是不是已存在特定资源

具有资源属性 CloudFormation 的 UserData 脚本

terraform 中的任务执行 IAM 角色

如何知道 sam/cloudformation 堆栈 lambda 正在执行啥