Sectigo Ansible integration

Overview

The Sectigo Ansible integration provides a seamless solution for the enrollment, collection, and revocation of SSL/TLS and client (S/MIME) certificates issued by the Sectigo Certificate Manager (SCM) through Ansible playbooks. The Sectigo Ansible integration is distributed as an Ansible role. It provides the following features:

  • RSA 2048, 3072, and 4096 bit private key generation

  • Certificate Signing Request (CSR)

  • Detailed command line help

The Sectigo Ansible integration supports both the generation of new SSL and client certificates and the detection of existing certificates stored in a location accessible to the role at runtime. The integration also checks the validity of a certificate when an existing certificate is used. There are various types of SSL certificates that can be requested by supplying the appropriate configuration options.

Ansible Sectigo integration
The types of SSL/TLS certificates available to you are based on your account setup.

Prerequisites

The Sectigo Ansible integration has the following prerequisites:

  • Ansible control node:

    • Python 3

    • Ansible 2.7 or 2.8

  • Ansible managed nodes:

    • Python 3

    • Requests 2.22

    • pyOpenSSL 19.0.0

    • SSH daemon

  • SCM API:

    • An SCM organization with Web API access enabled for both SSL and client certificates

    • A list of SSL and client types with associated terms for the organization

The Ansible role has been tested on the following operating systems:

  • Linux CentOS 7.3

  • Ubuntu Server 18.04 LTS

  • Ubuntu 16.04 LTS

  • FreeBSD 11.3

  • FreeBSD 12

The Ansible role is not supported on Windows systems.

Ansible integration package

The Sectigo Ansible integration package for Linux contains the Ansible role for Sectigo which uses a Python module to interact with SCM REST APIs to provision SSL/TLS and client (SMIME) certificates. The package contents are the following:

  • defaults:

    • main.yml: The default variable values

  • library:

    • sectigo_ansible.py: The Sectigo Ansible module

  • meta:

    • main.yml: The role dependencies and metadata

  • module_utils:

    • init.py: A Python Knowledge file

    • sectigo_api_client.py: The utility library for the module

  • tasks: The role tasks

  • tests: Tests and example playbooks

Sectigo Ansible integration package

The module is packaged in a .zip file. If you follow the Ansible best practices for the directory layout, you only need to unzip the package under the roles folder.

The following is an example of the expected layout:

  • my-playbook/: The playbook directory

    • example-playbook.yml: The playbook that uses the role

    • roles/

      • sectigo_ansible/: The sectigo_ansible role directory

Otherwise, unzip in any of the folders defined in your roles search path.

The sectigo_ansible/defaults/main.yml file provides an example variable file with values for each role variable. For more information on running the role, see Running a playbook using the role.

Understanding the integration

Ansible modules are a natural way to simplify the complexity of the Sectigo API. The Ansible module provides higher level constructs and hides the details of the Sectigo API. It also plays the role of adapter between the Ansible playbooks and the REST API.

Components

The Sectigo Ansible integration is based on the following four components:

  • The Python client library for the Sectigo API which handles the communication with the Sectigo REST API.

  • The Ansible module which mediates the interaction between the user and the Sectigo REST API.

  • An Ansible role example which provides a basic role for the certificate issuance that can be tailored to meet specific needs.

  • An Ansible playbook example which shows how to take advantage of the example role from an Ansible playbook.

Sectigo Ansible integration components

Python client library

The Python client library is delivered as a component of the Ansible module. The intended use is that the Ansible module is the only software component interacting with the library.

This library is not designed or delivered as a general-purpose library for Sectigo customers.

Ansible module

The Ansible module comes with documentation available using the standard ansible-doc command line utility. It is delivered as a standard module with minimum dependencies. The full list of dependencies is identified in a pip requirements file. The requirements are also explicitly stated in the documentation.

The Ansible module supports the enrollment, collection, and revocation of SSL and client certificates.

Ansible role and playbook

The Ansible role provides an example and a starting point for customers. The Ansible role also provides the tasks required to install the module requirements. The Ansible playbook comes as an example of how a playbook and role can be used in a typical use case.

Integration deployment

The solution components are required on different nodes in the target environment. Within an environment controlled by Ansible you can identify two main kinds of nodes:

  • Control node: The node where the user invokes Ansible on a playbook

  • Managed node: The target for the execution of the tasks in a playbook or role

An additional node is represented by the Sectigo API Service.

While each user environment is different, these kinds of nodes can be used as basic elements of the deployment model.

Sectigo Ansible integration deployment

The managed nodes server01, server02, and server03 are the servers defined in the Inventory.

Control node

The control node hosts the example playbook and the example role. Ansible must be installed on the control node. The node requires SSH access to the set of managed nodes defined in the inventory.

Managed nodes

The certificate issuance module and the Sectigo Python client will be running on the managed nodes. Ansible ensures that the module code is delivered to each managed node. It is up to the user playbook or role to set up all the module prerequisites on each managed node—​this is usually accomplished with tasks in the playbook or role that installs all the module prerequisites on the target host. The managed nodes will also require access to the internet to contact the Sectigo REST API.

Each certificate is delivered on each managed node.

The connection to the internet is rarely direct. Often an http proxy is restricting access to a limited set of hosts. In such cases, the Sectigo REST API endpoints must be allowed by the proxy configuration.

Local execution

When the user executes the playbook locally, the control node and managed node are the same host.

Sectigo Ansible local execution

The certificate is delivered on the same node where the playbook is executed. In this case, all the prerequisites for a managed node also apply to the control node.

Enrollment logic

The enrollment logic is designed to minimize the chances of issuing an SSL or client certificate by mistake. The module will follow the logic depicted in the following illustration.

Sectigo Ansible enrollment logic

Configuring the Ansible role

The Ansible role requires that certain variables are provided. The variables required are dependent on the specific use case. The variables can be specified as a variable .yml file to the playbook using the role.

Some variables contain sensitive values. For these variables, we strongly encourage the use of ansible-vault for encryption. For more information on using ansible-vault, see the Ansible Vault documentation.

Customer specific parameters

You must provide the following parameters for all SSL and client certificate use cases.

It is also possible to specify the customer specific parameters as environment variables. The names of the environment variables are the same names as parameters but in uppercase—​for example, SECTIGO_CM_USER for sectigo_cm_user.

Values specified as environment variables have precedence over values specified in playbooks. It is suggested that you familiarize yourself with the Ansible variables precedence rules.
Parameter Type Description

sectigo_cm_user

Mandatory

The user ID to access your URI

sectigo_cm_password

Mandatory

The password to access your URI

sectigo_cm_uri

Mandatory

Your specific URI

sectigo_cm_org_id

Mandatory

Your Organization ID (numeric)

sectigo_cm_base_url

Mandatory

The base URL of the Sectigo Certificate Authority

CSR parameters

The following CSR parameters are required for all SSL and client certificate use cases.

Parameter Type Description

sectigo_csr_domain

Conditional

A single value for a domain which is included in the certificate Common Name (CN) field.

Required if sectigo_csr_subject is not provided.

sectigo_csr_subject

Conditional

The certificate signing request subject. If this parameter is provided, then you generate the default RSA 2048-bit private key to be used for the CSR.

Required if the other parameters for the CSR have not been provided.

sectigo_csr_country

Conditional

The country name which is included in the certificate Country (C) field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr_state

Conditional

The state/province name which is included in the certificate State (ST) field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr_location

Conditional

The location name which is included in the certificate Location (L) field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr_organization

Conditional

The organization name which is included in the certificate Organization (O) field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr_organization_unit

Conditional

The organization unit which is included in the certificate Organization Unit (OU) field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr_email_address

Conditional

The email address which is included in the certificate emailAddress field.

Required if sectigo_csr_subject or sectigo_csr is not defined.

sectigo_csr

Conditional

The full path of the certificate signing request file. If this is provided, then the subject parameters will be ignored.

