Skip to content

Commit 19fb13c

Browse files
jaymzhfacebook-github-bot
authored andcommitted
New cookbook: fb_letsencrypt (facebook#248)
Summary: This is a simple cookbook to manage letsencrypt/certbot on systems. Signed-off-by: Phil Dibowitz <phil@ipom.com> Pull Request resolved: facebook#248 Differential Revision: D69054634 fbshipit-source-id: 56dba1139faec86840ca14becdec9a5d4051ce79
1 parent 03e935b commit 19fb13c

File tree

8 files changed

+250
-1
lines changed

8 files changed

+250
-1
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Delivery for Local Phases Execution
2+
#
3+
# This file allows you to execute test phases locally on a workstation or
4+
# in a CI pipeline. The delivery-cli will read this file and execute the
5+
# command(s) that are configured for each phase. You can customize them
6+
# by just modifying the phase key on this file.
7+
#
8+
# By default these phases are configured for Cookbook Workflow only
9+
#
10+
11+
[local_phases]
12+
unit = "echo skipping unit phase."
13+
lint = "chef exec cookstyle"
14+
# foodcritic has been deprecated in favor of cookstyle so we skip the syntax
15+
# phase now.
16+
syntax = "echo skipping syntax phase. Use lint phase instead."
17+
provision = "chef exec kitchen create"
18+
deploy = "chef exec kitchen converge"
19+
smoke = "chef exec kitchen verify"
20+
# The functional phase is optional, you can define it by uncommenting
21+
# the line below and running the command: `delivery local functional`
22+
# functional = ""
23+
cleanup = "chef exec kitchen destroy"
24+
25+
# Remote project.toml file
26+
#
27+
# Instead of the local phases above, you may specify a remote URI location for
28+
# the `project.toml` file. This is useful for teams that wish to centrally
29+
# manage the behavior of the `delivery local` command across many different
30+
# projects.
31+
#
32+
# remote_file = "https://url/project.toml"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.vagrant
2+
*~
3+
*#
4+
.#*
5+
\#*#
6+
.*.sw[a-z]
7+
*.un~
8+
9+
# Bundler
10+
Gemfile.lock
11+
gems.locked
12+
bin/*
13+
.bundle/*
14+
15+
# test kitchen
16+
.kitchen/
17+
kitchen.local.yml
18+
19+
# Chef Infra
20+
Berksfile.lock
21+
.zero-knife.rb
22+
Policyfile.lock.json
23+
24+
.idea/
25+

cookbooks/fb_letsencrypt/README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
fb_letsencrypt Cookbook
2+
=======================
3+
4+
Requirements
5+
------------
6+
For RHEL or CentOS Stream, EPEL must be already setup.
7+
8+
Attributes
9+
----------
10+
* node['fb_letsencrypt']['manage_packages']
11+
* node['fb_letsencrypt']['certbot_plugins']
12+
* node['fb_letsencrypt']['enable_package_timer']
13+
14+
Usage
15+
-----
16+
### Managing packages
17+
18+
By default, this cookbook will manage certbot-related packages. If you do not
19+
want this, set `node['fb_letsencrypt']['manage_packages']` to `false`.
20+
21+
This cookbook will install both certbot itself as well as any plugin packages
22+
specified in `node['fb_letsencrypt']['certbot_plugins']`, which should only
23+
include the name of the plugin, not the name of the package. For example:
24+
25+
```ruby
26+
node.default['fb_letsencrypt']['certbot_plugins'] += [
27+
'apache',
28+
'dns-cloudflare',
29+
]
30+
```
31+
32+
### Renewal Timers
33+
34+
The certbot package includes a system timer to renew certificates, which we
35+
will keep enabled, by default. If you prefer to manage your own method of
36+
running reneals, you can set `node['fb_letsencrypt']['enable_package_timer']`
37+
to `false`, and this cookbook will disable it so that you may do whatever you
38+
like instead.
39+
40+
### Renewal Configuration
41+
42+
The configuration files for certificate renewals - while human-editable, are
43+
meant to be generated by initial certificate generation. As such we do not
44+
generate or manage them.
45+
46+
### Helper functions
47+
48+
This cookbook includes various helper functions to make it easy to reference
49+
your LetsEncrypt certificates from other cookbooks and to follow best
50+
practices.
51+
52+
#### FB::LetsEncrypt.cert(node, name)
53+
54+
This method returns the path you should use for the certificate in your
55+
service. It actually returns the `fullchain.pem` which is what you should pass
56+
to 'certificate' configuration for your service in nearly all cases.
57+
58+
This method is also aliased as `certificate` and `fullchain`, should you prefer
59+
those.
60+
61+
#### FB::LetsEncrypt.privkey(node, name)
62+
63+
This method returns the path to the private key. It is aliased as `privatekey`
64+
if you prefer.
65+
66+
#### FB::LetsEncrypt.minimal_cert(node, name)
67+
68+
In the event you really want just the leaf certificate, you can call
69+
`minimal_cert` and it will return the path to `cert.pem`. Note that this is
70+
dangerous and will likely lead to certificate validation errors for your
71+
service.
72+
73+
#### FB::LetsEncrypt.onlychain(node, name)
74+
75+
This method returns the path to `chain.pem`. This is rarely needed.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
default['fb_letsencrypt'] = {
2+
'manage_packages' => true,
3+
'certbot_plugins' => [],
4+
'enable_package_timer' => true,
5+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#
2+
# Copyright:: 2025-present, Meta Platforms, Inc.
3+
# Copyright:: 2025-present, Phil Dibowitz
4+
# All rights reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
# rubocop:disable Style/ClassVars
20+
module FB
21+
class LetsEncrypt
22+
# Makes all these class methods without the `self.` and allows
23+
# `alias` to work.
24+
class << self
25+
@@base_dir = nil
26+
27+
def _base_dir(node)
28+
@@base_dir ||= node.value_for_platform(
29+
:windows => {
30+
:default => ::File.join('C:\certbot', 'live'),
31+
},
32+
:default => ::File.join('/etc', 'letsencrypt', 'live'),
33+
)
34+
end
35+
36+
def _pki_path(node, name, filetype)
37+
::File.join(_base_dir(node), name, "#{filetype}.pem")
38+
end
39+
40+
def cert(node, name)
41+
_pki_path(node, name, 'fullchain')
42+
end
43+
alias certificate cert
44+
alias fullchain cert
45+
alias crt cert
46+
47+
def privkey(node, name)
48+
_pki_path(node, name, 'privkey')
49+
end
50+
alias privatekey privkey
51+
alias key privkey
52+
53+
def minimal_cert(node, name)
54+
_pki_path(node, name, 'cert')
55+
end
56+
57+
def onlychain(node, name)
58+
_pki_path(node, name, 'chain')
59+
end
60+
end
61+
end
62+
end
63+
# rubocop:enable Style/ClassVars
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name 'fb_letsencrypt'
2+
maintainer 'Meta Platforms, Inc.'
3+
maintainer_email 'noreply@facebook.com'
4+
license 'Apache-2.0'
5+
description 'Managed letsencrypt'
6+
version '0.1.0'
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#
2+
# Cookbook:: fb_letsencrypt
3+
# Recipe:: default
4+
#
5+
# Copyright:: 2025-present, Meta Platforms, Inc.
6+
# Copyright:: 2025-present, Phil Dibowitz
7+
# All rights reserved.
8+
#
9+
# Licensed under the Apache License, Version 2.0 (the "License");
10+
# you may not use this file except in compliance with the License.
11+
# You may obtain a copy of the License at
12+
#
13+
# http://www.apache.org/licenses/LICENSE-2.0
14+
#
15+
# Unless required by applicable law or agreed to in writing, software
16+
# distributed under the License is distributed on an "AS IS" BASIS,
17+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
# See the License for the specific language governing permissions and
19+
# limitations under the License.
20+
#
21+
22+
package 'certbot packages' do
23+
only_if { node['fb_letsencrypt']['manage_packages'] }
24+
package_name lazy {
25+
(
26+
%w{certbot} + node['fb_letsencrypt']['certbot_plugins'].map do |plugin|
27+
"python3-certbot-#{plugin}"
28+
end
29+
).uniq
30+
}
31+
action :upgrade
32+
end
33+
34+
service 'conditionally enable certbot.timer' do
35+
only_if { node['fb_letsencrypt']['enable_package_timer'] }
36+
service_name 'certbot.timer'
37+
action :enable
38+
end
39+
40+
service 'conditionally disable certbot.timer' do
41+
not_if { node['fb_letsencrypt']['enable_package_timer'] }
42+
service_name 'certbot.timer'
43+
action :disable
44+
end

cookbooks/fb_smartmon/metadata.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
license 'All Rights Reserved'
66
source_url 'https://github.com/facebook/chef-cookbooks/'
77
description 'Installs/Configures fb_smartmon'
8-
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
98
# never EVER change this number, ever.
109
version '0.1.0'
1110
depends 'fb_helpers'

0 commit comments

Comments
 (0)