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

Make hosted_zone_id optional, code update #812

Merged
merged 3 commits into from
Oct 27, 2023
Merged

Make hosted_zone_id optional, code update #812

merged 3 commits into from
Oct 27, 2023

Conversation

lorchda
Copy link
Contributor

@lorchda lorchda commented Oct 17, 2023

Feature or Bugfix

  • Bugfix

Detail

  • Make hosted_zone_id optional, code update

Relates

Security

Please answer the questions below briefly where applicable, or write N/A. Based on
OWASP 10.

  • Does this PR introduce or modify any input fields or queries - this includes
    fetching data from storage outside the application (e.g. a database, an S3 bucket)? N/A
    • Is the input sanitized? N/A
    • What precautions are you taking before deserializing the data you consume? N/A
    • Is injection prevented by parametrizing queries? N/A
    • Have you ensured no eval or similar functions are used? N/A
  • Does this PR introduce any functionality or component that requires authorization? N/A
    • How have you ensured it respects the existing AuthN/AuthZ mechanisms? N/A
    • Are you logging failed auth attempts? N/A
  • Are you using or adding any cryptographic features? N/A
    • Do you use a standard proven implementations? N/A
    • Are the used keys controlled by the customer? Where are they stored? N/A
  • Are you introducing any new policies/roles/users? N/A
    • Have you used the least-privilege principle? How? N/A

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. YES

Description

Make hosted_zone_id optional and provide HostedZoneId and DNSName in CloudFormation Stack Output, so users can create their own Route53 AliasTarget.

Following validation checks in ecs_patterns.ApplicationLoadBalancedFargateService were considered:

  • frontend_alternate_domain and userguide_alternate_domain have to be None when the hosted_zone is None, see checks in multiple-target-groups-service-base.ts#L463, or else a A Route53 hosted domain zone name is required to configure the specified domain name error is raised
  • for a HTTPS ALB listener, only the certificate is ultimately required, and not the domainName or domainZone, as per evaluation logic in application-load-balanced-service-base.ts#L509

@lorchda lorchda changed the title Make hosted_zone_id optional Make hosted_zone_id optional, code update Oct 17, 2023
@lorchda
Copy link
Contributor Author

lorchda commented Oct 17, 2023

This is what the documentation says for the parameters to ecs_patterns.ApplicationLoadBalancedFargateService:

  • domain_name (Optional[str]) – The domain name for the service, e.g. “api.example.com.”.
    Default: - No domain name.
  • domain_zone (Optional[IHostedZone]) – The Route53 hosted zone for the domain, e.g. “example.com.”.
    Default: - No Route53 hosted domain zone.

@dlpzx dlpzx self-requested a review October 23, 2023 08:45
@dlpzx
Copy link
Contributor

dlpzx commented Oct 23, 2023

Hi @lorchda, I am looking into this PR today. The albfront stack will only be deployed for VPC-facing frontend. In our documentation we specify that the custom_domain MUST be specified for this type of deployment. The reason behind this is the ALB integration with ACM.

image

From the code I think there is going to be an issue in lines 149-159:

        if custom_domain and custom_domain.get('certificate_arn'):
            certificate = acm.Certificate.from_certificate_arn(self, "CustomDomainCertificate",
                                                               custom_domain.get('certificate_arn'))
        else:
            certificate = acm.Certificate(
                self,
                'CustomDomainCertificate',
                domain_name=custom_domain['hosted_zone_name'],
                subject_alternative_names=[f'*.{custom_domain["hosted_zone_name"]}'],
                validation=acm.CertificateValidation.from_dns(hosted_zone=hosted_zone),
            )

If the ACM certificate is not provided, data.all tries to create a certificate. In the case no custom_domain is provided the hosted_zone is left as None and my guess is that the certificate creation is going to fail. For this PR to be merged we need an additional condition on the creation of the certificate to create it only when there is a custom domain. In addition we need to update the docs to clearly communicate that no certificate is created, which is a downgrade in security.

What are your thoughts? Also @noah-paige I would like your opinion on this

@lorchda
Copy link
Contributor Author

lorchda commented Oct 23, 2023

@dlpzx yes noticed that as well. My thinking was that custom_domain['hosted_zone_name'] would raise a not very descriptive KeyError along with a stack trace, but would otherwise abort as desired. This could be improved by providing a user-friendly error message that checks for the presence of custom_domain['hosted_zone_name'].

However, this is an unrelated issue that already existed before this PR. This PR is related only to hosted_zoned_id, and the semantics around hosted_zone_name (which must be provided) remains the same.

Example configuration:

    "DeploymentEnvironments": [
      {
        "internet_facing": false,
        "custom_domain": {
          "hosted_zone_name": "dataall.example.internal",
          "certificate_arn": "arn:aws:acm:REGION:ACCOUNT_ID:certificate/UID"
        }
        ...
      }
    ]

@lorchda
Copy link
Contributor Author

lorchda commented Oct 23, 2023

@dlpzx I am pretty sure that custom_domain['hosted_zone_name'] will abort with a KeyError and stacktrace, and not simply continue with deployment as you suggested. This reduces the problem to a cosmetic issue, where a more user-friendly error message could be provided in the absence of custom_domain['hosted_zone_name'], but the desired functionality is there. To be validated.

@lorchda
Copy link
Contributor Author

lorchda commented Oct 23, 2023

custom_domain['hosted_zone_name']
raises a KeyError when the key does not exist

custom_domain.get('hosted_zone_name')
returns None if the key does not exist

@dlpzx
Copy link
Contributor

dlpzx commented Oct 24, 2023

Hi @lorchda, thanks for the quick response. It is true that the certificate problem is more of a cosmetic issue, but based on our experience with customers we really need to provide an error message to users for them to understand the issue. This problem was not there before because custom_domain['hosted_zone_name'] was mandatory (at least in the documentation) for an internet_facing=false.

It is still unclear to me what your final architecture looks like. The target is to not provide any route53 zone or certificate and have the ALB defined without those optional parameters right? In your cdk.json the parameter "custom_domain" does not exist right?

@lorchda
Copy link
Contributor Author

lorchda commented Oct 24, 2023

@dlpzx I added a fix for this (unrelated) issue to check for custom_domain['hosted_zone_name']

@dlpzx
Copy link
Contributor

dlpzx commented Oct 26, 2023

Thank you @lorchda, the PR looks good. I will do a final test by deploying it to AWS and we can merge. I will test multiple scenarios to ensure backwards compatibility:

Scenario 1: pre-existing deployment. VPC-facing, with hosted zone ID

"internet_facing": false,
        "custom_domain": {
          "hosted_zone_name": "somedomain.dataall.com",
          "hosted_zone_id": "XXXXXXXXXXXXX",
          "certificate_arn": "arn:aws:acm:us-east-1:111111111111:certificate/xxxxxxxxxxxxxxx"
        },
  • tested, CICD and deployment is unaffected by the PR changes

Scenario 2: new deployment. VPC-facing, without hosted zone name

"internet_facing": false,
        "custom_domain": {
          "hosted_zone_id": "XXXXXXXXXXXXX",
          "certificate_arn": "arn:aws:acm:us-east-1:111111111111:certificate/xxxxxxxxxxxxxxx"
        },
  • It should fail at synthesis - It fails, but in a previously synthesized stack. Either way it fails, which is what we want.

image

Scenario 3: existing deployment. VPC-facing, without hosted zone ID

"internet_facing": false,
        "custom_domain": {
          "hosted_zone_name": "somedomain.dataall.com",
          "certificate_arn": "arn:aws:acm:us-east-1:111111111111:certificate/xxxxxxxxxxxxxxx"
        },
  • CICD and deployment successful (see the screenshot below with the albfront stack updated
  • Application working as expected

image

All good, @lorchda approving and merging! Thanks again

@dlpzx dlpzx changed the base branch from main to v2m1m0 October 27, 2023 06:53
@dlpzx dlpzx changed the base branch from v2m1m0 to main October 27, 2023 07:01
@dlpzx dlpzx changed the base branch from main to v2m1m0 October 27, 2023 07:01
@dlpzx dlpzx merged commit fb7b61b into data-dot-all:v2m1m0 Oct 27, 2023
9 checks passed
@dlpzx dlpzx added this to the v2.1.0 milestone Oct 30, 2023
@dlpzx dlpzx linked an issue Oct 30, 2023 that may be closed by this pull request
@dlpzx dlpzx removed this from the v2.1.0 milestone Oct 30, 2023
@dlpzx dlpzx mentioned this pull request Oct 30, 2023
anushka-singh pushed a commit to anushka-singh/aws-dataall that referenced this pull request Oct 31, 2023
### Feature or Bugfix
- Bugfix

### Detail
- Make `hosted_zone_id` optional, code update

### Relates
- data-dot-all#797 

### Security
Please answer the questions below briefly where applicable, or write
`N/A`. Based on
[OWASP 10](https://owasp.org/Top10/en/).

- Does this PR introduce or modify any input fields or queries - this
includes
fetching data from storage outside the application (e.g. a database, an
S3 bucket)? N/A
  - Is the input sanitized? N/A
- What precautions are you taking before deserializing the data you
consume? N/A
  - Is injection prevented by parametrizing queries? N/A
  - Have you ensured no `eval` or similar functions are used? N/A
- Does this PR introduce any functionality or component that requires
authorization? N/A
- How have you ensured it respects the existing AuthN/AuthZ mechanisms?
N/A
  - Are you logging failed auth attempts? N/A
- Are you using or adding any cryptographic features? N/A
  - Do you use a standard proven implementations? N/A
- Are the used keys controlled by the customer? Where are they stored?
N/A
- Are you introducing any new policies/roles/users? N/A
  - Have you used the least-privilege principle? How? N/A

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license. YES

### Description

Make `hosted_zone_id` optional and provide `HostedZoneId` and `DNSName`
in CloudFormation Stack Output, so users can create their own [Route53
AliasTarget](https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html).

Following validation checks in
`ecs_patterns.ApplicationLoadBalancedFargateService` were considered:
* `frontend_alternate_domain` and `userguide_alternate_domain` have to
be `None` when the `hosted_zone` is `None`, see checks in
[multiple-target-groups-service-base.ts#L463](https://github.com/aws/aws-cdk/blob/c445b8cc6e20d17e4a536f17262646b291a0fe36/packages/aws-cdk-lib/aws-ecs-patterns/lib/base/network-multiple-target-groups-service-base.ts#L463),
or else a `A Route53 hosted domain zone name is required to configure
the specified domain name` error is raised
* for a HTTPS ALB listener, only the `certificate` is ultimately
required, and not the `domainName` or `domainZone`, as per evaluation
logic in
[application-load-balanced-service-base.ts#L509](https://github.com/aws/aws-cdk/blob/c445b8cc6e20d17e4a536f17262646b291a0fe36/packages/aws-cdk-lib/aws-ecs-patterns/lib/base/application-load-balanced-service-base.ts#L509)
dlpzx added a commit that referenced this pull request Nov 8, 2023
### Feature or Bugfix
- Feature
- Bugfix
- Refactoring

### Detail

#### Features
* Limit pivot role S3 permissions by @dlpzx in
#780
* Limit pivot role KMS permissions by @dlpzx in
#830
* Add configurable session timeout to IDP by @manjulaK in
#786
* Allow to submit a share when you are both an approver and a requester
by @zsaltys in #793
* Redirect upon creating a share request by @zsaltys in
#799
* Handle Pre-filtering of tables by @anushka-singh in
#811
* Email Notification on Share Workflow - Issue - 734 by @TejasRGitHub in
#818
* Refactor notifications from core to modules by @dlpzx in
#822
* Add frontend and backend feature flags by @zsaltys in
#817
* Make hosted_zone_id optional by @lorchda in
#812

#### Fixes
* Add Additional Error Messages for KMS Key lookup on imported dataset
by @noah-paige in #748
* Handle Environment Import of IAM service roles by @noah-paige in
#749
* Build Compliant Names for Opensearch Resources by @noah-paige in
#750
* Update Lambda runtime by @nikpodsh in
#782
* Ensure valid environments for share request and other objects creation
by @dlpzx in #781
* Fix shell true semgrep by @dlpzx in
#760
* Add condition when there are no public subnets by @lorchda in
#794
* Remove unused variable by @zsaltys in
#815
* Check other share exists before clean up by @noah-paige in
#769


### Relates
- v2.1.0 minor release

## New Contributors
* @manjulaK made their first contribution in
#786
* @zsaltys made their first contribution in
#793
* @anushka-singh made their first contribution in
#811
* @TejasRGitHub made their first contribution in
#818

### Security
Please answer the questions below briefly where applicable, or write
`N/A`. Based on
[OWASP 10](https://owasp.org/Top10/en/).

- Does this PR introduce or modify any input fields or queries - this
includes
fetching data from storage outside the application (e.g. a database, an
S3 bucket)?
  - Is the input sanitized?
- What precautions are you taking before deserializing the data you
consume?
  - Is injection prevented by parametrizing queries?
  - Have you ensured no `eval` or similar functions are used?
- Does this PR introduce any functionality or component that requires
authorization?
- How have you ensured it respects the existing AuthN/AuthZ mechanisms?
  - Are you logging failed auth attempts?
- Are you using or adding any cryptographic features?
  - Do you use a standard proven implementations?
  - Are the used keys controlled by the customer? Where are they stored?
- Are you introducing any new policies/roles/users?
  - Have you used the least-privilege principle? How?


By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license.

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Noah Paige <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: jaidisido <[email protected]>
Co-authored-by: mourya-33 <[email protected]>
Co-authored-by: nikpodsh <[email protected]>
Co-authored-by: MK <[email protected]>
Co-authored-by: Zilvinas Saltys <[email protected]>
Co-authored-by: Daniel Lorch <[email protected]>
Co-authored-by: Anushka Singh <[email protected]>
Co-authored-by: trajopadhye <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make DNS alias record creation toggleable / optional
2 participants