Venafi TPP - Create and Provision Certificate

Octopus.Script exported 2021-08-23 by harrisonmeister belongs to ‘Venafi’ category.

This step template will authenticate against a Venafi TPP instance using an existing OAuth access token, and create a new certificate as well as optionally associate and push the new certificate to specified existing application(s). This is achieved using a combination of two functions from the VenafiPS PowerShell module:

  1. New-TppCertificate which is an alias of the New-VdcCertificate function.
  2. Add-TppCertificateAssociation which is an alias of the Add-VdcCertificateAssociation function.

Options:

  • Provide a distinguished name (DN) path for the new certificate.
  • Provide a name for the new certificate.
  • Provide a common name (CN) for the new certificate.
  • Optional - Provide the distinguished name (DN) path to a certificate authority template to be used for the new certificate.
  • Optional - Choose from the following certificate types:
    • Code Signing
    • Device
    • Server
    • User
  • Optional - Choose from the following certificate management types:
    • Enrollment
    • Provisioning
    • Monitoring
    • Unassigned
  • Optional - Provide subject alternate names for the new certificate using the following acceptable SAN types:
    • OtherName
    • Email
    • DNS
    • URI
    • IPAdress
  • Optional - Choose if you would like the step to wait for the certificate to finishing provisioning before moving on.
  • Optional - Choose the maximum time in seconds that you would like the step to wait for provisioning to finish.
  • Optional - Provide the application(s) path to associate the new certificate to.
  • Optional - Choose to push the new certificate to the specified application(s).
  • Optional - Choose to revoke the access token used on successful completion.

Required:

  • The VenafiPS PowerShell module installed on the deployment target or worker. If the module can’t be found, the step will attempt to download a version from the PowerShell gallery.

Notes:

  • Tested on Octopus 2021.2.
  • Tested with VenafiPS 3.1.5.
  • Tested with both Windows PowerShell and PowerShell Core on Linux.

Parameters

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

Venafi TPP Server

Venafi.TPP.CreateCert.Server =

Required: The URL of the Venafi TPP instance you want to create a certificate in.

For example : https://mytppserver.example.com

Venafi TPP Access Token

Venafi.TPP.CreateCert.AccessToken =

Required: The access token to authenticate against the TPP instance.

Venafi TPP Certificate Path

Venafi.TPP.CreateCert.DNPath =

Required: The Distinguished Name (DN) of the certificate you wish to create. This is the absolute path to the certificate in the TPP instance, separated by \.

Certificate Name

Venafi.TPP.CreateCert.Name =

Required: Name of the certificate to be created.

Certificate Subject Common Name

Venafi.TPP.CreateCert.SubjectCN =

Required: Subject common name (CN) of the certificate to be created.

Venafi TPP Certificate Authority Path (Optional)

Venafi.TPP.CreateCert.CertificateAuthorityDN =

Optional: The Distinguished Name (DN) of the certificate authority you wish to use. This is the absolute path to a certificate authority template in the TPP instance, separated by \.

Venafi TPP Certificate Type (Optional)

Venafi.TPP.CreateCert.Type = Server

Optional: Type of certificate to be created. Valid options are:

  • Code Signing
  • Device
  • Server (Default)
  • User

Venafi TPP Certificate Management Type (Optional)

Venafi.TPP.CreateCert.ManagementType = Enrollment

Optional: The level of management that Trust Protection Platform applies to the certificate. Valid options are:

  • Enrollment: (Default) Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Do not automatically provision the certificate.
  • Provisioning: Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Automatically install or provision the certificate.
  • Monitoring: Allow Trust Protection Platform to monitor the certificate for expiration and renewal.
  • Unassigned: Certificates are neither enrolled or monitored by Trust Protection Platform.

Venafi TPP Certificate Subject Alternate Names (Optional)

Venafi.TPP.CreateCert.SubjectAltNames =

Optional: A list of Subject Alternate Names. The value must be 1 or more lines with the SAN type and value. Each SAN type needs to be separated by a ;. Acceptable SAN types are OtherName, Email, DNS, URI, and IPAddress. You can provide more than 1 of the same SAN type with multiple lines.

For example:

DNS=octopus.local.samples;Email=octopus@email.com
DNS=octopus.samples;IPAddress=0.0.0.0

Wait for certificate provisioning?