sectigo_csr_key_algo

Optional

The private key algorithm to use to generate the private key. The default value is RSA.

sectigo_csr_key_size

Optional

The size of the TLS/SSL key to generate. The possible values are:

  • 2048-bit (default)

  • 3072-bit

  • 4096-bit

Certificate issuance parameters

The SSL and client certificate issuance use cases support different scenarios that require different parameters.

Parameter Type Description

SSL certificates

sectigo_ssl_cert_file_path

Mandatory

The location where the certificate is to be stored. The same location is used to store the CSR, private key, and enrollment IDs.

sectigo_ssl_cert_file_name

Mandatory

The name of the certificate file. The same name is used for the private key, CSR, and enrollment IDs.

sectigo_ssl_cert_type

Mandatory

The type of SSL certificate (numeric). This is the ID of the SSL certificate type.

sectigo_ssl_cert_validity

Mandatory

The certificate validity period in days (numeric). The available values are dependent on sectigo_ssl_cert_type.

sectigo_ssl_cert_format_type

Optional

The format type for the SSL certificate. The supported values are:

  • x509: X509, Base64 encoded (default)

  • x509CO: X509 Certificate only, Base64 encoded

  • x509IO: X509 Intermediates/Root only, Base64 encoded

  • base64: PKCS#7, Base64 encoded

  • bin: PKCS#7, Bin encoded

  • x509IOR: X509 Intermediates/Root only reverse, Base64 encoded

sectigo_ssl_cert_comments

Optional

Comments for certificate enrollment

sectigo_ssl_cert_num_servers

Conditional

The number of server licenses (numeric)

sectigo_ssl_cert_custom_fields

Optional

The custom fields to be applied to the requested certificate. The expected format for custom fields is the following: [{"name":"custom_field_1","value":"value_1"},{"name":"custom_field_2","value":"value_2"}]. If you are providing this input in a JSON string, make sure that the internal double quotes are escaped properly using \.

sectigo_ssl_cert_server_type

Optional

The server type ID (numeric)

sectigo_ssl_cert_subject_alt_names

Optional

A list of subject alternative names (SAN)

sectigo_ssl_cert_external_requester

Optional

A comma separated list of emails

SSL certificate autorenewal

sectigo_auto_renew

Optional

If true, the auto-renewal option is enabled. The default value is true.

sectigo_ssl_cert_expiry_window

Optional

The period of days (numeric) prior to expiration that a new SSL certificate enrollment process will be initiated if a playbook is executed.

Note: The default expiry window is 7 days.

Client certificates

sectigo_client_cert_file_path

Mandatory

The location where the certificate, CSR, private key, and enrollment IDs are stored.

sectigo_client_cert_file_name

Mandatory

The name of the certificate file. The same name is used for the private key, the CSR, and enrollment IDs.

sectigo_client_cert_first_name

Mandatory

The user’s first name

sectigo_client_cert_middle_name

Conditional

The user’s middle name

sectigo_client_cert_last_name

Mandatory

The user’s last name. The combined length of the first, middle, and last name fields cannot exceed 64 characters.

sectigo_client_cert_email

Mandatory

A valid user email that is less than 256 characters.

sectigo_client_cert_type

Mandatory

The type of certificate (numeric). This is the ID of the client certificate type.

sectigo_client_cert_validity

Mandatory

The certificate validity period in days (numeric). The available values depend on sectigo_client_cert_type.

sectigo_client_cert_custom_fields

Optional

The custom fields to be applied to the requested certificate. The expected format for custom fields is the following: [{"name":"custom_field_1","value":"value_1"},{"name":"custom_field_2","value":"value_2"}]. If you are providing this input in a JSON string, make sure that the internal double quotes are escaped properly using \.

Client certificate autorenewal

sectigo_auto_renew

Optional

If true, the auto-renewal option is enabled. The default value is true.

sectigo_client_cert_expiry_window

Optional

The period of days (numeric) prior to expiration that a new client certificate enrollment process will be initiated if a playbook is executed. The default expiry window is 7 days.

