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

Import and use an existing certificate for my domain. #2694

Closed
makies opened this issue Aug 4, 2021 · 9 comments · Fixed by #3503
Closed

Import and use an existing certificate for my domain. #2694

makies opened this issue Aug 4, 2021 · 9 comments · Fixed by #3503
Labels
size/M We should be able to deliver roughly 1 medium issue in a sprint. type/feature Issues that are new feature requests. type/request Issues that are created by customers.

Comments

@makies
Copy link

makies commented Aug 4, 2021

I have a wildcard SSL certificate on AWS ACM. When deploying, copilot does not use this certificate, creates another certificate and attempts DNS authentication, but it is not authenticated.

We want to import and use an existing certificate for my domain.

(Japanese)
AWSのACMでワイルドカードのSSL証明書を保持しています。デプロイする時に、copilotは、この証明書を使わずに、別な証明書を作成し、DNS認証を試みますが、それは認証されません。

独自ドメインの既存の証明書をインポートして使いたいです。

@efekarakus efekarakus added size/M We should be able to deliver roughly 1 medium issue in a sprint. type/feature Issues that are new feature requests. type/request Issues that are created by customers. labels Aug 4, 2021
@efekarakus
Copy link
Contributor

Hi @makies ! Thank you for the feature request, it makes a lot of sense.

@iamhopaul123 on the team had started on this feature before 😬 #2413
We should be able to resurrect the changes 🧟 and continue from there!

@heyheman11
Copy link

+1 on this issue, seems very hacky to get containers running over https if your domain isn't currently hosted on AWS

@chriskuech
Copy link

@heyheman11 , were you ever able to get https containers running without hosting the domain on AWS? I'm desperate for a solution. It seems as though we cannot use a reverse proxy container as the healthchecks are http and only one port is supported.

@heyheman11
Copy link

@chriskuech I followed the instructions from a previous reply from the team at AWS but here is a brief overview of what I did:

1. Ensure manifest.yml looks something like this (ensure container only exposes port 80):

http:
  path: "/"
  healthcheck:
    path: "/health_check/"
    success_codes: "200"

image:
  build:
    context: ./project
    dockerfile: ./project/Dockerfile
  port: 80

2. Create a certificate in ACM or import an exisiting one for the desired domain

3. Create a new listener rule on the existing load balancer that listens on port 443, use the certificate from step 2 and copy all rules from the existing rule.

4. Go to your DNS provider and create a new CNAME record to point to the ELB address

Essentially the https connection is terminated at the listener, and my server in the container only listens for http traffic on port 80.

@chriskuech
Copy link

This seems to be a valid template snippet for what you are describing and it passes a linter, but fails in cloudformation with a "AWS::ElasticLoadBalancingV2::ListenerRule Validation exception", but doesn't seem to show anywhere what the actual validation issue is.

Any idea what I'm doing wrong?

  HttpsListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      Certificates:
        - CertificateArn: !FindInMap [EnvMap, !Ref Env, CertificateArn]
      DefaultActions:
        - Type: forward
          ForwardConfig:
            TargetGroupStickinessConfig:
              Enabled: false
            TargetGroups:
              - TargetGroupArn:
                  !FindInMap [EnvMap, !Ref Env, LoadBalancerDefaultTargetArn]
                Weight: 1
          TargetGroupArn:
            !FindInMap [EnvMap, !Ref Env, LoadBalancerDefaultTargetArn]
      LoadBalancerArn: !FindInMap [EnvMap, !Ref Env, LoadBalancerArn]
      Port: 443
      Protocol: HTTPS

  HttpsListenerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - Type: forward
          ForwardConfig:
            TargetGroupStickinessConfig:
              Enabled: false
            TargetGroups:
              - TargetGroupArn:
                  !FindInMap [EnvMap, !Ref Env, LoadBalancerRouteTargetArn]
                Weight: 1
          TargetGroupArn:
            !FindInMap [EnvMap, !Ref Env, LoadBalancerRouteTargetArn]
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values:
              - /*
          Values:
            - /*
      ListenerArn: !Ref HttpsListener
      Priority: 50000

@heyheman11
Copy link

@chriskuech sorry I did this all through the console, I didn't need to cloudformation scripts. Maybe posting this on stack overflow might help as it seems like a general cloudformation question

@sugarjig
Copy link

sugarjig commented Dec 6, 2021

@chriskuech I tried a similar solution a few months ago, but the issue was the target group's ARN is not exposed as an output by Copilot. See #2642.

@matthewhembree
Copy link

Clarification:
I am not a decision maker for this project, but I am curious about this use case.

Question:
Why would you want to use an existing certificate?

If it's due to non Route 53 hosted domains, that seems like it involves various hacks to use Copilot currently with that constraint. I would just delegate a Copilot specific subdomain, but you'd lose out on http.alias functionality. Which is probably the main blocker for everyone here.

Other potential use cases:

  • Desire to use ACM Private CA certificates: I'm curious about the intersection of ACM Private CA users and Copilot users. Would that be a GovCloud use-case?
  • Desire to use a certificate obtained from a third party that is imported into ACM: In my industry (financial), we have a business partner that opposes Domain Validated certificates and require Organization Validated certificates for endpoints that they connect to. They also oppose wildcard certificates.
  • Desire to use a certificate that was created with certificate transparency logging disabled: This is useful if you are deploying non-browser accessed services (e.g. backend APIs that are fronted by a BFF (Lambda@Edge / Etc.)). I like disabling CTL on these because it reduces OSINT that a bad actor could use to create a list of endpoints to target. It also is beneficial if you're developing a product or service that you are not ready to make a public announcement about.

IMO, wildcard certificates are generally not an ideal practice. There is no limitation on the blast radius of a key compromise or a certificate expiration. These two points are mostly non-issues for ACM generated certificates as it controls the keys and manages renewal. Which is why I think Copilot environment level wildcard certificates are acceptable for most cases.

Question:
Would any organization have a need for service level (non-wildcard) certificates?

I would guess the demand for this is low.

Question:
How are organizations handling this currently?

I read some of the workarounds above. Organizations that have that requirement could:

  • An API Gateway httpapi (AWS::ApiGatewayV2::Api) as a reverse proxy in front of a Copilot service to accomplish this. This would work easily with a Copilot dedicated Route 53 zone, delegated off of your non-Route 53 zone. I think it's even possible as an add-on, based on the parameters being passed.
  • A load balancer managed out of band of the Copilot toolchain
  • Through the use a Copilot managed NLB and terminating the TLS connection in the container with cert/key pair in the image (or mounted through EFS or passed as an environment variable).

@iamhopaul123 iamhopaul123 pinned this issue Apr 7, 2022
mergify bot pushed a commit that referenced this issue Apr 19, 2022
part of #2694


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
mergify bot pushed a commit that referenced this issue Apr 21, 2022
Part of #2694


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
mergify bot pushed a commit that referenced this issue Apr 26, 2022
Related #2694. Specifically, instead of grabbing DNS info from env parameters, we now describe the listener rule for it.


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
@mergify mergify bot closed this as completed in #3503 Apr 29, 2022
mergify bot pushed a commit that referenced this issue Apr 29, 2022
Resolves #2694


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the Apache 2.0 License.
@huanjani
Copy link
Contributor

huanjani commented May 9, 2022

The feature is now released in v1.18.0: https://github.com/aws/copilot-cli/releases/tag/v1.18.0! 🎉

@efekarakus efekarakus unpinned this issue May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/M We should be able to deliver roughly 1 medium issue in a sprint. type/feature Issues that are new feature requests. type/request Issues that are created by customers.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants