Lets Encrypt - Azure DNS

Octopus.Script exported 2026-08-12 by harrisonmeister belongs to ‘Lets Encrypt’ category.

Request (or renew) a X.509 SSL Certificate from the Let’s Encrypt Certificate Authority.

Features

  • ACME v2 protocol support which allows generating wildcard certificates (*.example.com)
  • Azure DNS Challenge for TLD, CNAME and Wildcard domains.
  • Publishes/Updates SSL Certificates in the Octopus Deploy Certificate Store.
  • Verified to work on both Windows (PowerShell 5+) and Linux (PowerShell 6+) deployment Targets or Workers.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Certificate Domain

LE_AzureDNS_CertificateDomain =

Domain (TLD, CNAME or Wildcard) to create a certificate for.

PFX Password

LE_AzureDNS_PfxPassword =

Password to use when converting to / from PFX.

Replace expiring certificate before N days

LE_AzureDNS_ReplaceIfExpiresInDays = 30

Replace the certificate if it expiries within N days

Azure account

LE_AzureDNS_AzureAccount =

An Azure Account that has API access to make DNS changes.

Octopus Deploy API key

LE_AzureDNS_Octopus_APIKey =

A Octopus Deploy API key with access to change Certificates in the Certificate Store.

Use Lets Encrypt Staging

LE_AzureDNS_Use_Staging = false

Should the Certificate be generated using the Lets Encrypt Staging infrastructure?

Contact Email Address

LE_AzureDNS_ContactEmailAddress = #{Octopus.Deployment.CreatedBy.EmailAddress}

Email Address

Create Wildcard SAN

LE_AzureDNS_CreateWildcardSAN = false

Should the certificate have a Subject Alternative Name (SAN) excluding the wildcard?

e.g. a certificate domain of *.internal.example-domain.com could also have a SAN of internal.example-domain.com

DNS Alias

LE_AzureDNS_DnsAlias =

Use a CNAME alias for the TXT challenge.

Script body

Steps based on this template will execute the following PowerShell script.

###############################################################################
# TLS 1.2
###############################################################################
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

###############################################################################
# Required Modules folder
###############################################################################
Write-Host "Checking for required powershell modules folder"
$ModulesFolder = "$HOME\Documents\WindowsPowerShell\Modules"
if ($PSEdition -eq "Core") {
    if ($PSVersionTable.Platform -eq "Unix") {
        $ModulesFolder = "$HOME/.local/share/powershell/Modules"
    }
    else {
        $ModulesFolder = "$HOME\Documents\PowerShell\Modules"
    }
}
$PSModuleFolderExists = (Test-Path $ModulesFolder)
if ($PSModuleFolderExists -eq $False) {
	Write-Host "Creating directory: $ModulesFolder"
	New-Item $ModulesFolder -ItemType Directory -Force
    $env:PSModulePath = $ModulesFolder + [System.IO.Path]::PathSeparator + $env:PSModulePath
}

###############################################################################
# Required Modules
###############################################################################
Write-Host "Checking for required modules."
$required_posh_acme_version = 3.12.0
$module_check = Get-Module -ListAvailable -Name Posh-Acme | Where-Object { $_.Version -ge $required_posh_acme_version }

if (-not ($module_check)) {
    Write-Host "Ensuring NuGet provider is bootstrapped."
    Get-PackageProvider NuGet -ForceBootstrap | Out-Null
    Write-Host "Installing Posh-ACME."
    Install-Module -Name Posh-ACME -MinimumVersion 3.12.0 -Scope CurrentUser -Force
}

Import-Module Posh-ACME

###############################################################################
# Constants
###############################################################################
$LE_AzureDNS_CertificateDomain = $OctopusParameters["LE_AzureDNS_CertificateDomain"]
$LE_AzureDNS_CertificateName = "Lets Encrypt - $($LE_AzureDNS_CertificateDomain)"

# Let's Encrypt rotates its intermediate CAs and the Common Name of each intermediate is
# short lived (Let's Encrypt Authority X3 -> R3 -> R10 -> YR1 and so on), so matching on a
# list of Common Names goes stale every time a new intermediate appears. Match on the issuer
# Organization instead, which has been stable since 2015, and use the "(STAGING) " prefix on
# the Common Name to tell staging and production apart. The prefix is what separates the two
# environments: staging intermediates in the Generation Y hierarchy carry the production
# Organization, so the Organization alone cannot be used to distinguish them.
$LE_AzureDNS_Issuer_Organizations = @("Let's Encrypt", "(STAGING) Let's Encrypt")
$LE_AzureDNS_Staging_Issuer_CommonNamePattern = "(STAGING) *"
# The original staging intermediate carries no Organization, so it is matched on Common Name.
$LE_AzureDNS_Legacy_Staging_Issuer_CommonName = "Fake LE Intermediate X1"

# (Optional) CNAME DNS alias. If specified, the alias will be used for the TXT challenge.
# https://poshac.me/docs/v4/Guides/Using-DNS-Challenge-Aliases/
$LE_AzureDNS_DnsAlias = $OctopusParameters["LE_AzureDNS_DnsAlias"]