Certificate revocation parameters

SSL and client certificates can be revoked by setting the sectigo_state variable to absent. The SSL and client revocation use cases support the use of the following parameters.

Parameter Type Description

SSL certificates

sectigo_ssl_cert_ssl_id

Mandatory

The ID of the SSL certificate to be revoked

sectigo_reason

Mandatory

The reason why a certificate is to be revoked

Client certificates

sectigo_client_cert_order_number

Mandatory

The order number of the client certificate to be revoked

sectigo_reason

Mandatory

The reason why a certificate is to be revoked

Other parameters

These additional parameters determine the behavior of the role.

Parameter Type Description

sectigo_loop_period

Optional

The interval (in seconds) between repeated attempts to collect a certificate (numeric). The default value is 30.

sectigo_max_timeout

Optional

The maximum time (in seconds) during which repeated attempts to collect a certificate will be made (numeric). The default value is 600.

sectigo_force

Optional

Used to issue a new certificate even if there is already an existing one on the target server (Boolean). The default is false.

sectigo_reason

Optional

The reason why a certificate is to be revoked

Running a playbook using the role

This section provides a few examples on how to use the Sectigo Ansible integration. Additional example playbooks can be found in the tests folder included in the package.

SSL certificate issuance

This example uses the following directory structure:

  • my-playbook/: The playbook directory

    • example-playbook.yml: The playbook that uses the role

    • roles/

      • sectigo_ansible/: The sectigo_ansible role directory

Set up the variables in the example-vars.yml variable file as shown in the following example.

sectigo_cm_user: "your username"
sectigo_cm_password: "your password"
sectigo_cm_uri: "your uri"
sectigo_cm_org_id: 123
sectigo_cm_base_url: "https://myorg.cert-manager.com/api/ssl/v1"
sectigo_csr_subject: "C=CA/ST=ON/L=Ottawa/O=myorg/OU=Research/CN=mydomain.com/[email protected]"
sectigo_ssl_cert_file_path: "/tmp/ssl/mycerts"
sectigo_ssl_cert_file_name: "your-certificate-file"
sectigo_ssl_cert_type: 51
sectigo_ssl_cert_validity: 365
sectigo_ssl_cert_format_type: x509
sectigo_ssl_cert_num_servers: 1
sectigo_ssl_cert_server_type: -1
sectigo_ssl_cert_subject_alt_names: ['example.yourDomain.com', 'yourDomain.com']
sectigo_ssl_cert_comments: "Test certificate for Sectigo"
sectigo_ssl_cert_expiry_window: 7
sectigo_auto_renew: true sectigo_max_timeout: 600
sectigo_loop_period: 30

The following example-playbook.yml playbook can be used to generate a Sectigo SSL certificate using the sectigo_role.

- hosts: localhost
  roles:
    - role: sectigo_ansible

Run the following command from the directory containing example-playbook.yml and example-vars.yml.

ansible-playbook ./example-playbook.yml -e "@example-vars.yml"

The playbook will create the my-certificate-file.crt SSL certificate under the /tmp/ssl/mycerts folder. In the same folder you will also find the following:

  • my-certificate-file.csr: A CSR using the parameters defined in the example-vars.yml file

  • my-certificate-file.key: An RSA private key generated by the Ansible role

  • my-certificate-file.ids: A JSON file containing unique identifiers for the certificate

The same result can be achieved by setting the variables directly in the example-playbook-with-vars.yml playbook as shown in the following example.

