Cloud Foundry service broker to manage AWS CloudFront, AWS ALBs and Let's Encrypt.
Like the cf-domain-broker, this broker combines the features of the cf-cdn-service-broker and the cf-domain-broker-alb. It provisions Let's Encrypt certificates for a given domain, and configures either AWS ALBs (created out-of-band) or an AWS CloudFront distribution (created by the broker) to use that certificate.
It's important to note this broker and it's configuration was designed first and foremost for AWS GovCloud, which has some limitations when it comes to global configurations. For example, Route53 is not avaialble in GovCloud as it's a global service, so while the domain broker can be deployed as a Cloud Foundry app in GovCloud, it still needs to cross the boundary into the AWS commercial cloud.
This also means the broker expects to use a different IAM user and configuration for ALBs and CloudFront distributions.
There's nothing preventing using AWS commercial resources (IAM users, ALBs, etc) where govcloud resources are expected, so a commercial-only deployment should be possible without any modification. Similarly, if CloudFront and Route53 were to be brought into govcloud, nothing would prevent using govcloud resources where commercial resources are expected.
When users request a domain service instance, this broker will validate some prerequisite DNS configuration then provision a Let's Encrypt certificate, an ELB and a CloudFront CDN, and wire them all up together.
We have some constraints that make the Let's Encrypt Challenge process "difficult":
HTTP01
with CloudFront gives us a chicken-and-egg problem, in that CloudFront
will not answer to a custom domain, even for HTTP, without verifying ownership
of that domain via a valid SSL
certificate:
If you want to use an alternate domain name with your CloudFront distribution, you must verify to CloudFront that you have authorized rights to use the alternate domain name. To do this, you must attach a valid certificate to your distribution, and make sure that the certificate comes from a trusted CA that is listed on the Mozilla Included CA Certificate List. CloudFront does not allow you to use a self-signed certificate to verify your authorized rights to use an alternate domain name.
We still need to fully investigate ALPN01
, and its support in CloudFront.
It's not clear if the ALPN01
certificate is a self-signed cert - if so, we'll
likely hit the same CloudFront limitation listed above.
Investigation pointers:
- CloudFront supports HTTP/2
- ALPN is the required SSL implementation for HTTP/2
- Dehydrate bash ACME client can generate ALPN certs.
We do not have access to or control over DNS for the application, so we cannot
automate the DNS01
challenge.
Because of these limitations, we have users create CNAME (or ALIAS) records pointing to records within our control. This allows us to validate the user's input ahead of time, hopefully reducing the number of failures at provision time. It also allows us to manage renewals using TXT records, which eliminates the S3 config from the previous iterations of the broker. Finally, it should make creating a process to change between CDN and ALB instances possible without risk of downtime.
Before creation, customers create a CNAME record for _acme-challenge.<their-domain>
pointed to _acme-challenge.<their-domain>.<our-configured-domain>
. This allows us to
update TXT records on their behalf, which in turn allows us to solve DNS-01 challenges for
them.
Before, during, or after provisioning, they add a CNAME record for <their-domain>
pointing
to <their-domain>.<our-configured-domain>
, which routes traffic to their site.
The Broker can be configured via the following environment variables:
Variable | |
---|---|
FLASK_ENV | Environment name for Flask |
SECRET_KEY | Flask secret key |
BROKER_USERNAME | Username for the broker |
BROKER_PASSWORD | Password for the broker |
DATABASE_ENCRYPTION_KEY | Key used to encrypt database storage |
ROUTE53_ZONE_ID | Zone ID of Route53 zone for hosted zone for DNS_ROOT_DOMAIN |
DNS_ROOT_DOMAIN | Intermediate domain users point their DNS to |
DEFAULT_CLOUDFRONT_ORIGIN | CloudFront origin used for instances that route to CF apps |
AWS_GOVCLOUD_REGION | Region to use for AWS govcloud services |
AWS_GOVCLOUD_SECRET_ACCESS_KEY | Access key for AWS govcloud services |
AWS_GOVCLOUD_ACCESS_KEY_ID | Access key ID for AWS govcloud services |
AWS_COMMERCIAL_REGION | Region to use for commercial AWS services |
AWS_COMMERCIAL_SECRET_ACCESS_KEY | Access key for commercial AWS services |
AWS_COMMERCIAL_ACCESS_KEY_ID | Access key ID for commercial AWS services |
ALB_LISTENER_ARNS | comma-separated list of ARNs for AWS ALB Listeners to use |
DEDICATED_ALB_LISTENER_ARNS | comma-separated list listener ARNs for dedicated instances |
SMTP_HOST | Hostname of SMTP server (for alerts) |
SMTP_PORT | Port for SMTP server (for alerts) |
SMTP_CERT | Certificate chain to trust for SMTP server (for alerts) |
SMTP_USER | Username for authentication with SMTP server (for alerts) |
SMTP_PASS | Password to use for SMTP server (for alerts) |
SMTP_FROM | Email address to send emails from (for alerts) |
SMTP_TO | Email address to send alert emails to |
As this broker manages ELBs, IAM Certificates, CloudFront and other AWS resources, it requires an IAM policy that allows access to those APIs. We've provided a sample govcloud policy and a sample commercial policy, but you're responsible for auditing your own security policies. No warranty, etc, etc.
This broker leverages Concourse for its deployment
automation, but it's not dependent on it. You can find example and live
concourse configuration files in the ci/
directory.
This broker supersedes the cf-domain-broker, the cf-cdn-service-broker and the cf-domain-broker-alb.