Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_cdk.aws_route53_targets: ElasticBeanstalkEnvironmentEndpointTarget throwing an error #17992

Closed
agusavior opened this issue Dec 13, 2021 · 6 comments
Labels
@aws-cdk/aws-route53-targets bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. effort/small Small work item – less than a day of effort p1

Comments

@agusavior
Copy link

agusavior commented Dec 13, 2021

What is the problem?

Creating a object of ElasticBeanstalkEnvironmentEndpointTarget is throwing a Exception.

I think this could be an bug because I'm just using this class in the way that it's supposed to be used.
This class receive an environment_endpoint, and that's what I give it to it.

Reproduction Steps

Just execute this with cdk deploy:

  # EB Enviroment
  enviroment = elasticbeanstalk.CfnEnvironment(self, 'Enviroment', 
      environment_name='MySampleEnviroment',
      application_name=application.application_name or application_name,
      solution_stack_name=SOLUTION_STACK_NAME,
      option_settings=self.get_option_setting_properties(),
      version_label=app_version_props.ref,
  )

  # Attach Domain to DNS Domain of the Load Balancer of the Enviroment
  route53.ARecord(self, f'{construct_label}AliasRecord',
      target=route53.RecordTarget.from_alias(
          targets.ElasticBeanstalkEnvironmentEndpointTarget(     # <-- Here is the problem
              enviroment.attr_endpoint_url,
          ),
      ),
      zone=domain_configuration.hosted_zone,
  )

What did you expect to happen?

I shouldn't have had an exception using that instance with the URL of the enviroment.

If I can't use that class with the url of the enviroment: Why that class exists.

I opened the link that appears on the exception but: That means that I can't do it without using the console? I want to use CDK and not the console.

What actually happened?

The exception:

jsii.errors.JSIIError: Cannot use an EBS alias as environmentEndpoint. You must find your EBS environment endpoint via the AWS console. See the Elastic Beanstalk developer guide: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customdomains.html

CDK CLI Version

2.1.0 (build f4f18b1)

Framework Version

No response

Node.js Version

v16.13.0

OS

Ubuntu 20.04 on WSL

Language

Python

Language Version

Python 3.7.2

Other information

I do not know how to create an AliasRecordTarget to point to my Load Balancer of my Elastic Beanstalk Enviroment.

I'm trying a lot of stuff.

I tried something like this: https://stackoverflow.com/questions/56164141/aws-cdk-how-to-target-an-elastic-beanstalk-environment-with-a-route53-alias-rec

But I couldn't do it with Python.

So I found out that there is a class ( ElasticBeanstalkEnvironmentEndpointTarget ) that seems to be right what I wanted.

Also: This is my first issue reported on GitHub. Sorry if I make a mistake with this.

@agusavior agusavior added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 13, 2021
@agusavior
Copy link
Author

agusavior commented Dec 13, 2021

I was reading the code. It's interesting.
I do not understand why the url has to be resolved.
I think it has to be resolved because you can't manipulate a string if it has tokens inside.
So, that gives me another question: Do I can workaround this by resolving the URL first?
In order to resolve it, I tried to add addDependsOn to the ARecord (to resolve frist the Enviroment with its url). But ARecord has no addDependsOn method.

@agusavior
Copy link
Author

[ Little bit off topic ]
Oh, I just realiced that Elastic Beanstalk has many problems with CDK because the enviroment of Elastic Beanstalk creates another Cloudformation template and creates a Stack for its own.

It were be nice if we could, in some way, reference the Stack and read all the resources of the Stack created by the enviroment of Elastic Beanstalk. The object of CfnEnviroment would has a function called "getStack" or something like that. That function would return the Stack created by the enviroment. Then, we would get the load balancer of the Stack. And then, with the load balancer we would create RecordTarget to point to the Load Balancer of that Stack.

Or shorter: A object of CfnEnviroment stores the URL of the load balancer, so: Why not store the Load Balancer ARN? So, we could get the load balancer and modify it.

MAYBE.

@njlynch njlynch added effort/small Small work item – less than a day of effort and removed needs-triage This issue or PR still needs to be triaged. labels Dec 30, 2021
@njlynch
Copy link
Contributor