- hosts: localhost
  remote_user: root
  vars:
    sectigo_cm_user: "your username"
    sectigo_cm_password: "your password"
    sectigo_cm_uri: "your uri"
    sectigo_cm_org_id: 123
    sectigo_cm_base_url: "https://myorg.cert-manager.com/api/ssl/v1"
    sectigo_csr_subject: "C=CA/ST=ON/L=Ottawa/O=myorg/OU=Research/CN=myorg.com/[email protected]"
    sectigo_ssl_cert_file_path: "/tmp/ssl/mycerts"
    sectigo_ssl_cert_file_name: "my-certificate-file"
    sectigo_ssl_cert_type: 51
    sectigo_ssl_cert_validity: 365
    sectigo_ssl_cert_format_type: x509
    sectigo_ssl_cert_num_servers: 1
    sectigo_ssl_cert_server_type: -1
    sectigo_ssl_cert_subject_alt_names: []
    sectigo_ssl_cert_comments: "Test certificate for Sectigo"
    sectigo_ssl_cert_expiry_window: 7
    sectigo_auto_renew: true
    sectigo_max_timeout: 600
    sectigo_loop_period: 30
  roles:
    - sectigo_ansible

In this case, the following command will produce the same results, without the need for variable files.

ansible-playbook ./example-playbook-with-vars.yml

SSL and client certificate revocation

SSL certificate revocation can be accomplished by setting the sectigo_state variable to absent and specifying the ID of the SSL certificate to revoke.

- hosts: localhost
  remote_user: root
  vars:
    sectigo_cm_user: "your username"
    sectigo_cm_password: "my password"
    sectigo_cm_uri: "your uri"
    sectigo_cm_org_id: 123
    sectigo_cm_base_url: "https://myorg.cert-manager.com/api/ssl/v1"
    sectigo_state: absent
    sectigo_ssl_cert_ssl_id: 13241 sectigo_reason: "Certificate compromised"
  roles:
    - sectigo_ansible

An alternative approach can be to take advantage of the certificate.ids file to fetch the sslId and use it as a variable in the playbook.

The following example shows you how you can achieve this using the slurp module for a certificate named myserver_certificate.

- name: Revoke myserver_certificate Server SSL certificate
  hosts: all
  pre_tasks:
    - name: Fetch the file containing the sslId of the myserver_certificate certificate
      slurp:
        src: "/certificates/myserver_certificate.ids"
    register: enrollment_ids
  - name: Extract the json file contents
    set_fact:
      certificate_ssl_id: "{{(enrollment_ids.content|b64decode|from_json).sslId}}"
  roles:
    - sectigo_ansible
  vars:
    sectigo_cm_base_url: 'https://myorg.cert-manager.com/api/ssl/v1'
    sectigo_ssl_cert_ssl_id: "{{certificate_ssl_id}}"
    sectigo_reason: Compromised certificate
    sectigo_state: absent

Client certificate revocation is similar—​it requires a different sectigo_cm_base_url and providing sectigo_client_cert_order_number instead of sectigo_ssl_cert_ssl_id.

- hosts: localhost
  remote_user: root
  vars:
    sectigo_cm_user: "myuser"
    sectigo_cm_password: "mypass"
    sectigo_cm_uri: "myuri"
    sectigo_cm_org_id: 123
    sectigo_cm_base_url: "https://myorg.cert-manager.com/api/smime/v1"
    sectigo_state: absent
    sectigo_client_cert_order_number: 13241
    sectigo_reason: "Certificate compromised"
  roles:
    - sectigo_ansible

You can also use an alternate approach like the one used for server certificates, paying attention to the fact that this time you want to fetch the orderNumber field instead.

The following example shows how you can achieve this using the slurp module for a certificate named myclient_certificate.

- name: Revoke test_default Client (SMIME) Certificate
  hosts: all
  pre_tasks:
    - name: Fetch the file containing the orderNumber of the myclient_certificate certificate
      slurp:
        src: "/smime-certificates/myclient_certificate.ids"
      register: enrollment_ids
    - name: Extract the json file contents
      set_fact:
        certificate_order_number: "{{(enrollment_ids.content|b64decode|from_json).orderNumber}}"
  roles:
    - sectigo_ansible
  vars:
    sectigo_cm_base_url: 'https://myorg.cert- manager.com/api/smime/v1'
    sectigo_client_cert_order_number: "{{certificate_order_number}}"
    sectigo_reason: Compromised certificate
    sectigo_state: absent