{"id":21745160,"url":"https://github.com/zuazo/ssl_certificate-cookbook","last_synced_at":"2025-04-13T05:12:30.292Z","repository":{"id":16051946,"uuid":"18796004","full_name":"zuazo/ssl_certificate-cookbook","owner":"zuazo","description":"Chef cookbook to make it easy for other cookbooks to support SSL.","archived":false,"fork":false,"pushed_at":"2020-06-27T17:39:24.000Z","size":487,"stargazers_count":32,"open_issues_count":9,"forks_count":36,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-26T22:05:23.803Z","etag":null,"topics":["certificate","chef","cookbook","devops","security","ssl","tls"],"latest_commit_sha":null,"homepage":"https://supermarket.chef.io/cookbooks/ssl_certificate","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zuazo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-04-15T10:23:21.000Z","updated_at":"2020-07-27T16:34:01.000Z","dependencies_parsed_at":"2022-08-28T17:20:17.328Z","dependency_job_id":null,"html_url":"https://github.com/zuazo/ssl_certificate-cookbook","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fssl_certificate-cookbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fssl_certificate-cookbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fssl_certificate-cookbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fssl_certificate-cookbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zuazo","download_url":"https://codeload.github.com/zuazo/ssl_certificate-cookbook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665742,"owners_count":21142123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certificate","chef","cookbook","devops","security","ssl","tls"],"created_at":"2024-11-26T07:13:47.587Z","updated_at":"2025-04-13T05:12:30.269Z","avatar_url":"https://github.com/zuazo.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"SSL Certificate Cookbook\n==========================\n[![GitHub](http://img.shields.io/badge/github-zuazo/ssl__certificate--cookbook-blue.svg?style=flat)](https://github.com/zuazo/ssl_certificate-cookbook)\n[![License](https://img.shields.io/github/license/zuazo/ssl_certificate-cookbook.svg?style=flat)](#license-and-author)\n\n[![Cookbook Version](https://img.shields.io/cookbook/v/ssl_certificate.svg?style=flat)](https://supermarket.chef.io/cookbooks/ssl_certificate)\n[![Dependency Status](http://img.shields.io/gemnasium/zuazo/ssl_certificate-cookbook.svg?style=flat)](https://gemnasium.com/zuazo/ssl_certificate-cookbook)\n[![Code Climate](http://img.shields.io/codeclimate/github/zuazo/ssl_certificate-cookbook.svg?style=flat)](https://codeclimate.com/github/zuazo/ssl_certificate-cookbook)\n[![Build Status](http://img.shields.io/travis/zuazo/ssl_certificate-cookbook.svg?style=flat)](https://travis-ci.org/zuazo/ssl_certificate-cookbook)\n[![Circle CI](https://circleci.com/gh/zuazo/ssl_certificate-cookbook/tree/master.svg?style=shield)](https://circleci.com/gh/zuazo/ssl_certificate-cookbook/tree/master)\n\nThe main purpose of this [Chef](https://www.chef.io/) cookbook is to make it easy for other cookbooks to support SSL. With the resource included, you will be able to manage certificates reading them from attributes, data bags or chef-vaults. Exposing its configuration through node attributes.\n\nMuch of the code in this cookbook is heavily based on the SSL implementation from the [owncloud](https://supermarket.chef.io/cookbooks/owncloud) cookbook.\n\nTable of Contents\n=================\n\n* [Requirements](#requirements)\n  * [Supported Platforms](#supported-platforms)\n  * [Required Applications](#required-applications)\n* [Usage](#usage)\n  * [Including the Cookbook](#including-the-cookbook)\n  * [A Short Example](#a-short-example)\n  * [Namespaces](#namespaces)\n  * [Examples](#examples)\n    * [Apache Examples](#apache-examples)\n    * [Nginx Example](#nginx-example)\n    * [Reading the Certificate from Attributes](#reading-the-certificate-from-attributes)\n    * [Reading the Certificate from a Data Bag](#reading-the-certificate-from-a-data-bag)\n    * [Reading the Certificate from Chef Vault](#reading-the-certificate-from-chef-vault)\n    * [Reading the Certificate from Files](#reading-the-certificate-from-files)\n    * [Reading the Certificate from Different Places](#reading-the-certificate-from-different-places)\n    * [Creating a Certificate with Subject Alternate Names](#creating-a-certificate-with-subject-alternate-names)\n    * [Reading Key, Certificate and Intermediary from a Data Bag](#reading-key-certificate-and-intermediary-from-a-data-bag)\n    * [Creating a PKCS12 Containing Both the Certificate and the Private Key](#creating-a-pkcs12-containing-both-the-certificate-and-the-private-key)\n    * [Creating a Certificate from a Certificate Authority](#creating-a-certificate-from-a-certificate-authority)\n    * [Reading the CA Certificate from a Chef Vault Bag](#reading-the-ca-certificate-from-a-chef-vault-bag)\n    * [Managing Certificates Via Attributes](#managing-certificates-via-attributes)\n    * [Real-world Examples](#real-world-examples)\n* [Attributes](#attributes)\n  * [Service Attributes](#service-attributes)\n* [Resources](#resources)\n  * [ssl_certificate](#ssl_certificate)\n    * [ssl_certificate Actions](#ssl_certificate-actions)\n    * [ssl_certificate Parameters](#ssl_certificate-parameters)\n* [Templates](#templates)\n  * [Partial Templates](#partial-templates)\n  * [Securing Server Side TLS](#securing-server-side-tls)\n* [Testing](#testing)\n  * [ChefSpec Matchers](#chefspec-matchers)\n    * [ssl_certificate(name)](#ssl_certificatename)\n    * [create_ssl_certificate(name)](#create_ssl_certificatename)\n* [Contributing](#contributing)\n* [TODO](#todo)\n* [License and Author](#license-and-author)\n\nRequirements\n============\n\n## Supported Platforms\n\nThis cookbook has been tested on the following platforms:\n\n* Amazon Linux\n* CentOS\n* Debian\n* Fedora\n* FreeBSD\n* Oracle Linux\n* RedHat\n* Scientific Linux\n* Ubuntu\n* Windows\n\nPlease, [let us know](https://github.com/zuazo/ssl_certificate-cookbook/issues/new?title=I%20have%20used%20it%20successfully%20on%20...) if you use it successfully on any other platform.\n\n## Required Applications\n\n* Chef `12` or higher.\n* Ruby `2.3` or higher.\n\nUsage\n=====\n\n## Including the Cookbook\n\nYou need to include this recipe in your `run_list` before using the  `ssl_certificate` resource:\n\n```json\n{\n  \"name\": \"example.com\",\n  \"[...]\": \"[...]\",\n  \"run_list\": [\n    \"recipe[ssl_certificate]\"\n  ]\n}\n```\n\nYou can also include the cookbook as a dependency in the metadata of your cookbook:\n\n```ruby\n# metadata.rb\ndepends 'ssl_certificate'\n```\n\nOne of the two is enough. No need to do anything else. Only use the `ssl_certificate` resource to create the certificates you need.\n\n## A Short Example\n\n```ruby\ncert = ssl_certificate 'webapp1' do\n  namespace node['webapp1'] # optional but recommended\nend\n# you can now use the #cert_path and #key_path methods to use in your\n# web/mail/ftp service configurations\nlog \"WebApp1 certificate is here: #{cert.cert_path}\"\nlog \"WebApp1 private key is here: #{cert.key_path}\"\n```\n\n## Namespaces\n\nThe `ssl_certificate` resource **namespace** parameter is a node attribute path, like for example `node['example.com']`, used to configure SSL certificate defaults. This will make easier to *integrate the node attributes* with the certificate creation matters. This means you can configure the certificate creation through node attributes.\n\nWhen a namespace is set in the resource, it will try to read the following attributes below the namespace (all attributes are **optional**):\n\n| Attribute                                          | Description                    |\n|:---------------------------------------------------|:-------------------------------|\n| `namespace['common_name']`                         | Server name or *Common Name*, used for self-signed certificates (uses `node['fqdn']` by default).\n| `namespace['country']`                             | *Country*, used for self-signed certificates.\n| `namespace['city']`                                | *City*, used for self-signed certificates.\n| `namespace['state']`                               | *State* or *Province* name, used for self-signed certificates.\n| `namespace['organization']`                        | *Organization* or *Company* name, used for self-signed certificates.\n| `namespace['department']`                          | Department or *Organizational Unit*, used for self-signed certificates.\n| `namespace['email']`                               | *Email* address, used for self-signed certificates.\n| `namespace['source']`                              | Attribute for setting certificate source and key source (both) to a value (`key_source` and `cert_source`).\n| `namespace['bag']`                                 | Attribute for setting certificate bag and key bag (both) to a value (`key_bag` and `cert_bag`).\n| `namespace['item']`                                | Attribute for setting certificate item name and key bag item name (both) to a value (`key_item` and `cert_item`).\n| `namespace['encrypted']`                           | Attribute for setting certificate encryption and key encryption (both) to a value (`key_encryption` and `cert_encryption`).\n| `namespace['secret_file']`                         | Attribute for setting certificate chef secret file and key chef secret file (both) to a value (`key_secret_file` and `cert_secret_file`).\n| `namespace['ssl_key']['source']`                   | Source type to get the SSL key from. Can be `'self-signed'`, `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| `namespace['ssl_key']['path']`                     | File path of the SSL key.\n| `namespace['ssl_key']['mode']`                     | File mode of the SSL key.\n| `namespace['ssl_key']['bag']`                      | Name of the Data Bag where the SSL key is stored.\n| `namespace['ssl_key']['item']`                     | Name of the Data Bag Item where the SSL key is stored.\n| `namespace['ssl_key']['item_key']`                 | Key of the Data Bag Item where the SSL key is stored.\n| `namespace['ssl_key']['encrypted']`                | Whether the Data Bag where the SSL key is stored is encrypted.\n| `namespace['ssl_key']['secret_file']`              | Secret file used to decrypt the Data Bag where the SSL key is stored.\n| `namespace['ssl_key']['content']`                  | SSL key content used when reading from attributes.\n| `namespace['ssl_key']['length']`                   | RSA key length used when generating a new key.\n| `namespace['ssl_cert']['source']`                  | Source type to get the SSL cert from. Can be `'self-signed'`, `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| `namespace['ssl_cert']['path']`                    | File path of the SSL certificate.\n| `namespace['ssl_cert']['bag']`                     | Name of the Data Bag where the SSL cert is stored.\n| `namespace['ssl_cert']['item']`                    | Name of the Data Bag Item where the SSL cert is stored.\n| `namespace['ssl_cert']['item_key']`                | Key of the Data Bag Item where the SSL cert is stored.\n| `namespace['ssl_cert']['encrypted']`               | Whether the Data Bag where the SSL cert is stored is encrypted.\n| `namespace['ssl_cert']['secret_file']`             | Secret file used to decrypt the Data Bag where the SSL cert is stored.\n| `namespace['ssl_cert']['content']`                 | SSL cert content used when reading from attributes.\n| `namespace['ssl_cert']['subject_alternate_names']` | An array of Subject Alternate Names for the SSL cert. Needed if your site has multiple domain names on the same cert.\n| `namespace['ssl_cert']['extended_key_usage']`      | An array of extended key usage attributes.\n| `namespace['ssl_chain']['name']`                   | File name to be used for the intermediate certificate chain file. **If this is not present, no chain file will be written.**\n| `namespace['ssl_chain']['source']`                 | Source type to get the intermediate certificate chain from. Can be `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| `namespace['ssl_chain']['path']`                   | File path of the intermediate SSL certificate chain.\n| `namespace['ssl_chain']['combined_path']`          | File path of the combined certificates (intermediate chain + domain certificate).\n| `namespace['ssl_chain']['bag']`                    | Name of the Data Bag where the intermediate certificate chain is stored.\n| `namespace['ssl_chain']['item']`                   | Name of the Data Bag Item where the intermediate certificate chain is stored.\n| `namespace['ssl_chain']['item_key']`               | Key of the Data Bag Item where the intermediate certificate chain is stored.\n| `namespace['ssl_chain']['encrypted']`              | Whether the Data Bag where the intermediate certificate chain is stored is encrypted.\n| `namespace['ssl_chain']['secret_file']`            | Secret file used to decrypt the Data Bag where the intermediate certificate chain is stored.\n| `namespace['ssl_chain']['content']`                | Intermediate certificate chain content used when reading from attributes.\n| `namespace['ca_cert_path']`                        | Certificate Authority full path.\n| `namespace['ca_key_path']`                         | Key Authority full path.\n| `namespace['ca_key_passphrase']`                   | Key Authority passphrase.\n| `namespace['pkcs12_path']`                         | Optional PKCS12 full path.\n| `namespace['pkcs12_passphrase']`                   | Optional PKCS12 passphrase.\n\n## Examples\n\n### Apache Examples\n\nApache `web_app` example using community [apache2](https://supermarket.chef.io/cookbooks/apache2) cookbook and node attributes:\n\n```ruby\nnode.default['my-webapp']['common_name'] = 'example.com'\nnode.default['my-webapp']['ssl_cert']['source'] = 'self-signed'\nnode.default['my-webapp']['ssl_key']['source'] = 'self-signed'\n\n# we need to save the resource variable to get the key and certificate file\n# paths\ncert = ssl_certificate 'my-webapp' do\n  # we want to be able to use node['my-webapp'] to configure the certificate\n  namespace node['my-webapp']\n  notifies :restart, 'service[apache2]'\nend\n\ninclude_recipe 'apache2'\ninclude_recipe 'apache2::mod_ssl'\nweb_app 'my-webapp' do\n  # this cookbook includes a virtualhost template for apache2\n  cookbook 'ssl_certificate'\n  server_name cert.common_name\n  docroot # [...]\n  # [...]\n  ssl_key cert.key_path\n  ssl_cert cert.cert_path\n  ssl_chain cert.chain_path\nend\n```\n\nUsing custom paths:\n\n```ruby\nmy_key_path = '/etc/keys/my-webapp.key'\nmy_cert_path = '/etc/certs/my-webapp.pem'\n\n# there is no need to save the resource in a variable in this case because we\n# know the paths\nssl_certificate 'my-webapp' do\n  key_path my_key_path\n  key_mode 00640\n  cert_path my_cert_path\nend\n\n# Configure Apache SSL\ninclude_recipe 'apache2::mod_ssl'\nweb_app 'my-webapp' do\n  cookbook 'ssl_certificate'\n  # [...]\n  ssl_key my_key_path\n  ssl_cert my_cert_path\nend\n```\n\nSee [templates documentation](#templates).\n\n### Nginx Example\n\nMinimal `nginx` example using community [nginx](https://supermarket.chef.io/cookbooks/nginx) cookbook:\n\n```ruby\ncert = ssl_certificate 'my-webapp' do\n  notifies :restart, 'service[nginx]'\nend\n\n# Create a virtualhost for nginx\ntemplate ::File.join(node['nginx']['dir'], 'sites-available', 'my-webapp-ssl') do\n  # You need to create a template for nginx to enable SSL support and read the\n  # keys from ssl_key and ssl_chain_combined attributes.\n  # You can use the *nginx.erb* partial template as shown below.\n  source 'nginx_vhost.erb'\n  mode 00644\n  owner 'root'\n  group 'root'\n  variables(\n    name: 'my-webapp-ssl',\n    server_name: 'ssl.example.com',\n    docroot: '/var/www',\n    # [...]\n    ssl_key: cert.key_path,\n    ssl_cert: cert.chain_combined_path\n  )\n  notifies :reload, 'service[nginx]'\nend\n\n# Enable the virtualhost\nnginx_site 'my-webapp-ssl' do\n  enable true\nend\n\n# publish the certificate to an attribute, it may be useful\nnode.set['web-app']['ssl_cert']['content'] = cert.cert_content\n```\n\nHere's a nginx template example using the [*nginx.erb* partial template](#partial-templates):\n\n```erb\n\u003c%# nginx_vhost.erb %\u003e\nserver {\n  server_name \u003c%= @server_name %\u003e;\n  listen 443;\n  # Path to the root of your installation\n  root \u003c%= @docroot %\u003e;\n\n  access_log \u003c%= node['nginx']['log_dir'] %\u003e/\u003c%= @name %\u003e-access.log combined;\n  error_log  \u003c%= node['nginx']['log_dir'] %\u003e/\u003c%= @name %\u003e-error.log;\n\n  index index.html;\n  \u003c%# [...] %\u003e\n\n  \u003c%= render 'nginx.erb', cookbook: 'ssl_certificate' %\u003e\n}\n```\n\nSee [templates documentation](#templates).\n\n### Reading the Certificate from Attributes\n\nThe SSL certificate can be read from an attribute directly:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['ssl_key']['content'] =\n  '-----BEGIN PRIVATE KEY-----[...]'\nnode.default['mysite']['ssl_cert']['content'] =\n  '-----BEGIN CERTIFICATE-----[...]'\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n  namespace node['mysite']\n  # this will read the node['mysite']['ssl_key']['content'] and\n  # node['mysite']['ssl_cert']['content'] keys\n  source 'attribute'\nend\n```\n\nAlternative example using a namespace and node attributes:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['common_name'] = 'cloud.mysite.com'\nnode.default['mysite']['ssl_key']['source'] = 'attribute'\nnode.default['mysite']['ssl_key']['content'] =\n  '-----BEGIN PRIVATE KEY-----[...]'\nnode.default['mysite']['ssl_cert']['source'] = 'attribute'\nnode.default['mysite']['ssl_cert']['content'] =\n  '-----BEGIN CERTIFICATE-----[...]'\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  namespace node['mysite']\nend\n```\n\n### Reading the Certificate from a Data Bag\n\n```ruby\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n  source 'data-bag'\n  bag 'ssl_data_bag'\n  key_item 'key' # data bag item\n  key_item_key 'content' # data bag item json key\n  cert_item 'cert'\n  cert_item_key 'content'\n  encrypted true\n  secret_file '/path/to/secret/file' # optional\nend\n```\n\nAlternative example using a namespace and node attributes:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['common_name'] = 'cloud.mysite.com'\n\nnode.default['mysite']['ssl_key']['source'] = 'data-bag'\nnode.default['mysite']['ssl_key']['bag'] = 'ssl_data_bag'\nnode.default['mysite']['ssl_key']['item'] = 'key'\nnode.default['mysite']['ssl_key']['item_key'] = 'content'\nnode.default['mysite']['ssl_key']['encrypted'] = true\nnode.default['mysite']['ssl_key']['secret_file'] = '/path/to/secret/file'\n\nnode.default['mysite']['ssl_cert']['source'] = 'data-bag'\nnode.default['mysite']['ssl_cert']['bag'] = 'ssl_data_bag'\nnode.default['mysite']['ssl_cert']['item'] = 'key'\nnode.default['mysite']['ssl_cert']['item_key'] = 'content'\nnode.default['mysite']['ssl_cert']['encrypted'] = true\nnode.default['mysite']['ssl_cert']['secret_file'] = '/path/to/secret/file'\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  namespace node['mysite']\nend\n```\n\n### Reading the Certificate from Chef Vault\n\n```ruby\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n  source 'chef-vault'\n  bag 'ssl_vault_bag'\n  key_item 'key' # data bag item\n  key_item_key 'content' # data bag item json key\n  cert_item 'cert'\n  cert_item_key 'content'\nend\n```\n\nThe same example, using a namespace and node attributes:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['common_name'] = 'cloud.mysite.com'\n\nnode.default['mysite']['ssl_key']['source'] = 'chef-vault'\nnode.default['mysite']['ssl_key']['bag'] = 'ssl_vault_bag'\nnode.default['mysite']['ssl_key']['item'] = 'key'\nnode.default['mysite']['ssl_key']['item_key'] = 'content'\n\nnode.default['mysite']['ssl_cert']['source'] = 'chef-vault'\nnode.default['mysite']['ssl_cert']['bag'] = 'ssl_vault_bag'\nnode.default['mysite']['ssl_cert']['item'] = 'key'\nnode.default['mysite']['ssl_cert']['item_key'] = 'content'\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  namespace node['mysite']\nend\n```\n\nFor testing you can enabled fall back to use unencrypted data bags if chef\nvault is not found by setting attribute `['chef-vault']['databag_fallback']` to\ntrue value\n\n### Reading the Certificate from Files\n\n```ruby\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n  source 'file'\n  key_path '/path/to/ssl/key'\n  cert_path '/path/to/ssl/cert'\nend\n```\n\nThe same example, using a namespace and node attributes:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['common_name'] = 'cloud.mysite.com'\n\nnode.default['mysite']['ssl_key']['source'] = 'file'\nnode.default['mysite']['ssl_key']['path'] = '/path/to/ssl/key'\n\nnode.default['mysite']['ssl_cert']['source'] = 'file'\nnode.default['mysite']['ssl_cert']['path'] = '/path/to/ssl/cert'\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  namespace node['mysite']\nend\n```\n\n### Reading the Certificate from Different Places\n\nYou can also read the certificate and the private key from different places each:\n\n```ruby\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n\n  # Read the private key from chef-vault\n  key_source 'chef-vault'\n  key_bag 'ssl_vault_bag'\n  key_item 'key' # data bag item\n  key_item_key 'content' # data bag item json key\n\n  # Read the public cert from a non-encrypted data bag\n  cert_source 'data-bag'\n  cert_bag 'ssl_data_bag'\n  cert_item 'cert'\n  cert_item_key 'content'\n  cert_encrypted false\nend\n```\n\nThe same example, using a namespace and node attributes:\n\n```ruby\n# Setting the attributes\nnode.default['mysite']['common_name'] = 'cloud.mysite.com'\n\n# Read the private key from chef-vault\nnode.default['mysite']['ssl_key']['source'] = 'chef-vault'\nnode.default['mysite']['ssl_key']['bag'] = 'ssl_vault_bag'\nnode.default['mysite']['ssl_key']['item'] = 'key'\nnode.default['mysite']['ssl_key']['item_key'] = 'content'\n\n# Read the public cert from a non-encrypted data bag\nnode.default['mysite']['ssl_cert']['source'] = 'data-bag'\nnode.default['mysite']['ssl_cert']['bag'] = 'ssl_data_bag'\nnode.default['mysite']['ssl_cert']['item'] = 'key'\nnode.default['mysite']['ssl_cert']['item_key'] = 'content'\nnode.default['mysite']['ssl_cert']['encrypted'] = false\n\n# Creating the certificate\nssl_certificate 'mysite' do\n  namespace node['mysite']\nend\n```\n\n### Creating a Certificate with Subject Alternate Names\n\n```ruby\ndomain = 'mysite.com'\n# SAN for mysite.com, foo.mysite.com, bar.mysite.com, www.mysite.com\nnode.default[domain]['ssl_cert']['subject_alternate_names'] =\n  [domain, \"foo.#{domain}\", \"bar.#{domain}\", \"www.#{domain}\"]\n\nssl_certificate 'mysite.com' do\n  namespace node[domain]\n  key_source 'self-signed'\n  cert_source 'self-signed'\nend\n```\n\nThe *subject_alternate_names* parameter adds *DNS* values by default. You can also include other kind of values using a colon to separate the type from the value:\n\n```ruby\ndomain = 'mysite.com'\nnode.default[domain]['email'] = 'email@example.com'\nnode.default[domain]['ssl_cert']['subject_alternate_names'] =\n  [\n    'email:copy',\n    \"email:my@#{domain}\",\n    \"URI:http://#{domain}/\",\n    'IP:192.168.7.1',\n    'IP:13::17',\n    'RID:1.2.3.4',\n    'otherName:1.2.3.4;UTF8:some other identifier'\n  ]\n\nssl_certificate 'mysite.com' do\n  namespace node[domain]\n  key_source 'self-signed'\n  cert_source 'self-signed'\nend\n```\n\nSee the [x509v3_config manual page](https://www.openssl.org/docs/apps/x509v3_config.html#Subject-Alternative-Name) for more information.\n\n### Reading Key, Certificate and Intermediary from a Data Bag\n\n```ruby\ncert_name = 'chain-data-bag'\nnode.default[cert_name]['ssl_key']['source'] = 'data-bag'\nnode.default[cert_name]['ssl_key']['bag'] = 'ssl'\nnode.default[cert_name]['ssl_key']['item'] = 'key'\nnode.default[cert_name]['ssl_key']['item_key'] = 'content'\nnode.default[cert_name]['ssl_key']['encrypted'] = true\nnode.default[cert_name]['ssl_cert']['source'] = 'data-bag'\nnode.default[cert_name]['ssl_cert']['bag'] = 'ssl'\nnode.default[cert_name]['ssl_cert']['item'] = 'cert'\nnode.default[cert_name]['ssl_cert']['item_key'] = 'content'\nnode.default[cert_name]['ssl_chain']['name'] = 'chain-ca-bundle.pem'\nnode.default[cert_name]['ssl_chain']['source'] = 'data-bag'\nnode.default[cert_name]['ssl_chain']['bag'] = 'ssl'\nnode.default[cert_name]['ssl_chain']['item'] = 'chain'\nnode.default[cert_name]['ssl_chain']['item_key'] = 'content'\n\nssl_certificate 'chain-data-bag' do\n  namespace cert_name\nend\n```\n### Creating a PKCS12 Containing Both the Certificate and the Private Key\n\n```ruby\nssl_certificate 'mysite' do\n  common_name 'cloud.mysite.com'\n  source 'self-signed'\n  key_path '/etc/key/my.key'\n  cert_path '/etc/cert/my.pem'\n  pkcs12_path '/home/me/my.p12'\n  pkcs12_passphrase 'I_Want_To_Secure_My_P12' # optional\nend\n```\n\n### Creating a Certificate from a Certificate Authority\n\n```ruby\nca_cert = '/usr/share/pki/ca-trust-source/anchors/CA.crt'\nca_key = '/usr/share/pki/ca-trust-source/anchors/CA.key'\n\ncert = ssl_certificate 'test' do\n  namespace node['test.com']\n  key_source 'self-signed'\n  cert_source 'with_ca'\n  ca_cert_path ca_cert\n  ca_key_path ca_key\n  ca_key_passphrase ca_key_passphrase\nend\n```\n\n### Reading the CA Certificate from a Chef Vault Bag\n\nIn this example, we read the CA certificate from a Chef Vault and use it to generate the shelf-signed certificates:\n\n```ruby\n# Create the CA from a Chef Vault bag\n\nca_cert = ssl_certificate 'ca.example.org' do\n  common_name 'ca.example.org'\n  source 'chef-vault'\n  bag 'ssl'\n  item 'ca_cert'\n  key_item_key 'key_content'\n  cert_item_key 'cert_content'\nend\n\nssl_certificate 'example.org' do\n  cert_source 'with_ca'\n  ca_cert_path ca_cert.cert_path\n  ca_key_path ca_cert.key_path\nend\n```\n\nThe vault bag content:\n\n```json\n{\n  \"id\": \"ca_cert\",\n  \"key_content\": \"-----BEGIN RSA PRIVATE KEY-----\\nMIIE [...]\",\n  \"cert_content\": \"-----BEGIN CERTIFICATE-----\\nMIIE [...]\"\n}\n```\n\nThe knife command to create the vault bag item:\n\n    $ knife vault create ssl ca_cert [...]\n\n### Managing Certificates Via Attributes\n\nSometimes you may want to use only node attributes to manage some of your SSL Certificates (instead of [the `ssl_certificate` resource](#ssl_certificate)). You can do it using the `ssl_certificate::attr_apply` recipe and configuring them inside the `node['ssl_certificate']['items']` array:\n\n```ruby\nrun_list(\n  'recipe[ssl_certificate::attr_apply]'\n)\noverride_attributes(\n  'ssl_certificate' =\u003e {\n    'items' =\u003e [\n      {\n        'name' =\u003e 'domain.com',\n        'dir' =\u003e '/etc/nginx/ssl',\n        'item' =\u003e 'domain_com',\n        'source' =\u003e 'chef-vault',\n        'bag' =\u003e 'ssl-vault',\n        'key_item_key' =\u003e 'key',\n        'cert_item_key' =\u003e 'cert',\n        'chain_item_key' =\u003e 'chain',\n        'chain_source' =\u003e 'chef-vault',\n        'chain_bag' =\u003e 'ssl-vault',\n        'chain_item' =\u003e 'domain_com',\n        'chain_name' =\u003e 'domain.com.chain.pem'\n      }\n    ]\n  }\n)\n```\n\n## Real-world Examples\n\nSome cookbooks that use the `ssl_certificate` resource to implement SSL/TLS:\n\n* [`postfixadmin`](https://github.com/zuazo/postfixadmin-cookbook) cookbook: Uses the certificate for Apache httpd and nginx.\n * [`postfixadmin::apache` recipe](https://github.com/zuazo/postfixadmin-cookbook/blob/2.1.0/recipes/apache.rb#L39-L65)\n * [*apache_vhost.erb* template](https://github.com/zuazo/postfixadmin-cookbook/blob/2.1.0/templates/default/apache_vhost.erb#L52-L54)\n * [`postfixadmin::nginx` recipe](https://github.com/zuazo/postfixadmin-cookbook/blob/2.1.0/recipes/nginx.rb#L50-L71)\n * [*nginx_vhost.erb* template](https://github.com/zuazo/postfixadmin-cookbook/blob/2.1.0/templates/default/nginx_vhost.erb#L11-L13)\n * [*README.md* section](https://github.com/zuazo/postfixadmin-cookbook/blob/2.1.0/README.md#the-https-certificate)\n\n* [`boxbilling`](https://github.com/zuazo/boxbilling-cookbook) cookbook: Uses the certificate for Apache httpd and nginx.\n * [`boxbilling::_apache` recipe](https://github.com/zuazo/boxbilling-cookbook/blob/1.0.0/recipes/_apache.rb#L86-L111)\n * [*apache_vhost.erb* template](https://github.com/zuazo/boxbilling-cookbook/blob/1.0.0/templates/default/apache_vhost.erb#L60-L62)\n * [`boxbilling::_nginx` recipe](https://github.com/zuazo/boxbilling-cookbook/blob/1.0.0/recipes/_nginx.rb#L59-L86)\n * [*nginx_vhost.erb* template](https://github.com/zuazo/boxbilling-cookbook/blob/1.0.0/templates/default/nginx_vhost.erb#L9-L11)\n * [*README.md* section](https://github.com/zuazo/boxbilling-cookbook/blob/1.0.0/README.md#the-https-certificate)\n\n* [`kong`](https://github.com/zuazo/kong-cookbook) cookbook: Uses the certificate for the embedded nginx server.\n * [`kong::_configuration` recipe](https://github.com/zuazo/kong-cookbook/blob/0.1.0/recipes/_configuration.rb#L25-L34)\n * [*kong.yml.erb* template](https://github.com/zuazo/kong-cookbook/blob/0.1.0/templates/default/kong.yml.erb#L87-L96), which includes the nginx server configuration.\n * [*README.md* section](https://github.com/zuazo/kong-cookbook/blob/0.1.0/README.md#the-https-certificate)\n\n* [`postfix-dovecot`](https://github.com/zuazo/postfix-dovecot-cookbook) cookbook: Creates one certificate for Postfix and another for Dovecot. Uses the [`SslCertificateCookbook::ServiceHelpers#ssl_config_for_service`](http://www.rubydoc.info/github/zuazo/ssl_certificate-cookbook/master/Chef%2FSslCertificateCookbook%2FServiceHelpers%3Assl_config_for_service) helper to set each service SSL configuration (cipher suites, supported protocols, ...).\n * [`postfix-dovecot::postfix` recipe](https://github.com/zuazo/postfix-dovecot-cookbook/blob/2.0.1/recipes/postfix.rb#L151-L170)\n * [`postfix-dovecot::dovecot` recipe](https://github.com/zuazo/postfix-dovecot-cookbook/blob/2.0.1/recipes/dovecot.rb#L178-L188)\n * [`postfix-dovecot::ssl_certificate` attributes](https://github.com/zuazo/postfix-dovecot-cookbook/blob/2.0.1/attributes/ssl_certificate.rb#L22-L31) to set the *protocols* in the correct format for each service.\n * [*README.md* section](https://github.com/zuazo/postfix-dovecot-cookbook/blob/2.0.1/README.md#the-ssl-certificate)\n\n* [`onddo_proftpd`](https://github.com/zuazo/proftpd-cookbook) cookbook contains examples to enable TLS:\n * [*README.md* documentation with a TLS example](https://github.com/zuazo/proftpd-cookbook/tree/2.0.0#enabling-ssltls)\n * [`onddo_proftpd_test::attrs` recipe](https://github.com/zuazo/proftpd-cookbook/blob/2.0.0/test/cookbooks/onddo_proftpd_test/recipes/attrs.rb#L158-L187) used for `test-kitchen` integration tests.\n\nAttributes\n==========\n\n| Attribute                                             | Default      | Description                        |\n|:------------------------------------------------------|:-------------|:-----------------------------------|\n| `node['ssl_certificate']['user']`                     | *calculated* | Default SSL files owner user.\n| `node['ssl_certificate']['group']`                    | *calculated* | Default SSL files owner group.\n| `node['ssl_certificate']['key_dir']`                  | *calculated* | Default SSL key directory.\n| `node['ssl_certificate']['cert_dir']`                 | *calculated* | Default SSL certificate directory.\n\n## Service Attributes\n\nThe following attributes are used to integrate SSL specific configurations with different services (Apache, nginx, ...). They are used internally by [the apache and nginx templates](#templates).\n\n| Attribute                                                  | Default      | Description                        |\n|:-----------------------------------------------------------|:-------------|:-----------------------------------|\n| `node['ssl_certificate']['service']['cipher_suite']`       | `nil`        | Service default SSL cipher suite.\n| `node['ssl_certificate']['service']['protocols']`          | `nil`        | Service default SSL protocols.\n| `node['ssl_certificate']['service']['apache']`             | *calculated* | Apache web service httpd specific SSL attributes.\n| `node['ssl_certificate']['service']['nginx']`              | *calculated* | nginx web service specific SSL attributes.\n| `node['ssl_certificate']['service']['compatibility']`      | `nil`        | Service SSL compatibility level (See [below](#securing-server-side-tls)).\n| `node['ssl_certificate']['service']['use_hsts']`           | `true`       | Whether to enable [HSTS](http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security) in the service.\n| `node['ssl_certificate']['service']['use_stapling']`       | *calculated* | Whether to enable [OCSP stapling](http://en.wikipedia.org/wiki/OCSP_stapling) in the service (nginx only, use `node['apache']['mod_ssl']['use_stapling']` for apache).\n| `node['ssl_certificate']['service']['stapling_resolver']`  | *calculated* | DNS resolver to use for OCSP. Only with Nginx.\n\nSee the [`ServiceHelpers` class documentation](http://www.rubydoc.info/github/zuazo/ssl_certificate-cookbook/master/Chef/SslCertificateCookbook/ServiceHelpers) to learn how to integrate them with new services.\n\nResources\n=========\n\n## ssl_certificate\n\nCreates a SSL certificate.\n\nBy default the resource will create a self-signed certificate, but a custom one can also be used. The custom certificate can be read from several sources:\n\n* Attribute\n* Data Bag\n* Encrypted Data Bag\n* Chef Vault\n* File\n\n### ssl_certificate Actions\n\n* `create`: Creates the SSL certificate.\n\n### ssl_certificate Parameters\n\n| Parameter               | Default                        | Description                    |\n|:------------------------|:-------------------------------|:-------------------------------|\n| namespace               | `{}`                           | Node namespace to read the default values from, something like `node['myapp']`. See the documentation above for more information on how to use the namespace.\n| common_name             | `namespace['common_name']`     | Server name or *Common Name*, used for self-signed certificates.\n| domain                  | `namespace['common_name']`     | `common_name` method alias.\n| country                 | `namespace['country']`         | *Country*, used for self-signed certificates.\n| city                    | `namespace['city']`            | *City*, used for self-signed certificates.\n| state                   | `namespace['state']`           | *State* or *Province* name, used for self-signed certificates.\n| organization            | `namespace['city']`            | *Organization* or *Company* name, used for self-signed certificates.\n| department              | `namespace['city']`            | Department or *Organizational Unit*, used for self-signed certificates.\n| email                   | `namespace['email']`           | *Email* address, used for self-signed certificates.\n| time                    | `10 * 365 * 24 * 60 * 60`      | Attribute for setting self-signed certificate validity time in seconds or `Time` object instance.\n| years                   | `10`                           | Write only attribute for setting self-signed certificate validity period in years.\n| owner                   | *calculated*                   | Certificate files owner user.\n| group                   | *calculated*                   | Certificate files owner group.\n| dir                     | `nil`                          | Write only attribute for setting certificate path and key path (both) to a directory (`key_dir` and `cert_dir`).\n| source                  | `nil`                          | Write only attribute for setting certificate source and key source (both) to a value (`key_source` and `cert_source`). Can be `'self-signed'`, `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| bag                     | `nil`                          | Write only attribute for setting certificate bag and key bag (both) to a value (`key_bag` and `cert_bag`).\n| item                    | `nil`                          | Write only attribute for setting certificate item name and key bag item name (both) to a value (`key_item` and `cert_item`).\n| encrypted               | `nil`                          | Write only attribute for setting certificate encryption and key encryption (both) to a value (`key_encrypted` and `cert_encrypted`).\n| secret_file             | `nil`                          | Write only attribute for setting certificate chef secret file and key chef secret file (both) to a value (`key_secret_file` and `cert_secret_file`).\n| key_path                | *calculated*                   | Private key full path.\n| key_mode                | `0600`                         | Private key file mode.\n| key_name                | `\"#{name}.key\"`                | Private key file name.\n| key_dir                 | *calculated*                   | Private key directory path.\n| key_source              | `'self-signed'`                | Source type to get the SSL key from. Can be `'self-signed'`, `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| key_bag                 | `namespace['ssl_key']['bag']`  | Name of the Data Bag where the SSL key is stored.\n| key_item                | `namespace['ssl_key']['item']` | Name of the Data Bag Item where the SSL key is stored.\n| key_item_key            | *calculated*                   | Key of the Data Bag Item where the SSL key is stored.\n| key_encrypted           | `false`                        | Whether the Data Bag where the SSL key is stored is encrypted.\n| key_length              | `2048`                         | Integer that must be a power of 2, with a reasonable maximum of 4096. This defines the length of a generated RSA key. \n| key_secret_file         | `nil`                          | Secret file used to decrypt the Data Bag where the SSL key is stored.\n| key_content             | *calculated*                   | SSL key file content in clear. **Be careful when using it.**\n| cert_path               | *calculated*                   | Public certificate full path.\n| cert_name               | `\"#{name}.pem\"`                | Public certiticate file name.\n| cert_dir                | *calculated*                   | Public certificate directory path.\n| cert_source             | `'self-signed'`                | Source type to get the SSL cert from. Can be `'self-signed'`, `'with_ca'`, `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| cert_bag                | `namespace['ssl_cert']['bag']` | Name of the Data Bag where the SSL cert is stored.\n| cert_item               | *calculated*                   | Name of the Data Bag Item where the SSL cert is stored.\n| cert_item_key           | *calculated*                   | Key of the Data Bag Item where the SSL cert is stored.\n| cert_encrypted          | `false`                        | Whether the Data Bag where the SSL cert is stored is encrypted.\n| cert_secret_file        | `nil`                          | Secret file used to decrypt the Data Bag where the SSL cert is stored.\n| cert_content            | *calculated*                   | SSL cert file content in clear.\n| subject_alternate_names | `nil`                          | Subject Alternate Names for the cert.\n| extended_key_usage      | `nil`                          | Extended keyUsage flags array\n| chain_path              | *calculated*                   | Intermediate certificate chain full path.\n| chain_name              | `nil`                          | File name of intermediate certificate chain file. **If this is not present, no chain file will be written.**\n| chain_dir               | *calculated*                   | Intermediate certificate chain directory path.\n| chain_source            | `nil`                          | Source type to get the intermediate certificate chain from. Can be `'attribute'`, `'data-bag'`, `'chef-vault'` or `'file'`.\n| chain_bag               | *calculated*                   | Name of the Data Bag where the intermediate certificate chain is stored.\n| chain_item              | *calculated*                   | Name of the Data Bag Item where the intermediate certificate chain is stored.\n| chain_item_key          | *calculated*                   | Key of the Data Bag Item where the intermediate certificate chain is stored.\n| chain_encrypted         | `false`                        | Whether the Data Bag where the intermediate certificate chain is stored is encrypted.\n| chain_secret_file       | `nil`                          | Secret file used to decrypt the Data Bag where the intermediate certificate chain is stored.\n| chain_content           | *calculated*                   | Intermediate certificate chain file content in clear.\n| chain_combined_name     | *calculated*                   | File name of intermediate certificate chain combined file (for **nginx**).\n| chain_combined_path     | *calculated*                   | Intermediate certificate chain combined file full path (for **nginx**).\n| ca_cert_path            | *nil*                          | Certificate Authority full path.\n| ca_key_path             | *nil*                          | Key Authority full path.\n| ca_key_passphrase       | *nil*                          | Key Authority passphrase.\n| pkcs12_path             | *nil*                          | Optional PKCS12 full path.\n| pkcs12_passphrase       | *nil*                          | Optional PKCS12 passphrase.\n\nTemplates\n=========\n\nThis cookbook includes a simple VirtualHost template which can be used by the `web_app` definition from the [apache2](https://supermarket.chef.io/cookbooks/apache2) cookbook:\n\n```ruby\ncert = ssl_certificate 'my-webapp' do\n  namespace node['my-webapp']\n  notifies :restart, 'service[apache2]'\nend\n\ninclude_recipe 'apache2'\ninclude_recipe 'apache2::mod_ssl'\nweb_app 'my-webapp' do\n  cookbook 'ssl_certificate'\n  server_name cert.common_name\n  docroot # [...]\n  # [...]\n  ssl_key cert.key_path\n  ssl_cert cert.cert_path\n  ssl_chain cert.chain_path\nend\n```\n\n## Partial Templates\n\nThis cookbook contains [partial templates](http://docs.chef.io/templates.html#partial-templates) that you can include in your virtualhost templates to enable and configure the SSL protocol. These partial templates are available:\n\n* *apache.erb*: For Apache httpd web server.\n* *nginx.erb*: For nginx web server.\n\n### Partial Templates Parameters\n\n| Parameter          | Default          | Description                        |\n|:-------------------|:-----------------|:-----------------------------------|\n| ssl_cert           | `nil`            | Public SSL certificate full path.\n| ssl_key            | `nil`            | Private SSL key full path.\n| ssl_chain          | `nil`            | Intermediate SSL certificate chain full path (**apache** only) *(optional)*.\n| ssl_compatibility  | *node attribute* | SSL compatibility level (See [below](#securing-server-side-tls)).\n\n### Apache Partial Template\n\n#### Using `web_app` Definition\n\nIf you are using the `web_app` definition, you should pass the `@params` variables to the partial template:\n\n```ruby\nweb_app 'my-webapp-ssl' do\n  docroot node['apache']['docroot_dir']\n  server_name cert.common_name\n  # [...]\n  ssl_key cert.key_path\n  ssl_cert cert.cert_path\n  ssl_chain cert.chain_path\nend\n```\n\n```erb\n\u003c%# included by web_app definition %\u003e\n\u003cVirtualHost *:443\u003e\n  ServerName \u003c%= @params[:server_name] %\u003e\n  DocumentRoot \u003c%= @params[:docroot] %\u003e\n  \u003c%# [...] %\u003e\n\n  \u003c%= render 'apache.erb', cookbook: 'ssl_certificate', variables: @params.merge(node: node) %\u003e\n\u003c/VirtualHost\u003e\n```\n\n#### Using `template` Resource\n\n```ruby\ncert = ssl_certificate 'my-webapp-ssl'\ntemplate ::File.join(node['apache']['dir'], 'sites-available', 'my-webapp-ssl') do\n  source 'apache_vhost.erb'\n  # [...]\n  variables(\n    # [...]\n    ssl_key: cert.key_path,\n    ssl_cert: cert.chain_combined_path,\n    ssl_chain: cert.chain_path\n  )\nend\n```\n\nYou can include the partial template as follows:\n\n```erb\n\u003c%# included by template resource %\u003e\n\u003cVirtualHost *:443\u003e\n  ServerName \u003c%= @server_name %\u003e\n  DocumentRoot \u003c%= @docroot %\u003e\n  \u003c%# [...] %\u003e\n\n  \u003c%= render 'apache.erb', cookbook: 'ssl_certificate' %\u003e\n\u003c/VirtualHost\u003e\n```\n\n### Nginx Partial Template\n\nIf you are using nginx template, we recommended to use the `SslCertificate#chain_combined_path` path value to set the `ssl_cert` variable instead of `SslCertificate#cert_path`. That's to ensure we [always include the chained certificate](http://nginx.org/en/docs/http/configuring_https_servers.html#chains) if there is one. This will also work when there is no chained certificate.\n\n```ruby\ncert = ssl_certificate 'my-webapp-ssl'\ntemplate ::File.join(node['nginx']['dir'], 'sites-available', 'my-webapp-ssl') do\n  source 'nginx_vhost.erb'\n  # [...]\n  variables(\n    # [...]\n    ssl_key: cert.key_path,\n    ssl_cert: cert.chain_combined_path\n  )\nend\n```\n\nSee [the examples above](#examples).\n\n## Securing Server Side TLS\n\nYou can change the SSL compatibility level based on [the TLS recommendations in the Mozilla wiki](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) using the `ssl_compatibility` template parameter:\n\n```ruby\ncert = ssl_certificate 'my-webapp' do\n  namespace node['my-webapp']\n  notifies :restart, 'service[apache2]'\nend\n\ninclude_recipe 'apache2'\ninclude_recipe 'apache2::mod_ssl'\nweb_app 'my-webapp' do\n  cookbook 'ssl_certificate'\n  server_name cert.common_name\n  docroot # [...]\n  # [...]\n  ssl_key cert.key_path\n  ssl_cert cert.cert_path\n  ssl_chain cert.chain_path\n  ssl_compatibility :modern # :modern | :intermediate | :old\nend\n```\n\nYou can also use the `node['ssl_certificate']['service']['compatibility']` node attribute to change the compatibility level used by default.\n\nTesting\n=======\n\nSee [TESTING.md](https://github.com/zuazo/ssl_certificate-cookbook/blob/master/TESTING.md).\n\n## ChefSpec Matchers\n\n### ssl_certificate(name)\n\nHelper method for locating a `ssl_certificate` resource in the collection.\n\n```ruby\nresource = chef_run.ssl_certificate('postfixadmin')\nexpect(resource).to notify('service[apache2]').to(:restart)\n```\n\n### create_ssl_certificate(name)\n\nAssert that the Chef run creates ssl_certificate.\n\n```ruby\nexpect(chef_run).to create_ssl_certificate('cloud.mysite.com')\n```\n\nContributing\n============\n\nPlease do not hesitate to [open an issue](https://github.com/zuazo/ssl_certificate-cookbook/issues/new) with any questions or problems.\n\nSee [CONTRIBUTING.md](https://github.com/zuazo/ssl_certificate-cookbook/blob/master/CONTRIBUTING.md).\n\nTODO\n====\n\nSee [TODO.md](https://github.com/zuazo/ssl_certificate-cookbook/blob/master/TODO.md).\n\n\nLicense and Author\n==================\n\n|                      |                                          |\n|:---------------------|:-----------------------------------------|\n| **Author:**          | [Raul Rodriguez](https://github.com/raulr) (\u003craul@raulr.com\u003e)\n| **Author:**          | [Xabier de Zuazo](https://github.com/zuazo) (\u003cxabier@zuazo.org\u003e)\n| **Contributor:**     | [Steve Meinel](https://github.com/smeinel)\n| **Contributor:**     | [Djuri Baars](https://github.com/dsbaars)\n| **Contributor:**     | [Elliott Davis](https://github.com/elliott-davis)\n| **Contributor:**     | [Jeremy MAURO](https://github.com/jmauro)\n| **Contributor:**     | [Benjamin Nørgaard](https://github.com/blacksails)\n| **Contributor:**     | [Stanislav Bogatyrev](https://github.com/realloc)\n| **Contributor:**     | [Karl Svec](https://github.com/karlsvec)\n| **Contributor:**     | [Nikita Borzykh](https://github.com/sample)\n| **Contributor:**     | [Baptiste Courtois](https://github.com/Annih)\n| **Contributor:**     | [Taliesin Sisson](https://github.com/taliesins)\n| **Contributor:**     | [Alexey Demidov](https://github.com/AlexeyDemidov)\n| **Contributor:**     | [Ali Ardestani](https://github.com/alisade)\n| **Contributor:**     | [HawkAndBaby](https://github.com/hawkandbaby)\n| **Contributor:**     | [Andrew J. Brown](https://github.com/andrewjamesbrown)\n| **Copyright:**       | Copyright (c) 2015-2017, Xabier de Zuazo\n| **Copyright:**       | Copyright (c) 2014-2015, Onddo Labs, SL.\n| **License:**         | Apache License, Version 2.0\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n        http://www.apache.org/licenses/LICENSE-2.0\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuazo%2Fssl_certificate-cookbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzuazo%2Fssl_certificate-cookbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuazo%2Fssl_certificate-cookbook/lists"}