|
| 1 | +--- |
| 2 | +title: Cloudflare Certificate Pack |
| 3 | +description: Learn how to create and manage Cloudflare Advanced Certificate Packs for flexible SSL/TLS certificates with multiple Certificate Authorities and custom configurations. |
| 4 | +--- |
| 5 | + |
| 6 | +# Certificate Pack |
| 7 | + |
| 8 | +The Certificate Pack resource lets you create and manage [Cloudflare Advanced Certificate Packs](https://developers.cloudflare.com/api/resources/ssl/subresources/certificate_packs/) for flexible SSL/TLS certificates with multiple Certificate Authority options. |
| 9 | + |
| 10 | +**Important Requirements:** |
| 11 | +- **Advanced Certificate Manager (ACM) must be activated:** Before using Certificate Packs, you must activate ACM in your Cloudflare dashboard. Navigate to your domain > **SSL/TLS** > **Edge Certificates** and click **Activate** for Advanced Certificate Manager. This requires a $10/month subscription per domain. |
| 12 | +- Requires a paid Cloudflare plan (not available on Free plans) |
| 13 | +- Certificate provisioning can take up to 10 minutes |
| 14 | +- Most properties are immutable after creation (only `cloudflareBranding` can be updated) |
| 15 | + |
| 16 | +## Basic Example |
| 17 | + |
| 18 | +Create a basic certificate pack with Let's Encrypt for your domain. |
| 19 | + |
| 20 | +```ts |
| 21 | +import { Zone, CertificatePack } from "alchemy/cloudflare"; |
| 22 | + |
| 23 | +const zone = await Zone("my-zone", { |
| 24 | + name: "example.com", |
| 25 | +}); |
| 26 | + |
| 27 | +const basicCert = await CertificatePack("my-cert", { |
| 28 | + zone: zone, |
| 29 | + certificateAuthority: "lets_encrypt", |
| 30 | + hosts: ["example.com", "www.example.com"], |
| 31 | + validationMethod: "txt", |
| 32 | + validityDays: 90, |
| 33 | +}); |
| 34 | +``` |
| 35 | + |
| 36 | +## Enterprise Certificate with Google Trust Services |
| 37 | + |
| 38 | +Create an enterprise-grade certificate with Google Trust Services and Cloudflare branding. |
| 39 | + |
| 40 | +```ts |
| 41 | +const enterpriseCert = await CertificatePack("enterprise-cert", { |
| 42 | + zone: "example.com", // Can use zone ID string or Zone resource |
| 43 | + certificateAuthority: "google", |
| 44 | + hosts: ["example.com", "*.example.com", "api.example.com"], |
| 45 | + validationMethod: "txt", |
| 46 | + validityDays: 365, |
| 47 | + cloudflareBranding: true, |
| 48 | +}); |
| 49 | +``` |
| 50 | + |
| 51 | +## Wildcard Certificate with SSL.com |
| 52 | + |
| 53 | +Create a wildcard certificate using SSL.com with email validation. |
| 54 | + |
| 55 | +```ts |
| 56 | +const wildcardCert = await CertificatePack("wildcard-cert", { |
| 57 | + zone: myZone, |
| 58 | + certificateAuthority: "ssl_com", |
| 59 | + hosts: ["example.com", "*.example.com"], |
| 60 | + validationMethod: "email", |
| 61 | + validityDays: 365, |
| 62 | +}); |
| 63 | +``` |
| 64 | + |
| 65 | +## Multi-Domain Certificate |
| 66 | + |
| 67 | +Create a certificate covering multiple subdomains with Let's Encrypt. |
| 68 | + |
| 69 | +```ts |
| 70 | +const multiDomainCert = await CertificatePack("multi-cert", { |
| 71 | + zone: "example.com", |
| 72 | + certificateAuthority: "lets_encrypt", |
| 73 | + hosts: [ |
| 74 | + "example.com", |
| 75 | + "www.example.com", |
| 76 | + "api.example.com", |
| 77 | + "admin.example.com", |
| 78 | + "blog.example.com" |
| 79 | + ], |
| 80 | + validationMethod: "http", |
| 81 | + validityDays: 90, |
| 82 | +}); |
| 83 | +``` |
| 84 | + |
| 85 | +## Properties |
| 86 | + |
| 87 | +| Property | Type | Required | Description | |
| 88 | +|----------|------|----------|-------------| |
| 89 | +| `zone` | `string \| Zone` | Yes | Zone resource or zone ID where the certificate will be created | |
| 90 | +| `certificateAuthority` | `"google" \| "lets_encrypt" \| "ssl_com"` | Yes | Certificate Authority to use for issuing the certificate | |
| 91 | +| `hosts` | `string[]` | Yes | List of hostnames (max 50, must include zone apex) | |
| 92 | +| `validationMethod` | `"txt" \| "http" \| "email"` | Yes | Domain ownership validation method | |
| 93 | +| `validityDays` | `14 \| 30 \| 90 \| 365` | Yes | Certificate validity period in days | |
| 94 | +| `cloudflareBranding` | `boolean` | No | Add Cloudflare branding subdomain as Common Name (default: false) | |
| 95 | +| `type` | `"advanced"` | No | Certificate type (only "advanced" supported, default: "advanced") | |
| 96 | +| `delete` | `boolean` | No | Whether to delete the certificate pack on destroy (default: true) | |
| 97 | + |
| 98 | +## Certificate Authorities |
| 99 | + |
| 100 | +### Let's Encrypt (`lets_encrypt`) |
| 101 | +- **Cost:** Free |
| 102 | +- **Best for:** Basic SSL needs, development environments |
| 103 | +- **Validity:** Shorter periods (14, 30, 90 days) |
| 104 | +- **Features:** Standard domain validation |
| 105 | + |
| 106 | +### Google Trust Services (`google`) |
| 107 | +- **Cost:** Paid |
| 108 | +- **Best for:** Enterprise applications, production environments |
| 109 | +- **Validity:** Up to 365 days |
| 110 | +- **Features:** Enhanced validation, enterprise support |
| 111 | + |
| 112 | +### SSL.com (`ssl_com`) |
| 113 | +- **Cost:** Commercial |
| 114 | +- **Best for:** Commercial applications requiring extended validation |
| 115 | +- **Validity:** Up to 365 days |
| 116 | +- **Features:** Extended validation options, commercial support |
| 117 | + |
| 118 | +## Validation Methods |
| 119 | + |
| 120 | +### TXT Record (`txt`) |
| 121 | +- Add DNS TXT record to prove domain ownership |
| 122 | +- Most reliable method for automation |
| 123 | +- Works with all domain configurations |
| 124 | + |
| 125 | +### HTTP File (`http`) |
| 126 | +- Upload verification file to domain's web server |
| 127 | +- Requires web server access |
| 128 | +- Good for domains with existing websites |
| 129 | + |
| 130 | +### Email (`email`) |
| 131 | +- Receive validation email at admin addresses |
| 132 | +- Requires access to domain admin email |
| 133 | +- Manual validation process |
| 134 | + |
| 135 | +## Important Notes |
| 136 | + |
| 137 | +### Immutable Properties |
| 138 | +Most certificate pack properties cannot be changed after creation. To modify these properties, you must delete and recreate the certificate pack: |
| 139 | + |
| 140 | +- Certificate Authority (`certificateAuthority`) |
| 141 | +- Hostnames (`hosts`) |
| 142 | +- Validation Method (`validationMethod`) |
| 143 | +- Validity Period (`validityDays`) |
| 144 | +- Type (`type`) |
| 145 | + |
| 146 | +### Updateable Properties |
| 147 | +Only `cloudflareBranding` can be updated after creation: |
| 148 | + |
| 149 | +```ts |
| 150 | +// Update to enable Cloudflare branding |
| 151 | +const updatedCert = await CertificatePack("my-cert", { |
| 152 | + zone: zone, |
| 153 | + certificateAuthority: "lets_encrypt", // Must match original |
| 154 | + hosts: ["example.com", "www.example.com"], // Must match original |
| 155 | + validationMethod: "txt", // Must match original |
| 156 | + validityDays: 90, // Must match original |
| 157 | + cloudflareBranding: true, // Only this can change |
| 158 | +}); |
| 159 | +``` |
| 160 | + |
| 161 | +### Host Requirements |
| 162 | +- Maximum 50 hostnames per certificate pack |
| 163 | +- Must include the zone apex (root domain) |
| 164 | +- Supports wildcards (e.g., `*.example.com`) |
| 165 | +- Cannot be empty |
| 166 | + |
| 167 | +### Provisioning Time |
| 168 | +- Certificate packs take time to provision and become active |
| 169 | +- Full deployment can take up to 10 minutes |
| 170 | +- Monitor the `status` property to track progress |
| 171 | + |
| 172 | +### Subscription Requirements |
| 173 | +Advanced Certificate Packs require a paid Cloudflare plan. Free plans cannot create certificate packs and will receive subscription-related errors. |
| 174 | + |
| 175 | +## Status Values |
| 176 | + |
| 177 | +Certificate packs progress through various status values during their lifecycle: |
| 178 | + |
| 179 | +- `initializing` - Certificate pack creation in progress |
| 180 | +- `pending_validation` - Waiting for domain validation |
| 181 | +- `pending_issuance` - Certificate being issued by CA |
| 182 | +- `pending_deployment` - Certificate being deployed to edge |
| 183 | +- `active` - Certificate is live and serving traffic |
| 184 | +- `expired` - Certificate has expired |
| 185 | +- `deleted` - Certificate pack has been deleted |
| 186 | + |
| 187 | +Error states include `*_timed_out` variants when operations exceed time limits. |
| 188 | + |
| 189 | +## Helper Functions |
| 190 | + |
| 191 | +### Wait for Certificate to Become Active |
| 192 | + |
| 193 | +```ts |
| 194 | +import { waitForCertificatePackActive } from "alchemy/cloudflare/certificate-pack"; |
| 195 | + |
| 196 | +// Wait for certificate to become active (up to 10 minutes) |
| 197 | +const finalStatus = await waitForCertificatePackActive( |
| 198 | + api, |
| 199 | + zone.id, |
| 200 | + certificatePack.id, |
| 201 | + 10 * 60 * 1000 // 10 minutes timeout |
| 202 | +); |
| 203 | + |
| 204 | +console.log(`Certificate pack is now: ${finalStatus}`); |
| 205 | +``` |
0 commit comments