This open source project is community-supported. To report a problem or share an idea, use
Issues; and if you have a suggestion for fixing the issue, please include those details, too.
In addition, use Pull Requests to contribute actual bug fixes or proposed enhancements.
We welcome and appreciate all contributions. Got questions or want to discuss something with our team?
Join us on Slack!
This solution adds certificate enrollment capabilities to HashiCorp Terraform by seamlessly integrating with the CyberArk Certificate Manager, Self-Hosted or CyberArk Certificate Manager, SaaS in a manner that ensures compliance with corporate security policy and provides visibility into certificate issuance enterprise wide.
π Test drive our integration examples today
Let us show you step-by-step how to add certificates to your Infrastucture as Code automation using Terraform.
NOTE If you don't see an example for a product you use, check back later. We're working hard to add more integration examples.
Make sure that you are protecting your terraform state file as per the best practices by Hashicorp:
https://developer.hashicorp.com/terraform/language/state/sensitive-data.
This is an important step to prevent data breaches or leaks of sensitive data like usernames, passwords, tokens,
secrets, etc.
Your certificate authority (CA) must be able to issue a certificate in under one minute. Microsoft Active Directory Certificate Services (ADCS) is a popular choice. Other CA choices may have slightly different requirements.
Within CyberArk Certificate Manager, Self-Hosted, configure these settings.
-
A user account that has an authentication token for the
Venafi Provider for HashiCorp Terraform(IDhashicorp-terraform-by-venafi) API Application as of 20.1 (or scopecertificate:managefor 19.2 through 19.4) or has been granted WebSDK Access (deprecated). -
A Policy folder where the user has the following permissions:
View,Read,Write,Create. -
Enterprise compliant policies applied to the folder including:
- Subject DN values for Organizational Unit (OU), Organization (O), City/Locality (L), State/Province (ST) and Country (C).
- CA Template that CyberArk Certificate Manager, Self-Hosted will use to enroll general certificate requests.
- Management Type not locked or locked to
Enrollment. - Certificate Signing Request (CSR) Generation unlocked or not locked to
Service Generated CSR. - Generate Key/CSR on Application not locked or locked to
No. - Private Key PBE Algorithm to either
SHA1 3DESorSHA256 AES256toService Generated CSR. - (Recommended) Disable Automatic Renewal set to
Yes. - (Recommended) Key Bit Strength set to
2048or higher. - (Recommended) Domain Whitelisting policy appropriately assigned.
NOTE: If you are using Microsoft ACDS, the CRL distribution point and Authority Information Access (AIA) URIs must start with an HTTP URI (non-default configuration). If an LDAP URI appears first in the X509v3 extensions, some applications will fail, such as NGINX ingress controllers. These applications aren't able to retrieve CRL and OCSP information.
The CyberArk Certificate Manager, Self-Hosted REST API (WebSDK) must be secured with a certificate. Generally, the certificate is issued by a CA that is not publicly trusted so establishing trust is a critical part of your setup.
Two methods can be used to establish trust. Both require the trust anchor (root CA certificate) of the WebSDK
certificate. If you have administrative access, you can import the root certificate into the trust store for your
operating system. If you don't have administrative access, or prefer not to make changes to your system configuration,
save the root certificate to a file in PEM format (e.g. /opt/cyberark/bundle.pem) and include it using the trust_bundle
parameter of your Venafi Provider.
The Venafi Provider offers several authentication methods to CyberArk Certificate Manager, Self-Hosted. All of them work by requesting an access token that will grant access to the REST API. Automation becomes complex to manage when access tokens are introduced as they have an expiration date. When that date is met, the token is no longer valid.
A new Venafi-token provider has been released that allows customers to manage their access tokens. This way the Venafi Provider will always have a valid token to use, and automation will not be disrupted by token expiration.
If you are using CyberArk Certificate Manager, SaaS, verify the following:
- The CyberArk Certificate Manager, SaaS REST API is accessible from the system where Terraform will run. Currently, we support the following regions:
https://api.venafi.cloud[US]https://api.venafi.eu[EU]https://api.au.venafi.cloud[AU]https://api.uk.venafi.cloud[UK]https://api.sg.venafi.cloud[SG]https://api.ca.venafi.cloud[CA]
- You have successfully registered for a CyberArk Certificate Manager, SaaS account, have been granted at least the
Resource Ownerrole, and know your API key. - A CA Account and Issuing Template exist and have been configured with:
- Recommended Settings values for:
- Organizational Unit (OU)
- Organization (O)
- City/Locality (L)
- State/Province (ST)
- Country (C)
- Issuing Rules that:
- (Recommended) Limits Common Name and Subject Alternative Name to domains that are allowed by your organization
- (Recommended) Restricts the Key Length to 2048 or higher
- (Recommended) Does not allow Private Key Reuse
- Recommended Settings values for:
- An Application exists where you are among the owners, and you know the Application name.
- An Issuing Template is assigned to the Application, and you know its API Alias.
The Venafi Provider for HashiCorp Terraform is an officially verified integration. As such, releases are published to
the Terraform Registry where they are available for
terraform init to automatically download whenever the provider is referenced by a configuration file. No setup steps
are required to use an official release of this provider other than to download and install Terraform itself.
To use a pre-release or custom-built version of this provider, manually install the plugin binary into
required directory
using the prescribed subdirectory structure
that must align with how the provider is referenced in the required_providers block of the configuration file.
A Terraform module is a container for multiple resources that are used together and the steps that follow illustrate the resources required to enroll certificates using the Venafi Provider with HashiCorp Terraform 0.13 or higher.
π NOTE: For Terraform 0.12, omit the
required_providersblock and specify any desired version constraints for the provider in theproviderblock using the older way to manage provider versions.
β οΈ We dropped support for RSA PKCS#1 formatted keys for TLS certificates in version 15.0 and also for EC Keys in version 0.15.4 (you can find out more about this transition in here). For backward compatibility during Terraform state refresh please update to version 0.15.5 or above.
β οΈ As a part for upgrading our provider to SDK version 2, we dropped support for Terraform version 0.11 and below.
β οΈ With the introduction of version 0.18.0 the Venafi Provider now incorporates a new feature related to certificate retirement. When an infrastructure is decommissioned, the associated certificate will be automatically retired from the CyberArk Platform (CyberArk Certificate Manager, Self-Hosted and CyberArk Certificate Manager, SaaS).
-
Declare that the Venafi Provider is required:
terraform { required_providers { venafi = { source = "venafi/venafi" version = "~> 0.16.0" } } required_version = ">= 0.13" } -
Specify the connection and authentication settings for the
venafiprovider:CyberArk Certificate Manager, Self-Hosted:
provider "venafi" { url = "https://cmsh.venafi.example" trust_bundle = file("/path/to/bundle.pem") access_token = "p0WTt3sDPbzm2BDIkoJROQ==" zone = "DevOps\\Terraform" }CyberArk Certificate Manager, SaaS:
provider "venafi" { api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS with access token:
provider "venafi" { token_url = "xxxxxxxx-xxxx" external_jwt = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS for EU:
provider "venafi" { url = "https://api.venafi.eu" api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS for AU:
provider "venafi" { url = "https://api.au.venafi.cloud" api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS for UK:
provider "venafi" { url = "https://api.uk.venafi.cloud" api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS for SG:
provider "venafi" { url = "https://api.sg.venafi.cloud" api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }CyberArk Certificate Manager, SaaS for CA:
provider "venafi" { url = "https://api.ca.venafi.cloud" api_key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" zone = "Business App\\Enterprise CIT" }The
venafiprovider has the following options:Property Type Description Env. Variable api_keyString CyberArk Certificate Manager, SaaSAPI keyVENAFI_API access_tokenString CyberArk Certificate Manager, Self-Hostedaccess token for the "hashicorp-terraform-by-venafi" API ApplicationVENAFI_TOKEN client_idString ID of the application that will request tokens. Not necessary when access_tokenprovided. If not provided, defaults tohashicorp-terraform-by-venafiVENAFI_CLIENT_ID external_jwtString JWT of the Identity Provider associated to a CyberArk Certificate Manager, SaaSservice account. Use it along withtenant_idto request access tokensVENAFI_EXTERNAL_JWT p12_cert_filenameString Filename of PKCS#12 keystore containing a client certificate, private key, and chain certificates to authenticate to CyberArk Platform VENAFI_P12_CERTIFICATE p12_cert_dataString Base64 encoded PKCS#12 keystore containing a client certificate, private key, and chain certificates to authenticate to CyberArk Platform VENAFI_P12_CERTIFICATE p12_cert_passwordString Password for the PKCS#12 keystore declared in p12_cert_filenameVENAFI_P12_PASSWORD token_urlString URL to request an access token from CyberArk Certificate Manager, SaaS. Use it along withexternal_jwtVENAFI_TENANT_ID tpp_usernameString [DEPRECATED] CyberArk Certificate Manager, Self-Hosted WebSDK username, use access_tokenif possibleVENAFI_USER tpp_passwordString [DEPRECATED] CyberArk Certificate Manager, Self-Hosted WebSDK password, use access_tokenif possibleVENAFI_PASS trust_bundleString Text file containing trust anchor certificates in PEM format, generally required for CyberArk Certificate Manager, Self-Hosted urlString CyberArk Certificate Manager, Self-Hostedservice URL (e.g. "https://cmsh.cyberark.example")VENAFI_URL zoneString Policy folder for CyberArk Certificate Manager, Self-Hostedor Application name and Issuing Template API Alias forCyberArk Certificate Manager, SaaS(e.g. "Business App\Enterprise CIT")VENAFI_ZONE skip_retirementBoolean When truethe certificate retirement on the related CyberArk Platform (CyberArk Certificate Manager, Self-HostedorCyberArk Certificate Manager, SaaS) will be skippedVENAFI_SKIP_RETIREMENT dev_modeBoolean When true, the provider operates without connecting toCyberArk Certificate Manager, Self-HostedorCyberArk Certificate Manager, SaaSVENAFI_DEVMODE π NOTE: The indicated environment variables can be used to specify values for provider settings rather than including them in a configuration file. Avoid specifying a value for
api_keyunless you are using CyberArk Certificate Manager, SaaS since that variable is used by the provider to decide which CyberArk product to use. -
Create a
venafi_certificateresource that will generate a new key pair and enroll the certificate needed by atls_serverapplication:resource "venafi_certificate" "tls_server" { common_name = "web.venafi.example" san_dns = [ "web01.venafi.example", "web02.venafi.example" ] algorithm = "RSA" rsa_bits = "2048" key_password = "${var.pk_pass}" }The
venafi_certificateresource has the following options, onlycommon_nameis required:π NOTE: Updating only
expiration_windowwill not trigger another resource to be created by itself, thus won't enroll a new certificate. This won't apply if the expiration_window constraint allows it, this means, if time to expire of the certificate is within the expiration window.Property Type Description Default common_nameString Common name of certificate nonenicknameString Use to specify a name for the new certificate object that will be created and placed in a policy. Only valid for CyberArk Certificate Manager, Self-Hosted. nonesan_dnsList String array of DNS names to use as alternative subjects of the certificate nonesan_emailList String array of email addresses to use as alternative subjects of the certificate nonesan_ipList String array of IP addresses to use as alternative subjects of the certificate nonesan_uriList String array of Uniform Resource Identifiers (URIs) to use as alternative subjects of the certificate nonealgorithmString Key encryption algorithm (i.e. RSA or ECDSA) RSA rsa_bitsInteger Number of bits to use when generating an RSA key pair (i.e. 2048 or 4096). Applies when algorithm=RSA2048 ecdsa_curveString ECDSA curve to use when generating a key pair (i.e. P256, P384, P521). Applies when algorithm=ECDSAP521 key_passwordString Private key password nonecustom_fieldsMap Collection of key-value pairs where the key is the name of the Custom Field in CyberArk Certificate Manager, Self-Hosted. For list type Custom Fields, use the \ character to delimit mulitple values.
Example:custom_fields = { "Number List" = "2|4|6" }valid_daysInteger Desired number of days for which the new certificate will be valid noneissuer_hintString Used with valid_daysto indicate the target issuer when using CyberArk Certificate Manager, Self-Hosted and the CA is DigiCert, Entrust, or Microsoft.
Example:issuer_hint = "Microsoft"noneexpiration_windowInteger Number of hours before certificate expiry to request a new certificate 168 csr_originString Option to decide whether key-pair generation will be localorservicegeneratedlocalπ NOTE: The
venafi_certificateresource handles certificate renewals as long as aterraform applyis done within theexpiration_windowperiod. Keep in mind that theexpiration_windowin the Terraform configuration needs to align with the renewal window of the issuing CA to achieve the desired result.After enrollment, the
venafi_certificateresource will expose the following:Property Type Description private_key_pemString Private key in PEM format encrypted using key_password, if specifiedchainString Trust chain CA certificate(s) in PEM format concatenated one after the other certificateString End-entity certificate in PEM format pkcs12String Base64-encoded PKCS#12 keystore encrypted using key_password, if specified. Useful when working with resources like azurerm_key_vault_certificate. Base64 decode to obtain file bytes. -
For verification purposes, output the certificate, private key, and chain in PEM format and as a PKCS#12 keystore (base64-encoded):
output "my_private_key" { value = venafi_certificate.tls_server.private_key_pem sensitive = true } output "my_certificate" { value = venafi_certificate.tls_server.certificate } output "my_trust_chain" { value = venafi_certificate.tls_server.chain } output "my_p12_keystore" { value = venafi_certificate.tls_server.pkcs12 } -
Execute
terraform init,terraform plan,terraform apply, and finallyterraform showfrom the directory containing the configuration file.
π NOTE: Don't specify an
expiration_windowwithin your Terraform file when importing, since will trigger a new update on re-applying your configuration unless that's desired. By default, we set a value of168hours.
π NOTE: This operation doesn't support
issuer_hintamong the attributes for importing, neither local generated certificate key-pair.
The venafi_certificate resource supports the Terraform import
method.
The import_id is composed by an id which is different for each platform, a comma (,) and the key-password.
The id for each platform is:
CyberArk Certificate Manager, Self-Hosted:
The nickname of the certificate, which represents the name of the certificate object in CyberArk Certificate Manager, Self-Hosted. Internally we built the pickup_id using the zone defined at the provider block.
π NOTE: The certificate object name at CyberArk Certificate Manager, Self-Hosted, usually, should be the same as the
common_nameprovided as it is considered good practice, but thenicknameactually could differ from the common name, as there some use cases whenever you want to handle certificates with different nicknames. For example, you could have certificates with same common name and different SANs, then, you could manage many certificate resources that share the same common name usingfor_eachandcountmeta arguments.
CyberArk Certificate Manager, SaaS:
The pickup-id.
π NOTE: You can learn more about the
pickup-idand pickup actions for CyberArk Certificate Manager, Self-Hosted here, and for CyberArk Certificate Manager, SaaS, here
terraform import "venafi_certificate.<resource_name>" "<id>,<key-password>"Example (assuming our resource name is imported_certificate):
resource "venafi_certificate" "imported_certificate" {}CyberArk Certificate Manager, Self-Hosted:
terraform import "venafi_certificate.imported_certificate" "tpp.venafi.example,my_key_password"CyberArk Certificate Manager, SaaS:
terraform import "venafi_certificate.imported_certificate" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,my_key_password"-
Declare that the Venafi Provider and specify the connection and authentication settings as described in the previous section.
π NOTE: For CyberArk Certificate Manager, Self-Hosted, the
access_tokenassigned to thevenafiprovider must have the configuration:manage scope in order to apply certificate policy. -
Create a
venafi_policyresource that will create or update the certificate policy for a CyberArk zone:resource "venafi_policy" "tls_server_certificates" { zone = "My Business App\\Server Certificates" policy_specification = file("/path/to/tls_server_cert_policy.json") }The
venafi_policyresource has the following options, all of which are required when setting policy:Property Type Description Default zoneString The CyberArk Certificate Manager, Self-Hosted policy folder or CyberArk Certificate Manager, SaaS application and issuing template nonepolicy_specificationString The JSON-formatted certificate policy specification as documented here. Typically read from a file using the file function. Use the VCert CLI to generate a policy specification template to get started (i.e. vcert getpolicy --starter)noneπ NOTE: The
venafi_policyresource supports theterraform importmethod. When used, thezoneandpolicy_specificationoptions are not required since the zone is a required parameter of the import method and the policy specification is populated from the existing infrastructure. Policy that is successfully imported is also output to a file named after the zone that was specified. The certificate:manage scope is require to import policy from CyberArk Certificate Manager, Self-Hosted.
-
Declare the Venafi Provider and specify the connection and authentication settings as described in the previous sections.
π NOTE: For CyberArk Certificate Manager, Self-Hosted, the access_token assigned to the Venafi Provider must have the ssh:manage scope in order to create SSH certificates.
CyberArk Certificate Manager, Self-Hosted:
provider "venafi" { url = "https://cmsh.cyberark.example" trust_bundle = file("/path/to/bundle.pem") access_token = "p0WTt3sDPbzm2BDIkoJROQ==" } -
Create a resource
venafi_ssh_certificatethat will generate a new key pair and enroll the ssh certificate needed by a remote host:resource "venafi_ssh_certificate" "remote-host" { key_id = "my_remote" template = "devops-terraform" public_key_method = "service" source_address = ["test.com"] key_passphrase = "abcd" extension = ["[email protected]:[email protected]"] valid_hours = 4 }The
venafi_ssh_certificateresource has the following options, which onlykey_idandtemplateare required:Property Type Description Default key_idString The identifier of the requested certificate nonetemplateString The certificate issuing template nonekey_passphraseString Passphrase for encrypting the private key nonefolderString The DN of the policy folder where the certificate object will be created. It will overwrite the default folder set at the template noneforce_commandString The requested force command nonekey_sizeInt The key size bits, they will be used for creating keypair 3072windowsBool Output certificate and key files in Windows format (i.e. with \r\n line endings) instead of Unix format (i.e. \n line endings). falsevalid_hoursInt How much time the requester wants to have the certificate valid, the format is hours noneobject_nameString The friendly name for the certificate object. If not specified, the value of the key_idis used.nonepublic_keyString The path of the public key that will be used to generate the certificate if public_key_methodset tofilenonepublic_key_methodString If the public key will be: localorservicegenerated orfileprovidedlocalprincipalList [DEPRECATED] This will be removed in the future. Use principalsinstead. The requested principalsnoneprincipalsList The requested principals nonesource_addressList The requested source addresses as list of IP/CIDR nonedestination_addressList The address (FQDN/hostname/IP/CIDR) of the destination host where the certificate will be used for authentication. Applicable for client certificates and is used for reporting/auditing only. noneextensionList The requested certificate extensions none -
Create a resource
venafi_ssh_configthat will hold configuration needed by a remote host:resource "venafi_ssh_config" "cit" { template = "devops-terraform-cit" }The
venafi_ssh_configresource has the following option, which is required when obtaining configuration from the template:Property Type Description Default templateString The certificate issuing template noneIn addition, the following attributes are exported:
Property Type Description ca_public_keyString The template's CA PublicKey principalsList The requested principals
Copyright Β© Venafi, Inc. and CyberArk Software Ltd. ("CyberArk")
This solution is licensed under the Mozilla Public License, Version 2.0. See LICENSE for the full license text.
Please direct questions/comments to [email protected].