Unresolved Dependencies error when creating Beanstalk Env with shared load balancer in CloudFormation

0

I'm trying to create a Beanstalk Environment in CloudFormation that will use an existing shared application load balancer, rather than one created by Beanstalk.

Unfortunately I get an error in Beanstalk suggesting that I'm not referencing the load balancer correctly.

Service:AmazonCloudFormation, Message:Template format error: Unresolved resource dependencies [AWSEBV2LoadBalancer] in the Resources block of the template

ElasticBeanstalk events

In my CloudFormation template I have the following:

Resources:
  ConfigurationTemplate:
  Type: AWS::ElasticBeanstalk::ConfigurationTemplate
  Properties:
    ApplicationName: !ImportValue
      Fn::Sub: "${ApplicationStackName}-ApplicationName"
    SolutionStackName: !Ref StackType
    OptionSettings:
        - Namespace: aws:elasticbeanstalk:environment
           OptionName: EnvironmentType
           Value: LoadBalanced
        - Namespace: aws:elasticbeanstalk:environment
           OptionName: LoadBalancerIsShared
           Value: true
        - Namespace: aws:elasticbeanstalk:environment
          OptionName: LoadBalancerType
          Value: application
        - Namespace: aws:elbv2:loadbalancer
          OptionName: SharedLoadBalancer
          Value:
            Fn::ImportValue: !Sub "${SharedLoadBalancerStackName}-LoadBalancer-Arn"

I have double-checked and the export is available where we're importing it from. Any idea why I would be getting the load balancer-related error in Beanstalk?

For completeness, and in case I'm misunderstanding, I'm using instructions from [1], and [2] to try add a listener to the load balancer from the Beanstalk CloudFormation template but the Lambda doesn't get executed so I guess we don't make it this far.

  LambdaBasicExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess
        - arn:aws:iam::aws:policy/AWSElasticBeanstalkReadOnly
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  GetEBLBTargetGroupResource:
    Type: Custom::GetEBLoadBalancerArn
    Properties:
      ServiceToken: !GetAtt GetEBLBTargetGroupLambda.Arn
      EBEnvName: !Ref Environment

  # Query EB for its first load balancer's ARN
  GetEBLBTargetGroupLambda:
    Type: AWS::Lambda::Function
    Properties:
      Description: Get ARN of ElasticBeanstalk load balancer
      Handler: index.handler
      Timeout: 30
      Role: !GetAtt 'LambdaBasicExecutionRole.Arn'
      Runtime: nodejs12.x
      Code:
        ZipFile: |
          const AWS = require('aws-sdk');
          const cfnResponse = require('cfn-response');
          const eb = new AWS.ElasticBeanstalk();
          const cfn = new AWS.CloudFormation();
          
          exports.handler = (event, context) => {
            if (event['RequestType'] !== 'Create') {
              console.log(event['RequestType'], 'is not Create');
              return cfnResponse.send(event, context, cfnResponse.SUCCESS, {
                Message: `${event['RequestType']} completed.`,
              });
            }
          
            eb.describeEnvironmentResources(
              { EnvironmentName: event['ResourceProperties']['EBEnvName'] },
              function (err, { EnvironmentResources }) {
                if (err) {
                  console.log('Exception', err);
                  return cfnResponse.send(event, context, cfnResponse.FAILED, {});
                }
          
                const PhysicalResourceId = EnvironmentResources['AutoScalingGroups'].find(
                  (group) => group.Name
                )['Name'];
          
                const { StackResources } = cfn.describeStackResources(
                  { PhysicalResourceId },
                  function (err, { StackResources }) {
                    if (err) {
                      console.log('Exception', err);
                      return cfnResponse.send(event, context, cfnResponse.FAILED, {});
                    }
                    const TargetGroup = StackResources.find(
                      (resource) => resource.LogicalResourceId === 'AWSEBV2LoadBalancerTargetGroup'
                    );
          
                    cfnResponse.send(event, context, cfnResponse.SUCCESS, {
                      TargetGroupArn: TargetGroup.PhysicalResourceId,
                    });
                  }
                );
              }
            );
          }

  ListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Priority: 1
      ListenerArn:
        Fn::ImportValue: !Sub '${SharedLoadBalancerStackName}-Listener-Arn'
      Actions:
        - Type: forward
          TargetGroupArn:
            Fn::GetAtt: [ 'GetEBLBTargetGroupResource', 'TargetGroupArn' ]
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values: [ '/*' ]

[1] https://stackoverflow.com/questions/67322501/cloudformation-elasticbeanstalk-specify-target-group-for-shared-load-balancer

[2] https://stackoverflow.com/questions/65677754/awswafv2webaclassociation-resourcearn-for-application-load-balancer-in-cloud/65729457#65729457

1 Antwort
0
Akzeptierte Antwort

It's because I had an ebextension that referenced AWSEBV2LoadBalancer.

beantwortet vor einem Jahr

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen