3

我正在设置要通过 Codepipeline -> Cloudformation 部署的 Java AWS lambda 函数,并且在使用 Cloudformation 时遇到了一些困难。我以前使用过 Terraform,所以我了解一般概念......

澄清一下,我的代码存放在 Codecommit 存储库中,一切都由 Codestar 设置,因此它创建了一个具有单阶段、两步部署(生成变更集,执行变更集)的 Codepipeline。

目前,我只是标记 Codestar 在存储库中创建的示例 template.yml 文件,因此是 HelloWorld 引用。

除了 template.yml 文件之外,我还有一个用于 Codebuild 的 buildspec.yml 文件,尽管构建过程已成功完成。

下面是我的 template.yml cloudformation 脚本。Codepipeline 部署阶段中的 ChangeSet 步骤成功完成,但是 ExecuteChangeset 步骤失败,并显示“未提供原因”(超级有用)。单击详细信息链接将我带到 Cloudformation 页面以执行实际上不显示任何错误的步骤。它显示了一些我希望看到的添加/删除步骤,尽管并不是我认为需要发生的所有步骤。如果我单击“执行”,则会失败并出现以下错误:

Error: Failed to execute change set: ChangeSet [arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/awscodestar-test2-lambda/07e71ee0-6a73-11e7-bee5-50d5cd24fac6] cannot be executed in its current execution status of [EXECUTE_FAILED]

我在这里做错了什么?我没有很好地掌握 Fn::GetAtt 调用,但我已经尝试了几种不同的方法,但没有任何乐趣。

**除了找出问题所在之外,我还有两个问题:

  1. 请解释我应该在 Fn::GetAtt 函数调用中究竟引用什么?是我在尝试调用的资源顶部提供的资源名称(例如 GetHelloWorld)吗?还是作为该资源的属性提供的显式名称(即 FunctionName)?

  2. 在 Lambda 函数声明中,我尝试在线设置事件触发器,然后需要引用 Lambda 函数。我可以从嵌套在 Lambda 函数资源中的事件声明中引用 Lambda 函数资源吗?

下面是我的 template.yml 文件。

AWSTemplateFormatVersion: 2010-09-09
Transform:
- AWS::Serverless-2016-10-31
- AWS::CodeStar

Parameters:
  ProjectId:
    Type: String
    Description: AWS CodeStar projectID used to associate new resources to team members

Resources:
  RoleForLambda:
    Type: "AWS::IAM::Role"
    Properties: 
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement: 
          - Effect: "Allow"
            Principal: 
              Service: "lambda.amazonaws.com"
            Action: "sts:AssumeRole"
      Policies:
      - PolicyName: s3put
        PolicyDocument:
          Version: "2012-10-17"
          Statement:
          - Effect: "Allow"
            Action:
            - 'logs:CreateLogGroup'
            - 'logs:CreateLogStream'
            - 'logs:PutLogEvents'
            - 's3:PutObject'
            Resource: 
            - 'arn:aws:logs:*:*:*'
            - 'arn:aws:s3:*'
  GetHelloWorld:
    Type: AWS::Serverless::Function
    Properties:
      Handler: com.aws.codestar.projecttemplates.handler.HelloWorldHandler
      Runtime: java8
      Timeout: 60
      MemorySize: 256
      Role:
        'Fn::GetAtt':
          - RoleForLambda
          - Arn
    ScheduleRule:
      Type: 'AWS::Events::Rule'
      Properties:
        Name: DownloadFiles
        ScheduleExpression: 'cron(2,7,12,17,22,27,32,37,42,47,52,57 * * * ? *)'
        State: ENABLED
        Targets:
          - Arn: 
              'Fn::GetAtt':
                - GetHelloWorld
                - Arn
            Id: downloadFiles
    LambdaInvokePermission:
      Type: "AWS::Lambda::Permission"
      Properties: 
        Action: lambda:InvokeFunction
        FunctionName: GetHelloWorld
        Principal: events.amazonaws.com
        SourceAccount: AWS::XXXXXXXXXXXX
        SourceArn:
          - Arn:
              'Fn::GetAtt':
                - ScheduleRule
                - Arn
4

2 回答 2

4

以防其他人遇到类似问题。原来,我有一些语法错误,我敢肯定,还有其他问题......这是一个工作模板。

AWSTemplateFormatVersion: 2010-09-09
Description: >-
  This Lambda function does something
Parameters:
  ProjectId:
    Description: AWS CodeStar projectID used to associate new resources to team members
    Type: String
Resources:
  DownloadRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Sid: ''
            Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: 'sts:AssumeRole'
      Policies:
        - PolicyName: PutS3Policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                  - 's3:PutObject'
                  - 's3:PutObjectAcl'
                  - 's3:PutObjectTagging'
                  - 'sns:Publish'
                Resource:
                  - 'arn:aws:logs:*:*:*'
                  - 'arn:aws:s3:::myBucket'
                  - 'arn:aws:s3:::myBucket/*'
                  - 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:SNS_TOPIC'
      Path: /
  DownloadFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      Handler: 'com.mycompany.download.LambdaFunction::lambdaHandler'
      MemorySize: '256'
      Description: A scheduled Lambda function
      FunctionName: Download
      Role: !GetAtt 
        - DownloadRole
        - Arn
      Runtime: java8
      Timeout: '60'
    DependsOn:
      - DownloadRole
  ScheduleRule:
    Type: 'AWS::Events::Rule'
    Properties:
      Name: DownloadFiles
      ScheduleExpression: 'cron(2,7,12,17,22,27,32,37,42,47,52,57 * * * ? *)'
      State: ENABLED
      Targets:
        - Arn: !GetAtt 
            - DownloadFunction
            - Arn
          Id: DownloadFiles
    DependsOn:
      - DownloadFunction
  LambdaInvokePermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      FunctionName: !GetAtt 
        - DownloadFunction
        - Arn
      Action: 'lambda:InvokeFunction'
      Principal: events.amazonaws.com
      SourceArn: !GetAtt 
        - ScheduleRule
        - Arn
    DependsOn:
      - DownloadFunction
      - ScheduleRule
于 2017-07-23T20:28:12.153 回答
1

也许不是完全相同的问题这是我们的错误消息:

调用 ExecuteChangeSet 操作时发生错误 (InvalidChangeSetStatus):ChangeSet [arn:aws:cloudformation:....] 在其当前执行状态 [OBSOLETE] 下无法执行

为了解决这个问题,我只是重新运行了相同的 Cloudformation 脚本。很奇怪——这个问题发生在所有环境(DEV、TETS 和 PROD)中,并且在所有 3 种情况下都发生了相同的步骤。

于 2021-09-22T10:03:10.237 回答