我的团队正在使用 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/