Created
November 25, 2022 20:57
-
-
Save aldoborrero/907bfd9d0066980350ee807b1147a81b to your computer and use it in GitHub Desktop.
How to setup a Nix binary cache in DigitalOcean Spaces + CDN, with custom domain in Cloudflare with Terraform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
locals { | |
domain = "example.com" | |
} | |
data "cloudflare_zone" "domain" { | |
name = local.domain | |
} | |
resource "tls_private_key" "nix_store_origin_key" { | |
algorithm = "RSA" | |
rsa_bits = 2048 | |
} | |
resource "tls_cert_request" "nix_store_origin_cert" { | |
private_key_pem = tls_private_key.nix_store_origin_key.private_key_pem | |
subject { | |
common_name = "cache.${local.domain}" | |
organization = "Willy Wonka LTD" | |
country = "USA" | |
locality = "Los Angeles" | |
} | |
} | |
resource "cloudflare_origin_ca_certificate" "nix_store_origin_cert" { | |
# See: https://github.com/cloudflare/terraform-provider-cloudflare/issues/1919#issuecomment-1270722657 | |
provider = cloudflare.cf-user-service-auth | |
csr = tls_cert_request.nix_store_origin_cert.cert_request_pem | |
hostnames = ["cache.${local.domain}"] | |
request_type = "origin-rsa" | |
requested_validity = 365 | |
} | |
resource "digitalocean_certificate" "nix_store_origin_cert" { | |
name = "cf-origin-cert" | |
type = "custom" | |
private_key = tls_private_key.nix_store_origin_key.private_key_pem | |
leaf_certificate = cloudflare_origin_ca_certificate.nix_store_origin_cert.certificate | |
} | |
resource "digitalocean_cdn" "nix_store_cdn" { | |
origin = digitalocean_spaces_bucket.nix_store.bucket_domain_name | |
certificate_name = digitalocean_certificate.nix_store_origin_cert.name | |
custom_domain = "cache.${local.domain}" | |
} | |
resource "cloudflare_record" "nix_store_cache" { | |
name = "cache" | |
value = digitalocean_cdn.nix_store_cdn.endpoint | |
type = "CNAME" | |
ttl = 1 # Auto | |
proxied = true | |
zone_id = data.cloudflare_zone.domain.id | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Original article: https://aldoborrero.com/posts/how-to-setup-a-nix-binary-cache-with-terraform-in-digitalocean-and-cloudflare | |
resource "digitalocean_spaces_bucket" "nix_store" { | |
name = "nix-store" | |
region = "fra1" | |
acl = "private" | |
lifecycle_rule { | |
id = "ttl" | |
enabled = true | |
abort_incomplete_multipart_upload_days = 1 | |
expiration { | |
days = 30 | |
} | |
} | |
versioning { | |
enabled = true | |
} | |
} | |
# See: https://fzakaria.com/2021/08/12/a-nix-binary-cache-specification.html | |
# See `NixCacheInfo Schema` to understand each parameter https://fzakaria.github.io/nix-http-binary-cache-api-spec/#/ | |
resource "digitalocean_spaces_bucket_object" "nix_cache_info" { | |
region = digitalocean_spaces_bucket.nix_store.region | |
bucket = digitalocean_spaces_bucket.nix_store.name | |
content_type = "text/html" | |
key = "nix-cache-info" | |
content = <<EOF | |
StoreDir: /nix/store | |
WantMassQuery: 1 | |
Priority: 10 | |
EOF | |
} | |
# See: https://nixos.org/manual/nix/stable/package-management/s3-substituter.html#anonymous-reads-to-your-s3-compatible-binary-cache | |
resource "digitalocean_spaces_bucket_policy" "nix_cache_anonymous_reads" { | |
region = digitalocean_spaces_bucket.nix_store.region | |
bucket = digitalocean_spaces_bucket.nix_store.name | |
policy = jsonencode({ | |
"Id" : "DirectReads", | |
"Version" : "2012-10-17", | |
"Statement" : [ | |
{ | |
"Sid" : "AllowDirectReads", | |
"Action" : [ | |
"s3:GetObject", | |
"s3:GetBucketLocation" | |
], | |
"Effect" : "Allow", | |
"Resource" : [ | |
"arn:aws:s3:::${digitalocean_spaces_bucket.nix_store.name}", | |
"arn:aws:s3:::${digitalocean_spaces_bucket.nix_store.name}/*" | |
], | |
"Principal" : "*" | |
} | |
] | |
}) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
terraform { | |
required_providers { | |
cloudflare = { source = "cloudflare/cloudflare" } | |
digitalocean = { source = "digitalocean/digitalocean" } | |
tls = { source = "hashicorp/tls" } | |
} | |
} | |
## Special configuration for Cloudflare Provider | |
## Some resources like 'cloudflare_origin_ca_certificate' needs to use special tokens. With recent work | |
## performed on the new Cloudflare Provider, the suggested solution is to configure provider aliases. | |
## See more info: https://github.com/cloudflare/terraform-provider-cloudflare/issues/1919 | |
variable "CF_API_TOKEN" { | |
type = string | |
sensitive = true | |
} | |
variable "CF_API_USER_SERVICE_KEY" { | |
type = string | |
sensitive = true | |
} | |
provider "cloudflare" { | |
api_token = var.CF_API_TOKEN | |
} | |
provider "cloudflare" { | |
alias = "cf-user-service-auth" | |
api_user_service_key = var.CF_API_USER_SERVICE_KEY | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment