azure-devops - 在 Azure DevOps Pipelines 中分配 AWS Cloudformation 输出变量

标签 azure-devops continuous-integration aws-cloudformation azure-pipelines continuous-deployment

我的团队正在使用 Azure Devops 管道将 Cloudformation 堆栈部署到 AWS。我们有可重复使用的通用 Cloudformation 模板(例如,可重复使用单个 Lambda.yml Cloudformation 模板来部署多个 Lambda 函数)。

除此之外,我还设置了一个步骤函数来编排逻辑流。步骤函数步骤需要引用基础设施各个部分的 ARN(在本例中,重点关注 lambda 函数)。

由于 Lambda.yml 被重用,因此每次任务重用模板来部署新的 lambda 时,输出变量都会被覆盖。我想在 Azure Devops 中的变量或参数中捕获每个任务后的输出。我查看了许多示例和有关变量的文档,但无法使其正常工作。此处列出了 Cloudformation 模板和部署脚本的相关部分(YAML 格式)。

Lambda.yml(Cloudformation 模板)

AWSTemplateFormatVersion: '2010-09-09'
Description: Template for Lambda function.
Parameters:
  FunctionName: 
    Description: The name of the Lambda function
    Type: String

Resources:
  LambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: !Ref FunctionName
.....

Outputs:
  LambdaFunctionName:
    Description: Lambda function name
    Value: !Ref LambdaFunction
  LambdaFunctionARN:
    Description: Lambda ARN
    Value: 
      Fn::GetAtt:
        - LambdaFunction
        - Arn

Deploy.yml(Azure Devops 管道部署)

# Deploy.yml is a series of deployment tasks called from a job/stage defined in another.yml file
# LambdaFunctionNumber1
- task: AmazonWebServices.aws-vsts-tools.CloudFormationCreateOrUpdateStack.CloudFormationCreateOrUpdateStack@1
  displayName: 'Stack: LambdaFunctionNumber1'
  inputs:
    templateSource: s3
    s3BucketName: ${{ parameters.azdoS3ArtifactBucket }}
    s3ObjectKey: '${{ parameters.azdoS3ArtifactPrefix }}/cfn/Lambda.yml'
    templateParametersSource: inline
    templateParameters: |
     -
         ParameterKey: FunctionName
         ParameterValue: LambdaFunctionNumber1
    ....
    captureStackOutputs: asVariables

# I would like to capture Cloudformation output variables here for use in other tasks
# variables lambdaNumberOneFunctionName and lambdaNumberOneFunctionArn are defined as variables by the job triggering these deployment tasks, and initialized to empty strings
- bash:
    echo "##vso[task.setvariable variable=lambdaNumbertOneFunctionName;isOutput=true]$LAMBDAFUNCTIONNAME"
    echo "##vso[task.setvariable variable=lambdaNumberOneFunctionArn;isOutput=true]$LAMBDAFUNCTIONARN"

# LambdaFunctionNumber2
- task: AmazonWebServices.aws-vsts-tools.CloudFormationCreateOrUpdateStack.CloudFormationCreateOrUpdateStack@1
  displayName: 'Stack: LambdaFunctionNumber2'
  inputs:
    templateSource: s3
    s3BucketName: ${{ parameters.azdoS3ArtifactBucket }}
    s3ObjectKey: '${{ parameters.azdoS3ArtifactPrefix }}/cfn/Lambda.yml'
    templateParametersSource: inline
    templateParameters: |
     -
         ParameterKey: FunctionName
         ParameterValue: LambdaFunctionNumber2
    ....
    captureStackOutputs: asVariables

# At this point the $(LambdaFunctionARN) output variable is set from Cloudformation of LambdaFunctionNumber2. 
# The ARN from LambdaFunctionNumber1 is lost unless I capture it somehow.
# I need multiple ARNs to provide as input to the Step Function that gets deployed here
- task: AmazonWebServices.aws-vsts-tools.CloudFormationCreateOrUpdateStack.CloudFormationCreateOrUpdateStack@1
  displayName: 'Stack: Step Function'
  inputs:
    stackName:step-function
    templateSource: s3
    s3BucketName: ${{ parameters.azdoS3ArtifactBucket }}
    s3ObjectKey: '${{ parameters.azdoS3ArtifactPrefix }}/cfn/StepFunction.yml'
    ....

    templateParametersSource: inline
    templateParameters: |
     -
         ParameterKey: StateMachineName
         ParameterValue: orchestration-step-function
     -
         # This doesn't work
         ParameterKey: State1LambdaArn
         ParameterValue: $[lambdaNumberOneFunctionArn]
     -
         # This works but only allows capturing the most recent output variable
         ParameterKey: State2LambdaArn
         ParameterValue: $(LambdaFunctionARN)

最佳答案

您可以尝试命名设置变量的步骤,然后使用步骤名称作为变量名称的一部分。您甚至可以将变量名称定义为模板参数,这样每次您都会获得唯一的名称。在代码中它可能看起来像这样:

模板.yaml

parameters:
- name: name
  type: string
  default: 'lambdaNumbertOneFunctionName'
- name: arn
  type: string
  default: 'lambdaNumberOneFunctionArn'
- name: stepName
  type: string
  default: 'StepOne'
- name: value
  type: string
  default: 'testValue'

steps:
- bash: |
    echo "##vso[task.setvariable variable=${{ parameters.name }};isOutput=true]${{ parameters.value }}"
    echo "##vso[task.setvariable variable=${{ parameters.arn }};isOutput=true]${{ parameters.value }}"
    echo "##vso[task.setvariable variable=Test;isOutput=true]${{ parameters.value }}"
    echo "##vso[task.setvariable variable=Test2;isOutput=true]Yesy2"
  name: ${{ parameters.stepName }}

- script: |
    echo $(${{ parameters.stepName }}.${{ parameters.name }})
    echo $(${{ parameters.stepName }}.${{ parameters.arn }})
    echo $(${{ parameters.stepName }}.Test)
    echo $(${{ parameters.stepName }}.Test2)

和主文件

jobs:
- job: myJob
  timeoutInMinutes: 10
  pool:
    vmImage: 'ubuntu-16.04'
  steps:
  - template: template.yaml
    parameters:
      name: 'lambdaNumbertOneFunctionName'
      arn: 'lambdaNumberOneFunctionArn'
      value: 'value-1'
      stepName: 'StepOne'
  - template: template.yaml
    parameters:
      name: 'lambdaNumberTwoFunctionName'
      arn: 'lambdaNumberTwoFunctionArn'
      value: 'value-2'
      stepName: 'StepTwo'
  - script: |
      echo 'lambdaNumbertOneFunctionName - $(StepOne.lambdaNumbertOneFunctionName)'
      echo 'lambdaNumberOneFunctionArn - $(StepOne.lambdaNumberOneFunctionArn)'
      echo 'lambdaNumberTwoFunctionName - $(StepTwo.lambdaNumberTwoFunctionName)'
      echo 'lambdaNumberTwoFunctionArn - $(StepTwo.lambdaNumberTwoFunctionArn)'

为此我得到了:

lambdaNumbertOneFunctionName - value-1
lambdaNumberOneFunctionArn - value-1
lambdaNumberTwoFunctionName - value-2
lambdaNumberTwoFunctionArn - value-2

我希望我理解您和您的问题并解决它:)

关于azure-devops - 在 Azure DevOps Pipelines 中分配 AWS Cloudformation 输出变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63959555/

相关文章:

amazon-web-services - 如何配置对 Elastic beanstalk Cloudformation 模板的 ECR 读取访问权限?

Azure DevOps 管道无法识别 Bash 脚本中的管道变量(不使用 YAML 文件)

entity-framework - CI 构建服务器上的 EF 迁移

amazon-web-services - 如何将 AWS Nitro Enclave 与 ECS 结合使用?

Delphi Tokyo 10.2 的 Powershell 静默/无人值守安装 - 用于在 win docker 容器中使用 CI

java - 如何停止 CruiseControl 构建或更改配置以导致长时间运行的构建超时?

amazon-web-services - 如何在 Cloudformation 模板条件中使用 AWS SSM 参数存储值?

visual-studio - 有没有办法轻松共享 Visual Studio Online/Team Foundation Server 的工作区设置(文件夹映射)?

azure - 在 Azure Pipelines 中用 FileTransform@1 替换变量时,可以采取哪些步骤来修复 InvalidRequestContent 错误?

build - Visual Studio Team Services 并使用排除文件夹删除文件(任务构建)