Venafi.TPP.CreateCert.ProvisioningWait = false

If the new certificate has a management type of Provisioning should the step wait for the provisioning to complete?

Max wait time for certificate provisioning.

Venafi.TPP.CreateCert.ProvisioningTimeout = 600

The max about of time in seconds you want the step to wait for the certificate to be provisioned.

Venafi TPP Application Path (Optional)

Venafi.TPP.CreateCert.ApplicationPath =

Optional: A comma separated list of application paths to associate with the new certificate. Each value in the list is the absolute path to an application in the TPP instance, separated by \.

Push certificate to associated application?

Venafi.TPP.CreateCert.PushCertificate = false

Push the newly created certificate to the applications

Revoke access token on completion?

Venafi.TPP.CreateCert.RevokeTokenOnCompletion = false

Should the access token used be revoked once the step has been completed successfully? Default: False.

Script body

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

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ErrorActionPreference = 'Stop'
# Variables
$Server = $OctopusParameters["Venafi.TPP.CreateCert.Server"]
$Token = $OctopusParameters["Venafi.TPP.CreateCert.AccessToken"]
$CertPath = $OctopusParameters["Venafi.TPP.CreateCert.DNPath"]
$CertName = $OctopusParameters["Venafi.TPP.CreateCert.Name"]
$CertCommonName = $OctopusParameters["Venafi.Tpp.CreateCert.SubjectCN"]
# Optional
$CertCAPath = $OctopusParameters["Venafi.Tpp.CreateCert.CertificateAuthorityDN"]
$CertType = $OctopusParameters["Venafi.Tpp.CreateCert.Type"]
$CertManagementType = $OctopusParameters["Venafi.Tpp.CreateCert.ManagementType"]
$CertSubjectAltNames = $OctopusParameters["Venafi.Tpp.CreateCert.SubjectAltNames"]
$CertProvisionWait = $OctopusParameters["Venafi.TPP.CreateCert.ProvisioningWait"]
$CertProvisionTimeout = $OctopusParameters["Venafi.TPP.CreateCert.ProvisioningTimeout"]
$ApplicationPath = $OctopusParameters["Venafi.TPP.CreateCert.ApplicationPath"]
$ApplicationPush = $OctopusParameters["Venafi.TPP.CreateCert.PushCertificate"]
$RevokeToken = $OctopusParameters["Venafi.TPP.CreateCert.RevokeTokenOnCompletion"]
# Validation
if ([string]::IsNullOrWhiteSpace($Server)) {
    throw "Required parameter Venafi.TPP.CreateCert.Server not specified"
}
if ([string]::IsNullOrWhiteSpace($Token)) {
    throw "Required parameter Venafi.TPP.CreateCert.AccessToken not specified"
}
if ([string]::IsNullOrWhiteSpace($CertPath)) {
    throw "Required parameter Venafi.TPP.CreateCert.DNPath not specified"
}
if ([string]::IsNullOrWhiteSpace($CertName)) {
    throw "Required parameter Venafi.TPP.CreateCert.Name not specified"
}
if ([string]::IsNullOrWhiteSpace($CertCommonName)) {
    throw "Required parameter Venafi.TPP.CreateCert.SubjectCN not specified"
}