###############################################################################
# Helpers
###############################################################################
function Get-WebRequestErrorBody {
    param (
        $RequestError
    )

    # Powershell < 6 you can read the Exception
    if ($PSVersionTable.PSVersion.Major -lt 6) {
        if ($RequestError.Exception.Response) {
            $reader = New-Object System.IO.StreamReader($RequestError.Exception.Response.GetResponseStream())
            $reader.BaseStream.Position = 0
            $reader.DiscardBufferedData()
            $response = $reader.ReadToEnd()

            return $response | ConvertFrom-Json
        }
    }
    else {
        return $RequestError.ErrorDetails.Message
    }
}

function Test-IsLetsEncryptIssuer {
    [OutputType([bool])]
    param (
        $Certificate,
        [bool] $Staging
    )

    $issuer_organization = $Certificate.IssuerOrganization
    $issuer_common_name = $Certificate.IssuerCommonName

    # Fall back to the Distinguished Name if the Octopus Server did not populate these fields.
    if ([string]::IsNullOrWhiteSpace($issuer_organization) -and $Certificate.IssuerDistinguishedName -match '(?:^|,)\s*O\s*=\s*([^,]+)') {
        $issuer_organization = $Matches[1].Trim()
    }

    if ([string]::IsNullOrWhiteSpace($issuer_common_name) -and $Certificate.IssuerDistinguishedName -match '(?:^|,)\s*CN\s*=\s*([^,]+)') {
        $issuer_common_name = $Matches[1].Trim()
    }

    # The original staging intermediate carries no Organization, so it is matched on Common Name.
    $is_legacy_staging_issuer = ($issuer_common_name -eq $LE_AzureDNS_Legacy_Staging_Issuer_CommonName)

    # Did Let's Encrypt issue this certificate, production or staging?
    $issued_by_lets_encrypt = ($LE_AzureDNS_Issuer_Organizations -contains $issuer_organization) -or $is_legacy_staging_issuer

    if (-not $issued_by_lets_encrypt) {
        Write-Debug "Issuer '$issuer_common_name' is not Let's Encrypt. Skipping this certificate."
        return $false
    }

    # Did a staging intermediate issue it? Staging Common Names are prefixed with "(STAGING) ".
    # The Organization cannot answer this: Generation Y staging intermediates carry the
    # production Organization of "Let's Encrypt".
    $issued_by_staging = ($issuer_common_name -like $LE_AzureDNS_Staging_Issuer_CommonNamePattern) -or $is_legacy_staging_issuer

    if ($Staging -and $issued_by_staging) {
        return $true
    }

    if ((-not $Staging) -and (-not $issued_by_staging)) {
        return $true
    }

    Write-Debug "Issuer '$issuer_common_name' is not from the Let's Encrypt environment we want. Skipping this certificate."
    return $false
}

###############################################################################
# Functions
###############################################################################
function Get-LetsEncryptCertificate {
    Write-Debug "Entering: Get-LetsEncryptCertificate"

    if ($OctopusParameters["LE_AzureDNS_Use_Staging"] -eq $True) {
        Write-Host "Using Lets Encrypt Server: Staging"
        Set-PAServer LE_STAGE;
    }
    else {
        Write-Host "Using Lets Encrypt Server: Production"
        Set-PAServer LE_PROD;
    }

    # Clobber account if it exists.
    $le_account = Get-PAAccount
    if ($le_account) {
        Remove-PAAccount $le_account.Id -Force
    }

    $azure_password = ConvertTo-SecureString -String $OctopusParameters["LE_AzureDNS_AzureAccount.Password"] -AsPlainText -Force
    $azure_credential = New-Object System.Management.Automation.PSCredential($OctopusParameters["LE_AzureDNS_AzureAccount.Client"], $azure_password)
    $azure_params = @{
        AZSubscriptionId = $OctopusParameters["LE_AzureDNS_AzureAccount.SubscriptionNumber"];
        AZTenantId       = $OctopusParameters["LE_AzureDNS_AzureAccount.TenantId"];
        AZAppCred        = $azure_credential
    }

    try {

        $DnsPlugins = @("Azure")
        $DomainList = @($LE_AzureDNS_CertificateDomain)
        
        # If domain is a wildcard e.g. *.example-domain.com, check if a SAN has been requested e.g. example-domain.com.
        if ($LE_AzureDNS_CertificateDomain -match "\*." -and $OctopusParameters["LE_AzureDNS_CreateWildcardSAN"] -eq $True) {
            $LE_AzureDNS_Certificate_SAN = $LE_AzureDNS_CertificateDomain.Replace("*.","")
            $DomainList += $LE_AzureDNS_Certificate_SAN
            # Include additional DnsPlugin of same type to suppress warning.
            $DnsPlugins += "Azure"
        }

        $Cert_Params = @{
            Domain = $DomainList
            AcceptTOS = $True;
            Contact = $OctopusParameters["LE_AzureDNS_ContactEmailAddress"];
            DnsPlugin = $DnsPlugins;
            PluginArgs = $azure_params;
            PfxPass = $OctopusParameters["LE_AzureDNS_PfxPassword"];
            Force = $True;
        }
        
        if ($LE_AzureDNS_DnsAlias) {
            $Cert_Params += @{DnsAlias = @($LE_AzureDNS_DnsAlias, $LE_AzureDNS_DnsAlias)} # Adding the value twice to avoid the warning "Fewer DnsAlias values than names in the order."
        }

        return New-PACertificate @Cert_Params
    }
    catch {
        Write-Host "Failed to Create Certificate. Error Message: $($_.Exception.Message). See Debug output for details."
        Write-Debug (Get-WebRequestErrorBody -RequestError $_)
        exit 1
    }
}

function Get-OctopusCertificates {
    Write-Debug "Entering: Get-OctopusCertificates"

    $octopus_uri = $OctopusParameters["Octopus.Web.ServerUri"]
    $octopus_space_id = $OctopusParameters["Octopus.Space.Id"]
    $octopus_headers = @{ "X-Octopus-ApiKey" = $OctopusParameters["LE_AzureDNS_Octopus_APIKey"] }
    $octopus_certificates_uri = "$octopus_uri/api/$octopus_space_id/certificates?search=$($LE_AzureDNS_CertificateDomain)"

    try {
        # Get a list of certificates that match our domain search criteria.
        $certificates_search = Invoke-WebRequest -Uri $octopus_certificates_uri -Method Get -Headers $octopus_headers -UseBasicParsing -ErrorAction Stop | ConvertFrom-Json | Select-Object -ExpandProperty Items

        # We don't want to confuse Production and Staging Lets Encrypt Certificates.
        $use_staging = ($OctopusParameters["LE_AzureDNS_Use_Staging"] -eq $True)

        return $certificates_search | Where-Object {
            $_.SubjectCommonName -eq $LE_AzureDNS_CertificateDomain -and
            (Test-IsLetsEncryptIssuer -Certificate $_ -Staging $use_staging) -and
            $null -eq $_.ReplacedBy -and
            $null -eq $_.Archived
        }
    }
    catch {
        Write-Host "Could not retrieve certificates from Octopus Deploy. Error: $($_.Exception.Message). See Debug output for details."
        Write-Debug (Get-WebRequestErrorBody -RequestError $_)
        exit 1
    }
}

function Publish-OctopusCertificate {
    param (
        [string] $JsonBody
    )

    Write-Debug "Entering: Publish-OctopusCertificate"

    if (-not ($JsonBody)) {
        Write-Host "Existing Certificate is required."
        exit 1
    }

    $octopus_uri = $OctopusParameters["Octopus.Web.ServerUri"]
    $octopus_space_id = $OctopusParameters["Octopus.Space.Id"]
    $octopus_headers = @{ "X-Octopus-ApiKey" = $OctopusParameters["LE_AzureDNS_Octopus_APIKey"] }
    $octopus_certificates_uri = "$octopus_uri/api/$octopus_space_id/certificates"

    try {
        Invoke-WebRequest -Uri $octopus_certificates_uri -Method Post -Headers $octopus_headers -Body $JsonBody -UseBasicParsing
        Write-Host "Published $($LE_AzureDNS_CertificateDomain) certificate to the Octopus Deploy Certificate Store."
    }
    catch {
        Write-Host "Failed to publish $($LE_AzureDNS_CertificateDomain) certificate. Error: $($_.Exception.Message). See Debug output for details."
        Write-Debug (Get-WebRequestErrorBody -RequestError $_)
        exit 1
    }
}

function Update-OctopusCertificate {
    param (
        [string]$Certificate_Id,
        [string]$JsonBody
    )

    Write-Debug "Entering: Update-OctopusCertificate"

    if (-not ($Certificate_Id -and $JsonBody)) {
        Write-Host "Existing Certificate Id and a replace Certificate are required."
        exit 1
    }

    $octopus_uri = $OctopusParameters["Octopus.Web.ServerUri"]
    $octopus_space_id = $OctopusParameters["Octopus.Space.Id"]
    $octopus_headers = @{ "X-Octopus-ApiKey" = $OctopusParameters["LE_AzureDNS_Octopus_APIKey"] }
    $octopus_certificates_uri = "$octopus_uri/api/$octopus_space_id/certificates/$Certificate_Id/replace"

    try {
        Invoke-WebRequest -Uri $octopus_certificates_uri -Method Post -Headers $octopus_headers -Body $JsonBody -UseBasicParsing
        Write-Host "Replaced $($LE_AzureDNS_CertificateDomain) certificate in the Octopus Deploy Certificate Store."
    }
    catch {
        Write-Error "Failed to replace $($LE_AzureDNS_CertificateDomain) certificate. Error: $($_.Exception.Message)"
        exit 1
    }
}

function Get-NewCertificatePFXAsJson {
    param (
        $Certificate
    )

    Write-Debug "Entering: Get-NewCertificatePFXAsJson"

    if (-not ($Certificate)) {
        Write-Host "Certificate is required."
        Exit 1
    }

    [Byte[]]$certificate_buffer = [System.IO.File]::ReadAllBytes($Certificate.PfxFullChain)
    $certificate_base64 = [convert]::ToBase64String($certificate_buffer)

    $certificate_body = @{
        Name = "$LE_AzureDNS_CertificateName";
        Notes             = "";
        CertificateData   = @{
            HasValue = $true;
            NewValue = $certificate_base64;
        };
        Password          = @{
            HasValue = $true;
            NewValue = $OctopusParameters["LE_AzureDNS_PfxPassword"];
        };
    }

    return $certificate_body | ConvertTo-Json
}

