如何使用 CloudFormation 成功检索 ALB ListenerArn 以设置 ListenerRules?

How do I successfully retrieve an ALB ListenerArn with CloudFormation to setup ListenerRules?

我开始认为与 "Type": "AWS::ElasticLoadBalancingV2::ListenerRule", 资源相关的 AWS Cloudformation 模板 validation/resource 查找存在根本缺陷。

具体来说,每次我尝试为已知的工作侦听器创建新的 ListenerRule 时,Cloudformation 都会出错

Unable to retrieve ListenerArn attribute for AWS::ElasticLoadBalancingV2::Listener, with error message One or more listeners not found (Service: ElasticLoadBalancingV2, Status Code: 400, Request ID: c6914f71-074c-4367-983a-bcf1d8fd1350, Extended Request ID: null)

经过测试,我可以通过在我的模板中硬编码 ListenArn 属性来使其工作,但这不是解决方案,因为该模板用于具有不同资源的多个堆栈。

以下是模板的相关部分:

    "WLBListenerHttp": {
      "Type": "AWS::ElasticLoadBalancingV2::Listener",
      "Properties": {
        "DefaultActions": [{
          "Type": "forward",
          "TargetGroupArn": { "Ref": "WLBTargetGroupHttp" }
        }],
        "LoadBalancerArn": { "Ref": "WebLoadBalancer" },
        "Port": 80,
        "Protocol": "HTTP"
      }
    },
    "ListenerRuleHttp": {
      "DependsOn": "WLBListenerHttp",
      "Type": "AWS::ElasticLoadBalancingV2::ListenerRule",
      "Properties": {
        "Actions": [{
          "Type": "fixed-response",
          "FixedResponseConfig": { "StatusCode": "200" }
        }],
        "Conditions": [{
          "Field": "host-header",
          "HostHeaderConfig": { "Values": ["domain*"] }
        }, {
          "Field": "path-pattern",
          "PathPatternConfig": { "Values": ["/path/to/respond/to"] }
        }],
        "ListenerArn": { "Fn::GetAtt": ["WLBListenerHttp", "ListenerArn"] },
        "Priority": 1
      }
    },

根据有关侦听器的文档,Fn::GetAtt 或 Ref 都应 return ListenerARN: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-elasticloadbalancingv2-listener.html

"Return 值 参考 当您将此资源的逻辑 ID 传递给内部 Ref 函数时,Ref return 是侦听器的 Amazon 资源名称 (ARN)。

有关使用 Ref 函数的详细信息,请参阅 Ref.

Fn::GetAtt Fn::GetAtt 内部函数 return 是此类型的指定属性的值。以下是可用的属性和示例 return 值。

有关使用 Fn::GetAtt 内部函数的详细信息,请参阅 Fn::GetAtt。

ListenerArn 侦听器的 Amazon 资源名称 (ARN)。

我试过 "ListenerArn": { "Fn::GetAtt": ["WLBListenerHttp", "ListenerArn"] },"ListenerArn": { "Ref": "WLBListenerHttp"}, 都没有成功,导致出现错误。如果我用完整的 Arn 硬编码 Arn "ListenerArn": "arn::",,它工作正常。

事实证明,我的语法完全没问题。然而,我没有意识到的是,虽然 WLBListenerHttp 资源存在,但它实际上与 CloudFormation 创建的 ARN 不同。显然,有人在不告诉我们的情况下在某个时候不小心删除了它,然后手动重新创建了它。这使帐户处于损坏状态,其中 CloudFormation 从创建时就为侦听器记录了一个 ARN,但它确实不再有效,因为新资源具有新的 ARN。

解决这个问题的方法是手动删除有问题的资源,然后在我们的 CloudFormation 模板中稍微更改它的名称,这样它就会创建一个新的。