$SecureToken = ConvertTo-SecureString $Token -AsPlainText -Force
[PSCredential]$AccessToken = New-Object System.Management.Automation.PsCredential("token", $SecureToken)
# Clean-up
$Server = $Server.TrimEnd('/')
# Required Modules
function Get-NugetPackageProviderNotInstalled {
    # See if the nuget package provider has been installed
    return ($null -eq (Get-PackageProvider -ListAvailable -Name Nuget -ErrorAction SilentlyContinue))
}
# Check to see if the package provider has been installed
if ((Get-NugetPackageProviderNotInstalled) -ne $false) {
    Write-Host "Nuget package provider not found, installing ..."    
    Install-PackageProvider -Name Nuget -Force -Scope CurrentUser
}
Write-Host "Checking for required VenafiPS module ..."
$required_venafips_version = 3.1.5
$module_available = Get-Module -ListAvailable -Name VenafiPS | Where-Object { $_.Version -ge $required_venafips_version }
if (-not ($module_available)) {
    Write-Host "Installing VenafiPS module ..."
    Install-Module -Name VenafiPS -MinimumVersion 3.1.5 -Scope CurrentUser -Force
}
else {
    $first_match = $module_available | Select-Object -First 1 
    Write-Host "Found version: $($first_match.Version)"
}
Write-Host "Importing VenafiPS module ..."
Import-Module VenafiPS
Write-Host "Requesting new session from $Server"
New-VenafiSession -Server $Server -AccessToken $AccessToken
# New certificate
$NewCert_Params = @{
    Path       = $CertPath;
    Name       = $CertName;
    CommonName = $CertCommonName
}
# Optional CertificateType field
if (-not [string]::IsNullOrWhiteSpace($CertType)) {
    $NewCert_Params.CertificateType = $CertType
}
# Optional CertificateAuthorityPath field
if (-not [string]::IsNullOrWhiteSpace($CertCAPath)) {
    $NewCert_Params.CertificateAuthorityPath = $CertCAPath
}
# Optional ManagementType field
if (-not [string]::IsNullOrWhiteSpace($CertManagementType)) {
    $NewCert_Params.ManagementType = $CertManagementType
}
# Optional SubjectAltName field
if (-not [string]::IsNullOrWhiteSpace($CertSubjectAltNames)) {
    $SubjectAltNames = @()
    $SubjectAltNameStrings = $CertSubjectAltNames -split "`n"
    foreach ($SubjectAltNameString in $SubjectAltNameStrings) {
        if (-not [string]::IsNullOrWhiteSpace($SubjectAltNameString)) {
            $ReplacedString = $SubjectAltNameString.Trim().Replace(";", "`n")
            $StringAsHash = $ReplacedString | ConvertFrom-StringData
            $SubjectAltNames += $StringAsHash
        }
    }
    $NewCert_Params.SubjectAltName = $SubjectAltNames
}
# Generate New Certificate
Write-Host "Creating certificate '$CertName' ($CertPath)..."
$NewCertificate = New-TppCertificate @NewCert_Params -PassThru
$count = 0
$Continue = $True
# Wait for certificate provisioning
if ($CertProvisionWait -eq $true -and $CertManagementType -eq "Provisioning") {
    $EndWait = (Get-Date).AddSeconds($CertProvisionTimeout)
    do {
        if ($count -gt 0) { 
            Write-Host "Waiting 30 seconds for certificate to provision..."
            Start-Sleep -Seconds 30
        }
        $count++
        Write-Host "Checking certificate provisioning status."
        $CertDetails = Get-VenafiCertificate -CertificateId $NewCertificate.Path
        Write-Verbose "ProcessingDetails: $($CertDetails.ProcessingDetails)"
        if (-not "$($CertDetails.ProcessingDetails)") {
            $Continue = $False
            Write-Host "Successful certificate provisioning detected."
        }
        elseif ($CertDetails.ProcessingDetails.InError -eq $True -or $CertDetails.ProcessingDetails.Status -eq "Failure") {
            $Continue = $False
            Write-Error "Certificate failed to provision at Stage: $($CertDetails.ProcessingDetails.Stage), Status: $($CertDetails.ProcessingDetails.Status)"
        }
    } until ($Continue -eq $False -or (Get-Date) -ge $EndWait)
}
# Associate Certificate with application
if (-not [string]::IsNullOrWhiteSpace($ApplicationPath)) {
    $ApplicationPathArray = @()
    if ($ApplicationPath.Contains(",")) {
        $ApplicationPathArray = $ApplicationPath.Split(",")
    }
    else {
        $ApplicationPathArray += $ApplicationPath
    }

    if ($CertProvisionWait -eq $false) {
    	Write-Warning "Associating the certificate $CertName with  application(s) at path(s) ($ApplicationPath) may be ongoing as waiting for provisioning is set to False. This could result in a failed association."
    }

    if ($ApplicationPush -eq $true) {
        Write-Host "Associating and pushing certificate to application at $ApplicationPath"
        Add-TppCertificateAssociation -CertificatePath $NewCertificate.Path -ApplicationPath $ApplicationPathArray -PushCertificate
    }
    else {
        Write-Host "Associating certificate to application at $ApplicationPath"
        Add-TppCertificateAssociation -CertificatePath $NewCertificate.Path -ApplicationPath $ApplicationPathArray
    }
}
if ($RevokeToken -eq $true) {
    # Revoke TPP access token
    Write-Host "Revoking access token with $Server"
    Revoke-TppToken -AuthServer $Server -AccessToken $AccessToken -Force
}

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": "dd4dfa66-e632-4c6a-bae6-156a7a105023",
  "Name": "Venafi TPP - Create and Provision Certificate",
  "Description": "This step template will authenticate against a Venafi TPP instance using an existing OAuth access token, and create a new certificate as well as optionally associate and push the new certificate to specified existing application(s). This is achieved using a combination of two functions from the VenafiPS PowerShell module:\n\n1. `New-TppCertificate` which is an alias of the [New-VdcCertificate](https://venafips.readthedocs.io/en/latest/functions/New-VdcCertificate/) function.\n2. `Add-TppCertificateAssociation` which is an alias of the [Add-VdcCertificateAssociation](https://venafips.readthedocs.io/en/latest/functions/Add-VdcCertificateAssociation/) function.\n\n---\n\n**Options:**\n\n- Provide a distinguished name (DN) path for the new certificate.\n- Provide a name for the new certificate.\n- Provide a common name (CN) for the new certificate.\n- *Optional* - Provide the distinguished name (DN) path to a certificate authority template to be used for the new certificate.\n- *Optional* - Choose from the following certificate types:\n  - `Code Signing`\n  - `Device`\n  - `Server`\n  - `User`\n- *Optional* - Choose from the following certificate management types:\n  - `Enrollment`\n  - `Provisioning`\n  - `Monitoring`\n  - `Unassigned`\n- *Optional* - Provide subject alternate names for the new certificate using the following acceptable SAN types: \n  - `OtherName`\n  - `Email`\n  - `DNS`\n  - `URI`\n  - `IPAdress`\n- *Optional* - Choose if you would like the step to wait for the certificate to finishing provisioning before moving on.\n- *Optional* - Choose the maximum time in seconds that you would like the step to wait for provisioning to finish.\n- *Optional* - Provide the application(s) path to associate the new certificate to.\n- *Optional* - Choose to push the new certificate to the specified application(s).\n- *Optional* - Choose to revoke the access token used on successful completion.\n\n---\n\n**Required:** \n- The `VenafiPS` PowerShell module installed on the deployment target or worker. If the module can't be found, the step will attempt to download a version from the [PowerShell gallery](https://www.powershellgallery.com/packages/VenafiPS).\n\nNotes:\n\n- Tested on Octopus `2021.2`.\n- Tested with VenafiPS `3.1.5`.\n- Tested with both Windows PowerShell and PowerShell Core on Linux.\n",
  "Version": 2,
  "ExportedAt": "2021-08-23T21:42:40.319Z",
  "ActionType": "Octopus.Script",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Id": "28b7cc35-41dc-4759-afc0-3ee8ded24a4b",
      "Name": "Venafi.TPP.CreateCert.Server",
      "Label": "Venafi TPP Server",
      "HelpText": "*Required*: The URL of the Venafi TPP instance you want to create a certificate in.\n\nFor example : `https://mytppserver.example.com`",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "58bf5279-d9a6-4129-81fc-9806a836e0a0",
      "Name": "Venafi.TPP.CreateCert.AccessToken",
      "Label": "Venafi TPP Access Token",
      "HelpText": "*Required*: The access token to authenticate against the TPP instance.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "52140bce-2c49-46df-9858-145183a76614",
      "Name": "Venafi.TPP.CreateCert.DNPath",
      "Label": "Venafi TPP Certificate Path",
      "HelpText": "*Required*: The Distinguished Name (DN) of the certificate you wish to create. This is the absolute path to the certificate in the TPP instance, separated by `\\`.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "caf96139-f59d-4d79-b076-7cba155e5da6",
      "Name": "Venafi.TPP.CreateCert.Name",
      "Label": "Certificate Name",
      "HelpText": "*Required*: Name of the certificate to be created.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "2dcab218-b4e3-4076-a05d-6d4b649fda80",
      "Name": "Venafi.TPP.CreateCert.SubjectCN",
      "Label": "Certificate Subject Common Name",
      "HelpText": "*Required*: Subject common name (CN) of the certificate to be created. ",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "040d9226-c782-47d6-b085-977f43b3f0cc",
      "Name": "Venafi.TPP.CreateCert.CertificateAuthorityDN",
      "Label": "Venafi TPP Certificate Authority Path (Optional)",
      "HelpText": "*Optional*: The Distinguished Name (DN) of the certificate authority you wish to use. This is the absolute path to a certificate authority template in the TPP instance, separated by `\\`.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "c8863e1f-0e3b-49a4-aafc-d765b103c89a",
      "Name": "Venafi.TPP.CreateCert.Type",
      "Label": "Venafi TPP Certificate Type (Optional)",
      "HelpText": "*Optional*: Type of certificate to be created. Valid options are:\n\n- `Code Signing`\n- `Device`\n- `Server` (**Default**)\n- `User`",
      "DefaultValue": "Server",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "Code Signing|Code Signing\nDevice|Device\nServer|Server\nUser|User"
      }
    },
    {
      "Id": "53b52bb0-64cf-4d11-bc66-f9e22b54c2a0",
      "Name": "Venafi.TPP.CreateCert.ManagementType",
      "Label": "Venafi TPP Certificate Management Type (Optional)",
      "HelpText": "*Optional*: The level of management that Trust Protection Platform applies to the certificate. Valid options are:\n\n- `Enrollment`: (**Default**) Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Do not automatically provision the certificate. \n- `Provisioning`: Issue a new certificate, renewed certificate, or key generation request to a CA for enrollment. Automatically install or provision the certificate.\n- `Monitoring`: Allow Trust Protection Platform to monitor the certificate for expiration and renewal.\n- `Unassigned`: Certificates are neither enrolled or monitored by Trust Protection Platform.",
      "DefaultValue": "Enrollment",
      "DisplaySettings": {
        "Octopus.ControlType": "Select",
        "Octopus.SelectOptions": "Enrollment|Enrollment\nProvisioning|Provisioning\nMonitoring|Monitoring\nUnassigned|Unassigned"
      }
    },
    {
      "Id": "a3306c46-a69d-4bdf-816b-0bac12276b6c",
      "Name": "Venafi.TPP.CreateCert.SubjectAltNames",
      "Label": "Venafi TPP Certificate Subject Alternate Names (Optional)",
      "HelpText": "*Optional*: A list of Subject Alternate Names. The value must be 1 or more lines with the SAN type and value. Each SAN type needs to be separated by a `;`. Acceptable SAN types are `OtherName`, `Email`, `DNS`, `URI`, and `IPAddress`. You can provide more than 1 of the same SAN type with multiple lines.\n\n**For example**: \n```md\nDNS=octopus.local.samples;Email=octopus@email.com\nDNS=octopus.samples;IPAddress=0.0.0.0\n```",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "3014d2f1-789c-4640-91e1-ee7ddb5661e7",
      "Name": "Venafi.TPP.CreateCert.ProvisioningWait",
      "Label": "Wait for certificate provisioning?",
      "HelpText": "If the new certificate has a management type of `Provisioning` should the step wait for the provisioning to complete?",
      "DefaultValue": "false",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "88386d92-8536-4be4-8a8f-2f5fd8d3242b",
      "Name": "Venafi.TPP.CreateCert.ProvisioningTimeout",
      "Label": "Max wait time for certificate provisioning.",
      "HelpText": "The max about of time in seconds you want the step to wait for the certificate to be provisioned.",
      "DefaultValue": "600",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "e9e84efe-28e1-437c-9c79-845a59a7e89e",
      "Name": "Venafi.TPP.CreateCert.ApplicationPath",
      "Label": "Venafi TPP Application Path (Optional)",
      "HelpText": "*Optional*: A comma separated list of application paths to associate with the new certificate. Each value in the list is the absolute path to an application in the TPP instance, separated by `\\`.\n\n",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "3bfc02d2-4711-4a21-821d-9add5de603d7",
      "Name": "Venafi.TPP.CreateCert.PushCertificate",
      "Label": "Push certificate to associated application?",
      "HelpText": "Push the newly created certificate to the applications",
      "DefaultValue": "false",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    },
    {
      "Id": "38eaa04c-6e4c-4d7d-b119-0631dfb7a490",
      "Name": "Venafi.TPP.CreateCert.RevokeTokenOnCompletion",
      "Label": "Revoke access token on completion?",
      "HelpText": "Should the access token used be revoked once the step has been completed successfully? Default: `False`.",
      "DefaultValue": "false",
      "DisplaySettings": {
        "Octopus.ControlType": "Checkbox"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n$ErrorActionPreference = 'Stop'\n# Variables\n$Server = $OctopusParameters[\"Venafi.TPP.CreateCert.Server\"]\n$Token = $OctopusParameters[\"Venafi.TPP.CreateCert.AccessToken\"]\n$CertPath = $OctopusParameters[\"Venafi.TPP.CreateCert.DNPath\"]\n$CertName = $OctopusParameters[\"Venafi.TPP.CreateCert.Name\"]\n$CertCommonName = $OctopusParameters[\"Venafi.Tpp.CreateCert.SubjectCN\"]\n# Optional\n$CertCAPath = $OctopusParameters[\"Venafi.Tpp.CreateCert.CertificateAuthorityDN\"]\n$CertType = $OctopusParameters[\"Venafi.Tpp.CreateCert.Type\"]\n$CertManagementType = $OctopusParameters[\"Venafi.Tpp.CreateCert.ManagementType\"]\n$CertSubjectAltNames = $OctopusParameters[\"Venafi.Tpp.CreateCert.SubjectAltNames\"]\n$CertProvisionWait = $OctopusParameters[\"Venafi.TPP.CreateCert.ProvisioningWait\"]\n$CertProvisionTimeout = $OctopusParameters[\"Venafi.TPP.CreateCert.ProvisioningTimeout\"]\n$ApplicationPath = $OctopusParameters[\"Venafi.TPP.CreateCert.ApplicationPath\"]\n$ApplicationPush = $OctopusParameters[\"Venafi.TPP.CreateCert.PushCertificate\"]\n$RevokeToken = $OctopusParameters[\"Venafi.TPP.CreateCert.RevokeTokenOnCompletion\"]\n# Validation\nif ([string]::IsNullOrWhiteSpace($Server)) {\n    throw \"Required parameter Venafi.TPP.CreateCert.Server not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($Token)) {\n    throw \"Required parameter Venafi.TPP.CreateCert.AccessToken not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($CertPath)) {\n    throw \"Required parameter Venafi.TPP.CreateCert.DNPath not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($CertName)) {\n    throw \"Required parameter Venafi.TPP.CreateCert.Name not specified\"\n}\nif ([string]::IsNullOrWhiteSpace($CertCommonName)) {\n    throw \"Required parameter Venafi.TPP.CreateCert.SubjectCN not specified\"\n}\n\n$SecureToken = ConvertTo-SecureString $Token -AsPlainText -Force\n[PSCredential]$AccessToken = New-Object System.Management.Automation.PsCredential(\"token\", $SecureToken)\n# Clean-up\n$Server = $Server.TrimEnd('/')\n# Required Modules\nfunction Get-NugetPackageProviderNotInstalled {\n    # See if the nuget package provider has been installed\n    return ($null -eq (Get-PackageProvider -ListAvailable -Name Nuget -ErrorAction SilentlyContinue))\n}\n# Check to see if the package provider has been installed\nif ((Get-NugetPackageProviderNotInstalled) -ne $false) {\n    Write-Host \"Nuget package provider not found, installing ...\"    \n    Install-PackageProvider -Name Nuget -Force -Scope CurrentUser\n}\nWrite-Host \"Checking for required VenafiPS module ...\"\n$required_venafips_version = 3.1.5\n$module_available = Get-Module -ListAvailable -Name VenafiPS | Where-Object { $_.Version -ge $required_venafips_version }\nif (-not ($module_available)) {\n    Write-Host \"Installing VenafiPS module ...\"\n    Install-Module -Name VenafiPS -MinimumVersion 3.1.5 -Scope CurrentUser -Force\n}\nelse {\n    $first_match = $module_available | Select-Object -First 1 \n    Write-Host \"Found version: $($first_match.Version)\"\n}\nWrite-Host \"Importing VenafiPS module ...\"\nImport-Module VenafiPS\nWrite-Host \"Requesting new session from $Server\"\nNew-VenafiSession -Server $Server -AccessToken $AccessToken\n# New certificate\n$NewCert_Params = @{\n    Path       = $CertPath;\n    Name       = $CertName;\n    CommonName = $CertCommonName\n}\n# Optional CertificateType field\nif (-not [string]::IsNullOrWhiteSpace($CertType)) {\n    $NewCert_Params.CertificateType = $CertType\n}\n# Optional CertificateAuthorityPath field\nif (-not [string]::IsNullOrWhiteSpace($CertCAPath)) {\n    $NewCert_Params.CertificateAuthorityPath = $CertCAPath\n}\n# Optional ManagementType field\nif (-not [string]::IsNullOrWhiteSpace($CertManagementType)) {\n    $NewCert_Params.ManagementType = $CertManagementType\n}\n# Optional SubjectAltName field\nif (-not [string]::IsNullOrWhiteSpace($CertSubjectAltNames)) {\n    $SubjectAltNames = @()\n    $SubjectAltNameStrings = $CertSubjectAltNames -split \"`n\"\n    foreach ($SubjectAltNameString in $SubjectAltNameStrings) {\n        if (-not [string]::IsNullOrWhiteSpace($SubjectAltNameString)) {\n            $ReplacedString = $SubjectAltNameString.Trim().Replace(\";\", \"`n\")\n            $StringAsHash = $ReplacedString | ConvertFrom-StringData\n            $SubjectAltNames += $StringAsHash\n        }\n    }\n    $NewCert_Params.SubjectAltName = $SubjectAltNames\n}\n# Generate New Certificate\nWrite-Host \"Creating certificate '$CertName' ($CertPath)...\"\n$NewCertificate = New-TppCertificate @NewCert_Params -PassThru\n$count = 0\n$Continue = $True\n# Wait for certificate provisioning\nif ($CertProvisionWait -eq $true -and $CertManagementType -eq \"Provisioning\") {\n    $EndWait = (Get-Date).AddSeconds($CertProvisionTimeout)\n    do {\n        if ($count -gt 0) { \n            Write-Host \"Waiting 30 seconds for certificate to provision...\"\n            Start-Sleep -Seconds 30\n        }\n        $count++\n        Write-Host \"Checking certificate provisioning status.\"\n        $CertDetails = Get-VenafiCertificate -CertificateId $NewCertificate.Path\n        Write-Verbose \"ProcessingDetails: $($CertDetails.ProcessingDetails)\"\n        if (-not \"$($CertDetails.ProcessingDetails)\") {\n            $Continue = $False\n            Write-Host \"Successful certificate provisioning detected.\"\n        }\n        elseif ($CertDetails.ProcessingDetails.InError -eq $True -or $CertDetails.ProcessingDetails.Status -eq \"Failure\") {\n            $Continue = $False\n            Write-Error \"Certificate failed to provision at Stage: $($CertDetails.ProcessingDetails.Stage), Status: $($CertDetails.ProcessingDetails.Status)\"\n        }\n    } until ($Continue -eq $False -or (Get-Date) -ge $EndWait)\n}\n# Associate Certificate with application\nif (-not [string]::IsNullOrWhiteSpace($ApplicationPath)) {\n    $ApplicationPathArray = @()\n    if ($ApplicationPath.Contains(\",\")) {\n        $ApplicationPathArray = $ApplicationPath.Split(\",\")\n    }\n    else {\n        $ApplicationPathArray += $ApplicationPath\n    }\n\n    if ($CertProvisionWait -eq $false) {\n    \tWrite-Warning \"Associating the certificate $CertName with  application(s) at path(s) ($ApplicationPath) may be ongoing as waiting for provisioning is set to False. This could result in a failed association.\"\n    }\n\n    if ($ApplicationPush -eq $true) {\n        Write-Host \"Associating and pushing certificate to application at $ApplicationPath\"\n        Add-TppCertificateAssociation -CertificatePath $NewCertificate.Path -ApplicationPath $ApplicationPathArray -PushCertificate\n    }\n    else {\n        Write-Host \"Associating certificate to application at $ApplicationPath\"\n        Add-TppCertificateAssociation -CertificatePath $NewCertificate.Path -ApplicationPath $ApplicationPathArray\n    }\n}\nif ($RevokeToken -eq $true) {\n    # Revoke TPP access token\n    Write-Host \"Revoking access token with $Server\"\n    Revoke-TppToken -AuthServer $Server -AccessToken $AccessToken -Force\n}"
  },
  "Category": "Venafi",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/venafi-tpp-create-provision-certificate.json",
  "Website": "/step-templates/dd4dfa66-e632-4c6a-bae6-156a7a105023",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Monday, August 23, 2021