njlynch commented Dec 30, 2021

This was noted in the initial implementation, but the original author didn't have the cycles to do the (more complicated) Token-safe implementation. The trick here is resolving the correct HostedZone for the correct region, based on the region from the (Elastic Beanstalk) environment. Contributions welcome!

@njlynch njlynch removed their assignment Dec 30, 2021
@nicfix
Copy link
Contributor

nicfix commented Feb 1, 2022

The current implementation has another problem as well.

Even if you create the beanstalk environment in advance (say in a previously run cdk deploy), and customize the CNAME_PREFIX, the ElasticBeanstalkEnvironmentEndpointTarget is not able to read correctly the region from the generated url.

Consider this scenario:

# app1.py
# EB Enviroment
enviroment = elasticbeanstalk.CfnEnvironment(self, 'Enviroment', 
    environment_name='MySampleEnviroment',
    application_name=application.application_name or application_name,
    solution_stack_name=SOLUTION_STACK_NAME,
    option_settings=self.get_option_setting_properties(),
    version_label=app_version_props.ref,
    cname_prefix='myapp'
)

This generates an elastic beanstalk environment with url myapp.eu-west-1.elasticbeanstalk.com (supposing one it's deploying in eu-west-1).

Then a following cdk app tries to create a DNS record for it

# app2.py
route53.ARecord(self, f'{construct_label}AliasRecord',
    target=route53.RecordTarget.from_alias(
        targets.ElasticBeanstalkEnvironmentEndpointTarget(     
            'myapp.eu-west-1.elasticbeanstalk.com',
        ),
    ),
    zone=domain_configuration.hosted_zone,
)

At this point the command cdk diff returns the following error:

jsii.errors.JSIIError: Elastic Beanstalk environment target is not supported for the "elasticbeanstalk" region.

Looking at the documentation ElasticBeanstalkEnvironmentEndpointTarget expects instead a URL similar to this:

myapp.xyz.eu-west-1.elasticbeanstalk.com

but the CNAME_PREFIX cannot contain . when created from cdk.

My guess is that the URL is split with . and then the 3rd group from the start is taken while it might be more robust to take the 3rd group from the end of the URL.

============

CDK CLI Version
2.10.0 (build e5b301f)

Framework Version
No response

Node.js Version
v14.18.3

OS
macOS 11.6

Language
Python

Language Version
Python 3.9.5

@altso
Copy link

altso commented Feb 11, 2022

Is there a workaround for this issue that could be used in .NET? I tried implementing IAliasRecordTarget but that didn't work and throws at runtime:

Unhandled exception. System.ArgumentException: Could not convert argument 'MyAliasRecordTarget' to Jsii (Parameter 'arguments')
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<>c__DisplayClass20_0.<ConvertArguments>b__0(Parameter parameter, Object frameworkArgument)
   at System.Linq.Enumerable.ZipIterator[TFirst,TSecond,TResult](IEnumerable`1 first, IEnumerable`1 second, Func`3 resultSelector)+MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& )
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeStaticMethod[T](Type type, Type[] parameterTypes, Object[] arguments, String methodName)
   at Amazon.CDK.AWS.Route53.RecordTarget.FromAlias(IAliasRecordTarget aliasTarget)

mergify bot pushed a commit that referenced this issue Mar 9, 2022
… elastic beanstalk environment endpoint target (#18804)

This PR fixes the extraction of the region name from a Elastic Beanstalk Environment URL generated with a custom CNAME_PREFIX.

The code is backward compatible with the regular URL

# Motivation

ElasticBeanstalkEnvironmentEndpointTarget is used to create an alias target for ElasticBeanstalk Environments that are already created and published for a certain region.

When creating an ElasticBeanstalk Environment is possible to configure a `cname_prefix` in order to have a "deterministic" url for the generated environment.

Normally the generated url looks like `mybeanstalkenvironment.xyz.eu-west-1.elasticbeanstalk.com`, however when the `cname_prefix` is specified the url loses the randomly generated hash and looks like `mycnameprefix.eu-west-1.elasticbeanstalk.com`.

In the custom `cname_prefix` scenario the `ElasticBeanstalkEnvironmentEndpointTarget` class fails with the following error:
```
jsii.errors.JSIIError: Elastic Beanstalk environment target is not supported for the "elasticbeanstalk" region.
```

I mentioned this problem also [here](#17992 (comment)), sorry for the double comment. This PR does not fix the original problem of that issue thread.

# How to reproduce
Consider this scenario:
```
# app1.py
# EB Enviroment
enviroment = elasticbeanstalk.CfnEnvironment(self, 'Enviroment', 
    environment_name='MySampleEnviroment',
    application_name=application.application_name or application_name,
    solution_stack_name=SOLUTION_STACK_NAME,
    option_settings=self.get_option_setting_properties(),
    version_label=app_version_props.ref,
    cname_prefix='myapp'
)
```

This generates an elastic beanstalk environment with url `myapp.eu-west-1.elasticbeanstalk.com` (supposing one it's deploying in eu-west-1).

Then a following cdk app tries to create a DNS record for it
```
# app2.py
route53.ARecord(self, f'{construct_label}AliasRecord',
    target=route53.RecordTarget.from_alias(
        targets.ElasticBeanstalkEnvironmentEndpointTarget(     
            'myapp.eu-west-1.elasticbeanstalk.com',
        ),
    ),
    zone=domain_configuration.hosted_zone,
)
```

At this point the command cdk diff returns the following error:
```
jsii.errors.JSIIError: Elastic Beanstalk environment target is not supported for the "elasticbeanstalk" region.
```

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
TheRealAmazonKendra pushed a commit to TheRealAmazonKendra/aws-cdk that referenced this issue Mar 11, 2022
… elastic beanstalk environment endpoint target (aws#18804)

This PR fixes the extraction of the region name from a Elastic Beanstalk Environment URL generated with a custom CNAME_PREFIX.

The code is backward compatible with the regular URL

# Motivation

ElasticBeanstalkEnvironmentEndpointTarget is used to create an alias target for ElasticBeanstalk Environments that are already created and published for a certain region.

When creating an ElasticBeanstalk Environment is possible to configure a `cname_prefix` in order to have a "deterministic" url for the generated environment.

Normally the generated url looks like `mybeanstalkenvironment.xyz.eu-west-1.elasticbeanstalk.com`, however when the `cname_prefix` is specified the url loses the randomly generated hash and looks like `mycnameprefix.eu-west-1.elasticbeanstalk.com`.

In the custom `cname_prefix` scenario the `ElasticBeanstalkEnvironmentEndpointTarget` class fails with the following error:
```
jsii.errors.JSIIError: Elastic Beanstalk environment target is not supported for the "elasticbeanstalk" region.
```

I mentioned this problem also [here](aws#17992 (comment)), sorry for the double comment. This PR does not fix the original problem of that issue thread.

# How to reproduce
Consider this scenario:
```
# app1.py
# EB Enviroment
enviroment = elasticbeanstalk.CfnEnvironment(self, 'Enviroment', 
    environment_name='MySampleEnviroment',
    application_name=application.application_name or application_name,
    solution_stack_name=SOLUTION_STACK_NAME,
    option_settings=self.get_option_setting_properties(),
    version_label=app_version_props.ref,
    cname_prefix='myapp'
)
```

This generates an elastic beanstalk environment with url `myapp.eu-west-1.elasticbeanstalk.com` (supposing one it's deploying in eu-west-1).

Then a following cdk app tries to create a DNS record for it
```
# app2.py
route53.ARecord(self, f'{construct_label}AliasRecord',
    target=route53.RecordTarget.from_alias(
        targets.ElasticBeanstalkEnvironmentEndpointTarget(     
            'myapp.eu-west-1.elasticbeanstalk.com',
        ),
    ),
    zone=domain_configuration.hosted_zone,
)
```

At this point the command cdk diff returns the following error:
```
jsii.errors.JSIIError: Elastic Beanstalk environment target is not supported for the "elasticbeanstalk" region.
```

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@github-actions
Copy link

This issue has not received any attention in 1 year. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added closing-soon This issue will automatically close in 4 days unless further comments are made. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Feb 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-route53-targets bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. effort/small Small work item – less than a day of effort p1
Projects
None yet
Development

No branches or pull requests

5 participants