fix: add ACME schedule environment variable for Azure Function deployment
This commit is contained in:
@@ -80,6 +80,7 @@ All configuration is via environment variables. CLI flags override env vars when
|
||||
| `ACME_DNS_PROPAGATION_WAIT` | `60` | Maximum seconds to wait for DNS TXT record propagation |
|
||||
| `ACME_DNS_CHALLENGE_TTL` | `60` | TTL (seconds) for DNS-01 challenge TXT records |
|
||||
| `ACME_LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` |
|
||||
| `ACME_SCHEDULE` | `0 0 2 * * *` | Azure Function timer schedule (cron expression, 6-field format). Only used when deployed as an Azure Function. |
|
||||
|
||||
### Azure Authentication
|
||||
|
||||
@@ -95,15 +96,136 @@ For sovereign clouds (Azure Government, Azure China), set `AZURE_AUTHORITY_HOST`
|
||||
|
||||
## Azure Function
|
||||
|
||||
The package includes an Azure Functions v4 timer trigger that runs the provisioner daily at 02:00 UTC. To deploy, point the function app at this package's entry point and configure the environment variables above as application settings.
|
||||
The package includes an Azure Functions v4 timer trigger that runs the provisioner daily at 02:00 UTC.
|
||||
|
||||
The function app requires a Managed Identity with the following RBAC assignments:
|
||||
|
||||
| Scope | Role |
|
||||
|---|---|
|
||||
| Key Vault | Key Vault Certificates Officer |
|
||||
| Key Vault | Key Vault Secrets Officer |
|
||||
| DNS Zone(s) | DNS Zone Contributor |
|
||||
| Key Vault instance | Key Vault Certificates Officer |
|
||||
| Key Vault instance | Key Vault Secrets Officer |
|
||||
| Each DNS zone | DNS Zone Contributor |
|
||||
|
||||
> **Note:** The only DNS changes made are temporary `_acme-challenge.<domain>` TXT records created during the DNS-01 challenge and deleted immediately after validation. No A, CNAME, or other records are modified. If you require tighter permissions than `DNS Zone Contributor`, create a custom role limited to `Microsoft.Network/dnszones/TXT/write` and `Microsoft.Network/dnszones/TXT/delete`.
|
||||
|
||||
### Deploying with Azure Functions Core Tools
|
||||
|
||||
**Prerequisites:** [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli), [Azure Functions Core Tools v4](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools), Node.js 24.
|
||||
|
||||
**1. Log in to Azure**
|
||||
|
||||
```sh
|
||||
az login
|
||||
```
|
||||
|
||||
**2. Create a resource group and storage account** (skip if they already exist)
|
||||
|
||||
```sh
|
||||
az group create --name <resource-group> --location <location>
|
||||
|
||||
az storage account create \
|
||||
--name <storage-account-name> \
|
||||
--resource-group <resource-group> \
|
||||
--location <location> \
|
||||
--sku Standard_LRS
|
||||
```
|
||||
|
||||
**3. Create the Function App**
|
||||
|
||||
```sh
|
||||
az functionapp create \
|
||||
--name <function-app-name> \
|
||||
--resource-group <resource-group> \
|
||||
--storage-account <storage-account-name> \
|
||||
--consumption-plan-location <location> \
|
||||
--runtime node \
|
||||
--runtime-version 24 \
|
||||
--functions-version 4
|
||||
```
|
||||
|
||||
**4. Assign a system-assigned Managed Identity**
|
||||
|
||||
```sh
|
||||
az functionapp identity assign \
|
||||
--name <function-app-name> \
|
||||
--resource-group <resource-group>
|
||||
```
|
||||
|
||||
Note the `principalId` from the output — you will need it in the next step.
|
||||
|
||||
**5. Grant RBAC roles to the Managed Identity**
|
||||
|
||||
```sh
|
||||
# Key Vault Certificates Officer
|
||||
az role assignment create \
|
||||
--assignee <principalId> \
|
||||
--role "Key Vault Certificates Officer" \
|
||||
--scope /subscriptions/<subscription-id>/resourceGroups/<kv-resource-group>/providers/Microsoft.KeyVault/vaults/<keyvault-name>
|
||||
|
||||
# Key Vault Secrets Officer
|
||||
az role assignment create \
|
||||
--assignee <principalId> \
|
||||
--role "Key Vault Secrets Officer" \
|
||||
--scope /subscriptions/<subscription-id>/resourceGroups/<kv-resource-group>/providers/Microsoft.KeyVault/vaults/<keyvault-name>
|
||||
|
||||
# Option A — per zone (minimum permission, repeat for each managed DNS zone)
|
||||
az role assignment create \
|
||||
--assignee <principalId> \
|
||||
--role "DNS Zone Contributor" \
|
||||
--scope /subscriptions/<subscription-id>/resourceGroups/<dns-resource-group>/providers/Microsoft.Network/dnszones/<zone-name>
|
||||
|
||||
# Option B — per resource group (convenient when all DNS zones are in one group)
|
||||
az role assignment create \
|
||||
--assignee <principalId> \
|
||||
--role "DNS Zone Contributor" \
|
||||
--scope /subscriptions/<subscription-id>/resourceGroups/<dns-resource-group>
|
||||
```
|
||||
|
||||
**6. Configure application settings**
|
||||
|
||||
```sh
|
||||
az functionapp config appsettings set \
|
||||
--name <function-app-name> \
|
||||
--resource-group <resource-group> \
|
||||
--settings \
|
||||
"ACME_KEYVAULT_URL=https://<keyvault-name>.vault.azure.net" \
|
||||
"ACME_SUBSCRIPTION_ID=<subscription-id>" \
|
||||
"ACME_RESOURCE_GROUPS=<dns-resource-group>" \
|
||||
"ACME_CONTACT_EMAIL=<email>"
|
||||
```
|
||||
|
||||
**7. Build and deploy**
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
func azure functionapp publish <function-app-name>
|
||||
```
|
||||
|
||||
### Local testing
|
||||
|
||||
Create a `local.settings.json` file at the project root (it is gitignored):
|
||||
|
||||
```json
|
||||
{
|
||||
"IsEncrypted": false,
|
||||
"Values": {
|
||||
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
|
||||
"FUNCTIONS_WORKER_RUNTIME": "node",
|
||||
"ACME_KEYVAULT_URL": "https://<keyvault-name>.vault.azure.net",
|
||||
"ACME_SUBSCRIPTION_ID": "<subscription-id>",
|
||||
"ACME_RESOURCE_GROUPS": "<dns-resource-group>",
|
||||
"ACME_CONTACT_EMAIL": "<email>",
|
||||
"ACME_SCHEDULE": "0 0 2 * * *"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
func start
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
|
||||
Reference in New Issue
Block a user