function Get-ReplaceCertificatePFXAsJson {
    param (
        $Certificate
    )

    Write-Debug "Entering: Get-ReplaceCertificatePFXAsJson"

    if (-not ($Certificate)) {
        Write-Host "Certificate is required."
        Exit 1
    }

    [Byte[]]$certificate_buffer = [System.IO.File]::ReadAllBytes($Certificate.PfxFullChain)
    $certificate_base64 = [convert]::ToBase64String($certificate_buffer)

    $certificate_body = @{
        CertificateData = $certificate_base64;
        Password        = $OctopusParameters["LE_AzureDNS_PfxPassword"];
    }

    return $certificate_body | ConvertTo-Json
}

###############################################################################
# DO THE THING | MAIN |
###############################################################################
Write-Debug "Do the Thing"

Write-Host "Checking for existing Lets Encrypt Certificates in the Octopus Deploy Certificates Store."
$certificates = Get-OctopusCertificates

# Check for PFX & PEM
if ($certificates) {

    # Handle weird behavior between Powershell 5 and Powershell 6+
    $certificate_count = 1
    if ($certificates.Count -ge 1) {
        $certificate_count = $certificates.Count
    }

    Write-Host "Found $certificate_count for $($LE_AzureDNS_CertificateDomain)."
    Write-Host "Checking to see if any expire within $($OctopusParameters["LE_AzureDNS_ReplaceIfExpiresInDays"]) days."

    # Check Expiry Dates
    $expiring_certificates = $certificates | Where-Object { [DateTime]$_.NotAfter -lt (Get-Date).AddDays($OctopusParameters["LE_AzureDNS_ReplaceIfExpiresInDays"]) }

    if ($expiring_certificates) {
        Write-Host "Found certificates that expire with $($OctopusParameters["LE_AzureDNS_ReplaceIfExpiresInDays"]) days. Requesting new certificates for $($LE_AzureDNS_CertificateDomain) from Lets Encrypt"
        $le_certificate = Get-LetsEncryptCertificate

        # PFX
        $existing_certificate = $expiring_certificates | Where-Object { $_.CertificateDataFormat -eq "Pkcs12" } | Sort-Object { [DateTime]$_.NotAfter } | Select-Object -First 1
        Write-Host "Replacing certificate $($existing_certificate.Id), which expires $(([DateTime]$existing_certificate.NotAfter).ToString('u'))."
        $certificate_as_json = Get-ReplaceCertificatePFXAsJson -Certificate $le_certificate
        Update-OctopusCertificate -Certificate_Id $existing_certificate.Id -JsonBody $certificate_as_json
    }
    else {
        Write-Host "Nothing to do here..."
    }

    exit 0
}

# No existing Certificates - Lets get some new ones.
Write-Host "No existing certificates found for $($LE_AzureDNS_CertificateDomain)."
Write-Host "Request New Certificate for $($LE_AzureDNS_CertificateDomain) from Lets Encrypt"

# New Certificate..
$le_certificate = Get-LetsEncryptCertificate

Write-Host "Publishing: LetsEncrypt - $($LE_AzureDNS_CertificateDomain) (PFX)"
$certificate_as_json = Get-NewCertificatePFXAsJson -Certificate $le_certificate
Publish-OctopusCertificate -JsonBody $certificate_as_json

Write-Host "GREAT SUCCESS"

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "79e0dd12-6222-4f8a-a8dc-bcbe579ed729",
  "Name": "Lets Encrypt - Azure DNS",
  "Description": "Request (or renew) a X.509 SSL Certificate from the [Let's Encrypt Certificate Authority](https://letsencrypt.org/). \n\n#### Features\n\n- ACME v2 protocol support which allows generating wildcard certificates (*.example.com)\n- [Azure DNS](https://azure.microsoft.com/en-us/services/dns/) Challenge for TLD, CNAME and Wildcard domains. \n- Publishes/Updates SSL Certificates in the [Octopus Deploy Certificate Store](https://octopus.com/docs/deployment-examples/certificates). \n- Verified to work on both Windows (PowerShell 5+) and Linux (PowerShell 6+) deployment Targets or Workers.",
  "Version": 17,
  "ExportedAt": "2026-08-12T15:16:59.552Z",
  "ActionType": "Octopus.Script",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "f1739a56-2603-42e0-b629-801dd71b0b0c",
      "Name": "LE_AzureDNS_CertificateDomain",
      "Label": "Certificate Domain",
      "HelpText": "Domain (TLD, CNAME or Wildcard) to create a certificate for. ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "c1f44b38-8025-4b12-b010-df48c02b3da4",
      "Name": "LE_AzureDNS_PfxPassword",
      "Label": "PFX Password",
      "HelpText": "Password to use when converting to / from PFX. ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "c258ee0e-e298-4fa1-9c66-5ac0749409c5",
      "Name": "LE_AzureDNS_ReplaceIfExpiresInDays",
      "Label": "Replace expiring certificate before N days",
      "HelpText": "Replace the certificate if it expiries within N days",
      "DefaultValue": "30",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "2935998d-d030-4af6-ad42-39e8b85e2dce",
      "Name": "LE_AzureDNS_AzureAccount",
      "Label": "Azure account",
      "HelpText": "An Azure Account that has API access to make DNS changes. ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "AzureAccount"
      }
    },
    {
      "Id": "85af482d-e577-40b8-94e5-626e545adab5",
      "Name": "LE_AzureDNS_Octopus_APIKey",
      "Label": "Octopus Deploy API key",
      "HelpText": "A Octopus Deploy API key with access to change Certificates in the Certificate Store. ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "00d513ed-3d75-48d2-954a-0a0165d85530",
      "Name": "LE_AzureDNS_Use_Staging",
      "Label": "Use Lets Encrypt Staging",
      "HelpText": "Should the Certificate be generated using the Lets Encrypt Staging infrastructure?",
      "DefaultValue": "false",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "f1fd315d-9fc5-4b15-b53c-9381ecc5cb88",
      "Name": "LE_AzureDNS_ContactEmailAddress",
      "Label": "Contact Email Address",
      "HelpText": "Email Address",
      "DefaultValue": "#{Octopus.Deployment.CreatedBy.EmailAddress}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "2dc7d9bc-9eee-4ee0-a33c-ef9371ed69f1",
      "Name": "LE_AzureDNS_CreateWildcardSAN",
      "Label": "Create Wildcard SAN",
      "HelpText": "Should the certificate have a Subject Alternative Name (SAN) excluding the wildcard?\n\ne.g. a certificate domain of `*.internal.example-domain.com` could also have a SAN of `internal.example-domain.com`",
      "DefaultValue": "false",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "36451c6b-f61d-4e00-b1f6-956341c9691d",
      "Name": "LE_AzureDNS_DnsAlias",
      "Label": "DNS Alias",
      "HelpText": "Use a CNAME alias for the TXT challenge.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "###############################################################################\n# TLS 1.2\n###############################################################################\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n###############################################################################\n# Required Modules folder\n###############################################################################\nWrite-Host \"Checking for required powershell modules folder\"\n$ModulesFolder = \"$HOME\\Documents\\WindowsPowerShell\\Modules\"\nif ($PSEdition -eq \"Core\") {\n    if ($PSVersionTable.Platform -eq \"Unix\") {\n        $ModulesFolder = \"$HOME/.local/share/powershell/Modules\"\n    }\n    else {\n        $ModulesFolder = \"$HOME\\Documents\\PowerShell\\Modules\"\n    }\n}\n$PSModuleFolderExists = (Test-Path $ModulesFolder)\nif ($PSModuleFolderExists -eq $False) {\n\tWrite-Host \"Creating directory: $ModulesFolder\"\n\tNew-Item $ModulesFolder -ItemType Directory -Force\n    $env:PSModulePath = $ModulesFolder + [System.IO.Path]::PathSeparator + $env:PSModulePath\n}\n\n###############################################################################\n# Required Modules\n###############################################################################\nWrite-Host \"Checking for required modules.\"\n$required_posh_acme_version = 3.12.0\n$module_check = Get-Module -ListAvailable -Name Posh-Acme | Where-Object { $_.Version -ge $required_posh_acme_version }\n\nif (-not ($module_check)) {\n    Write-Host \"Ensuring NuGet provider is bootstrapped.\"\n    Get-PackageProvider NuGet -ForceBootstrap | Out-Null\n    Write-Host \"Installing Posh-ACME.\"\n    Install-Module -Name Posh-ACME -MinimumVersion 3.12.0 -Scope CurrentUser -Force\n}\n\nImport-Module Posh-ACME\n\n###############################################################################\n# Constants\n###############################################################################\n$LE_AzureDNS_CertificateDomain = $OctopusParameters[\"LE_AzureDNS_CertificateDomain\"]\n$LE_AzureDNS_CertificateName = \"Lets Encrypt - $($LE_AzureDNS_CertificateDomain)\"\n\n# Let's Encrypt rotates its intermediate CAs and the Common Name of each intermediate is\n# short lived (Let's Encrypt Authority X3 -> R3 -> R10 -> YR1 and so on), so matching on a\n# list of Common Names goes stale every time a new intermediate appears. Match on the issuer\n# Organization instead, which has been stable since 2015, and use the \"(STAGING) \" prefix on\n# the Common Name to tell staging and production apart. The prefix is what separates the two\n# environments: staging intermediates in the Generation Y hierarchy carry the production\n# Organization, so the Organization alone cannot be used to distinguish them.\n$LE_AzureDNS_Issuer_Organizations = @(\"Let's Encrypt\", \"(STAGING) Let's Encrypt\")\n$LE_AzureDNS_Staging_Issuer_CommonNamePattern = \"(STAGING) *\"\n# The original staging intermediate carries no Organization, so it is matched on Common Name.\n$LE_AzureDNS_Legacy_Staging_Issuer_CommonName = \"Fake LE Intermediate X1\"\n\n# (Optional) CNAME DNS alias. If specified, the alias will be used for the TXT challenge.\n# https://poshac.me/docs/v4/Guides/Using-DNS-Challenge-Aliases/\n$LE_AzureDNS_DnsAlias = $OctopusParameters[\"LE_AzureDNS_DnsAlias\"]\n\n###############################################################################\n# Helpers\n###############################################################################\nfunction Get-WebRequestErrorBody {\n    param (\n        $RequestError\n    )\n\n    # Powershell < 6 you can read the Exception\n    if ($PSVersionTable.PSVersion.Major -lt 6) {\n        if ($RequestError.Exception.Response) {\n            $reader = New-Object System.IO.StreamReader($RequestError.Exception.Response.GetResponseStream())\n            $reader.BaseStream.Position = 0\n            $reader.DiscardBufferedData()\n            $response = $reader.ReadToEnd()\n\n            return $response | ConvertFrom-Json\n        }\n    }\n    else {\n        return $RequestError.ErrorDetails.Message\n    }\n}\n\nfunction Test-IsLetsEncryptIssuer {\n    [OutputType([bool])]\n    param (\n        $Certificate,\n        [bool] $Staging\n    )\n\n    $issuer_organization = $Certificate.IssuerOrganization\n    $issuer_common_name = $Certificate.IssuerCommonName\n\n    # Fall back to the Distinguished Name if the Octopus Server did not populate these fields.\n    if ([string]::IsNullOrWhiteSpace($issuer_organization) -and $Certificate.IssuerDistinguishedName -match '(?:^|,)\\s*O\\s*=\\s*([^,]+)') {\n        $issuer_organization = $Matches[1].Trim()\n    }\n\n    if ([string]::IsNullOrWhiteSpace($issuer_common_name) -and $Certificate.IssuerDistinguishedName -match '(?:^|,)\\s*CN\\s*=\\s*([^,]+)') {\n        $issuer_common_name = $Matches[1].Trim()\n    }\n\n    # The original staging intermediate carries no Organization, so it is matched on Common Name.\n    $is_legacy_staging_issuer = ($issuer_common_name -eq $LE_AzureDNS_Legacy_Staging_Issuer_CommonName)\n\n    # Did Let's Encrypt issue this certificate, production or staging?\n    $issued_by_lets_encrypt = ($LE_AzureDNS_Issuer_Organizations -contains $issuer_organization) -or $is_legacy_staging_issuer\n\n    if (-not $issued_by_lets_encrypt) {\n        Write-Debug \"Issuer '$issuer_common_name' is not Let's Encrypt. Skipping this certificate.\"\n        return $false\n    }\n\n    # Did a staging intermediate issue it? Staging Common Names are prefixed with \"(STAGING) \".\n    # The Organization cannot answer this: Generation Y staging intermediates carry the\n    # production Organization of \"Let's Encrypt\".\n    $issued_by_staging = ($issuer_common_name -like $LE_AzureDNS_Staging_Issuer_CommonNamePattern) -or $is_legacy_staging_issuer\n\n    if ($Staging -and $issued_by_staging) {\n        return $true\n    }\n\n    if ((-not $Staging) -and (-not $issued_by_staging)) {\n        return $true\n    }\n\n    Write-Debug \"Issuer '$issuer_common_name' is not from the Let's Encrypt environment we want. Skipping this certificate.\"\n    return $false\n}\n\n###############################################################################\n# Functions\n###############################################################################\nfunction Get-LetsEncryptCertificate {\n    Write-Debug \"Entering: Get-LetsEncryptCertificate\"\n\n    if ($OctopusParameters[\"LE_AzureDNS_Use_Staging\"] -eq $True) {\n        Write-Host \"Using Lets Encrypt Server: Staging\"\n        Set-PAServer LE_STAGE;\n    }\n    else {\n        Write-Host \"Using Lets Encrypt Server: Production\"\n        Set-PAServer LE_PROD;\n    }\n\n    # Clobber account if it exists.\n    $le_account = Get-PAAccount\n    if ($le_account) {\n        Remove-PAAccount $le_account.Id -Force\n    }\n\n    $azure_password = ConvertTo-SecureString -String $OctopusParameters[\"LE_AzureDNS_AzureAccount.Password\"] -AsPlainText -Force\n    $azure_credential = New-Object System.Management.Automation.PSCredential($OctopusParameters[\"LE_AzureDNS_AzureAccount.Client\"], $azure_password)\n    $azure_params = @{\n        AZSubscriptionId = $OctopusParameters[\"LE_AzureDNS_AzureAccount.SubscriptionNumber\"];\n        AZTenantId       = $OctopusParameters[\"LE_AzureDNS_AzureAccount.TenantId\"];\n        AZAppCred        = $azure_credential\n    }\n\n    try {\n\n        $DnsPlugins = @(\"Azure\")\n        $DomainList = @($LE_AzureDNS_CertificateDomain)\n        \n        # If domain is a wildcard e.g. *.example-domain.com, check if a SAN has been requested e.g. example-domain.com.\n        if ($LE_AzureDNS_CertificateDomain -match \"\\*.\" -and $OctopusParameters[\"LE_AzureDNS_CreateWildcardSAN\"] -eq $True) {\n            $LE_AzureDNS_Certificate_SAN = $LE_AzureDNS_CertificateDomain.Replace(\"*.\",\"\")\n            $DomainList += $LE_AzureDNS_Certificate_SAN\n            # Include additional DnsPlugin of same type to suppress warning.\n            $DnsPlugins += \"Azure\"\n        }\n\n        $Cert_Params = @{\n            Domain = $DomainList\n            AcceptTOS = $True;\n            Contact = $OctopusParameters[\"LE_AzureDNS_ContactEmailAddress\"];\n            DnsPlugin = $DnsPlugins;\n            PluginArgs = $azure_params;\n            PfxPass = $OctopusParameters[\"LE_AzureDNS_PfxPassword\"];\n            Force = $True;\n        }\n        \n        if ($LE_AzureDNS_DnsAlias) {\n            $Cert_Params += @{DnsAlias = @($LE_AzureDNS_DnsAlias, $LE_AzureDNS_DnsAlias)} # Adding the value twice to avoid the warning \"Fewer DnsAlias values than names in the order.\"\n        }\n\n        return New-PACertificate @Cert_Params\n    }\n    catch {\n        Write-Host \"Failed to Create Certificate. Error Message: $($_.Exception.Message). See Debug output for details.\"\n        Write-Debug (Get-WebRequestErrorBody -RequestError $_)\n        exit 1\n    }\n}\n\nfunction Get-OctopusCertificates {\n    Write-Debug \"Entering: Get-OctopusCertificates\"\n\n    $octopus_uri = $OctopusParameters[\"Octopus.Web.ServerUri\"]\n    $octopus_space_id = $OctopusParameters[\"Octopus.Space.Id\"]\n    $octopus_headers = @{ \"X-Octopus-ApiKey\" = $OctopusParameters[\"LE_AzureDNS_Octopus_APIKey\"] }\n    $octopus_certificates_uri = \"$octopus_uri/api/$octopus_space_id/certificates?search=$($LE_AzureDNS_CertificateDomain)\"\n\n    try {\n        # Get a list of certificates that match our domain search criteria.\n        $certificates_search = Invoke-WebRequest -Uri $octopus_certificates_uri -Method Get -Headers $octopus_headers -UseBasicParsing -ErrorAction Stop | ConvertFrom-Json | Select-Object -ExpandProperty Items\n\n        # We don't want to confuse Production and Staging Lets Encrypt Certificates.\n        $use_staging = ($OctopusParameters[\"LE_AzureDNS_Use_Staging\"] -eq $True)\n\n        return $certificates_search | Where-Object {\n            $_.SubjectCommonName -eq $LE_AzureDNS_CertificateDomain -and\n            (Test-IsLetsEncryptIssuer -Certificate $_ -Staging $use_staging) -and\n            $null -eq $_.ReplacedBy -and\n            $null -eq $_.Archived\n        }\n    }\n    catch {\n        Write-Host \"Could not retrieve certificates from Octopus Deploy. Error: $($_.Exception.Message). See Debug output for details.\"\n        Write-Debug (Get-WebRequestErrorBody -RequestError $_)\n        exit 1\n    }\n}\n\nfunction Publish-OctopusCertificate {\n    param (\n        [string] $JsonBody\n    )\n\n    Write-Debug \"Entering: Publish-OctopusCertificate\"\n\n    if (-not ($JsonBody)) {\n        Write-Host \"Existing Certificate is required.\"\n        exit 1\n    }\n\n    $octopus_uri = $OctopusParameters[\"Octopus.Web.ServerUri\"]\n    $octopus_space_id = $OctopusParameters[\"Octopus.Space.Id\"]\n    $octopus_headers = @{ \"X-Octopus-ApiKey\" = $OctopusParameters[\"LE_AzureDNS_Octopus_APIKey\"] }\n    $octopus_certificates_uri = \"$octopus_uri/api/$octopus_space_id/certificates\"\n\n    try {\n        Invoke-WebRequest -Uri $octopus_certificates_uri -Method Post -Headers $octopus_headers -Body $JsonBody -UseBasicParsing\n        Write-Host \"Published $($LE_AzureDNS_CertificateDomain) certificate to the Octopus Deploy Certificate Store.\"\n    }\n    catch {\n        Write-Host \"Failed to publish $($LE_AzureDNS_CertificateDomain) certificate. Error: $($_.Exception.Message). See Debug output for details.\"\n        Write-Debug (Get-WebRequestErrorBody -RequestError $_)\n        exit 1\n    }\n}\n\nfunction Update-OctopusCertificate {\n    param (\n        [string]$Certificate_Id,\n        [string]$JsonBody\n    )\n\n    Write-Debug \"Entering: Update-OctopusCertificate\"\n\n    if (-not ($Certificate_Id -and $JsonBody)) {\n        Write-Host \"Existing Certificate Id and a replace Certificate are required.\"\n        exit 1\n    }\n\n    $octopus_uri = $OctopusParameters[\"Octopus.Web.ServerUri\"]\n    $octopus_space_id = $OctopusParameters[\"Octopus.Space.Id\"]\n    $octopus_headers = @{ \"X-Octopus-ApiKey\" = $OctopusParameters[\"LE_AzureDNS_Octopus_APIKey\"] }\n    $octopus_certificates_uri = \"$octopus_uri/api/$octopus_space_id/certificates/$Certificate_Id/replace\"\n\n    try {\n        Invoke-WebRequest -Uri $octopus_certificates_uri -Method Post -Headers $octopus_headers -Body $JsonBody -UseBasicParsing\n        Write-Host \"Replaced $($LE_AzureDNS_CertificateDomain) certificate in the Octopus Deploy Certificate Store.\"\n    }\n    catch {\n        Write-Error \"Failed to replace $($LE_AzureDNS_CertificateDomain) certificate. Error: $($_.Exception.Message)\"\n        exit 1\n    }\n}\n\nfunction Get-NewCertificatePFXAsJson {\n    param (\n        $Certificate\n    )\n\n    Write-Debug \"Entering: Get-NewCertificatePFXAsJson\"\n\n    if (-not ($Certificate)) {\n        Write-Host \"Certificate is required.\"\n        Exit 1\n    }\n\n    [Byte[]]$certificate_buffer = [System.IO.File]::ReadAllBytes($Certificate.PfxFullChain)\n    $certificate_base64 = [convert]::ToBase64String($certificate_buffer)\n\n    $certificate_body = @{\n        Name = \"$LE_AzureDNS_CertificateName\";\n        Notes             = \"\";\n        CertificateData   = @{\n            HasValue = $true;\n            NewValue = $certificate_base64;\n        };\n        Password          = @{\n            HasValue = $true;\n            NewValue = $OctopusParameters[\"LE_AzureDNS_PfxPassword\"];\n        };\n    }\n\n    return $certificate_body | ConvertTo-Json\n}\n\nfunction Get-ReplaceCertificatePFXAsJson {\n    param (\n        $Certificate\n    )\n\n    Write-Debug \"Entering: Get-ReplaceCertificatePFXAsJson\"\n\n    if (-not ($Certificate)) {\n        Write-Host \"Certificate is required.\"\n        Exit 1\n    }\n\n    [Byte[]]$certificate_buffer = [System.IO.File]::ReadAllBytes($Certificate.PfxFullChain)\n    $certificate_base64 = [convert]::ToBase64String($certificate_buffer)\n\n    $certificate_body = @{\n        CertificateData = $certificate_base64;\n        Password        = $OctopusParameters[\"LE_AzureDNS_PfxPassword\"];\n    }\n\n    return $certificate_body | ConvertTo-Json\n}\n\n###############################################################################\n# DO THE THING | MAIN |\n###############################################################################\nWrite-Debug \"Do the Thing\"\n\nWrite-Host \"Checking for existing Lets Encrypt Certificates in the Octopus Deploy Certificates Store.\"\n$certificates = Get-OctopusCertificates\n\n# Check for PFX & PEM\nif ($certificates) {\n\n    # Handle weird behavior between Powershell 5 and Powershell 6+\n    $certificate_count = 1\n    if ($certificates.Count -ge 1) {\n        $certificate_count = $certificates.Count\n    }\n\n    Write-Host \"Found $certificate_count for $($LE_AzureDNS_CertificateDomain).\"\n    Write-Host \"Checking to see if any expire within $($OctopusParameters[\"LE_AzureDNS_ReplaceIfExpiresInDays\"]) days.\"\n\n    # Check Expiry Dates\n    $expiring_certificates = $certificates | Where-Object { [DateTime]$_.NotAfter -lt (Get-Date).AddDays($OctopusParameters[\"LE_AzureDNS_ReplaceIfExpiresInDays\"]) }\n\n    if ($expiring_certificates) {\n        Write-Host \"Found certificates that expire with $($OctopusParameters[\"LE_AzureDNS_ReplaceIfExpiresInDays\"]) days. Requesting new certificates for $($LE_AzureDNS_CertificateDomain) from Lets Encrypt\"\n        $le_certificate = Get-LetsEncryptCertificate\n\n        # PFX\n        $existing_certificate = $expiring_certificates | Where-Object { $_.CertificateDataFormat -eq \"Pkcs12\" } | Sort-Object { [DateTime]$_.NotAfter } | Select-Object -First 1\n        Write-Host \"Replacing certificate $($existing_certificate.Id), which expires $(([DateTime]$existing_certificate.NotAfter).ToString('u')).\"\n        $certificate_as_json = Get-ReplaceCertificatePFXAsJson -Certificate $le_certificate\n        Update-OctopusCertificate -Certificate_Id $existing_certificate.Id -JsonBody $certificate_as_json\n    }\n    else {\n        Write-Host \"Nothing to do here...\"\n    }\n\n    exit 0\n}\n\n# No existing Certificates - Lets get some new ones.\nWrite-Host \"No existing certificates found for $($LE_AzureDNS_CertificateDomain).\"\nWrite-Host \"Request New Certificate for $($LE_AzureDNS_CertificateDomain) from Lets Encrypt\"\n\n# New Certificate..\n$le_certificate = Get-LetsEncryptCertificate\n\nWrite-Host \"Publishing: LetsEncrypt - $($LE_AzureDNS_CertificateDomain) (PFX)\"\n$certificate_as_json = Get-NewCertificatePFXAsJson -Certificate $le_certificate\nPublish-OctopusCertificate -JsonBody $certificate_as_json\n\nWrite-Host \"GREAT SUCCESS\"\n",
    "Octopus.Action.SubstituteInFiles.Enabled": "True"
  },
  "Category": "Lets Encrypt",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates/letsencrypt-azure-dns.json",
  "Website": "/step-templates/79e0dd12-6222-4f8a-a8dc-bcbe579ed729",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Wednesday, August 12, 2026