apt_utils CHANGELOG
===================
+0.2.3
+-----
+- adds a reverse proxy (nginx) service with SSL setup feature to the `apt_utils::aptly-docker-compose` recipe.
+
0.2.2
-----
- adds the `apt_utils::aptly-docker-compose` recipe.
- [apt_utils::apt](#apt_utilsapt)
- [apt_utils::aptly](#apt_utilsaptly)
- [apt_utils::aptly-docker-compose](#apt_utilsaptly-docker-compose)
+ - [SSL server keys and certificates management by the `ssl_cert` cookbook](#ssl-server-keys-and-certificates-management-by-the-ssl_cert-cookbook)
- [apt_utils::conf](#apt_utilsconf)
- [apt_utils::apt-cacher-ng](#apt_utilsapt-cacher-ng)
- [apt_utils::mirror](#apt_utilsmirror)
|`['apt_utils']['aptly']['apt_repo']['recv-keys']`|String||`'9E3E53F19C7DE460'`|
|`['apt_utils']['aptly']['user']`|String||`'root'`|
|`['apt_utils']['aptly']['conf']`|Hash|`aptly.conf` configurations.|See `attributes/default.rb`|
+|`['apt_utils']['aptly']['with_ssl_cert_cookbook']`|Boolean|Activates TLS configurations by the `ssl_cert` cookbook. See `attributes/default.rb`|`false`|
+|`['apt_utils']['aptly']['ssl_cert']['common_name']`|String|Server common name for TLS|`node['fqdn']`|
|`['apt_utils']['aptly']['docker-compose']['app_dir']`|String|aptly app. root directory for docker-compose.|`"#{node['docker-grid']['compose']['app_dir']}/aptly"`|
+|`['apt_utils']['aptly']['docker-compose']['etc_dir']`|String||`"#{node['apt_utils']['aptly']['docker-compose']['app_dir']}/etc"`|
|`['apt_utils']['aptly']['docker-compose']['data_dir']`|String|Persistent volume path or nil (unset).|`"#{node['apt_utils']['aptly']['docker-compose']['app_dir']}/data"`|
|`['apt_utils']['aptly']['docker-compose']['config']`|Hash|`docker-compose.yml` configurations.|See `attributes/default.rb`|
|`['apt_utils']['apt-cacher-ng']['CacheDir']`|String|path to cache directory|`'/var/cache/apt-cacher-ng'`|
'config' => {
'version' => '2',
'services' => {
+ 'reverseproxy' => {
+ 'ports' => [
+ "#{aptly_port}:8080",
+ "#{aptly_api_port}:8081",
+ ],
+ 'volumes' => [
+ # This volume will be set by the apt_utils::aptly-docker-compose recipe automatically.
+ #"#{node['apt_utils']['aptly']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
+ ],
+ },
'aptly' => {
'restart' => 'always',
'image' => 'whitestar/aptly',
+ 'volumes' => [
+ # This volume will be set by the apt_utils::aptly-docker-compose recipe automatically.
+ #"#{node['apt_utils']['aptly']['docker-compose']['data_dir']}:/aptly-data:rw",
+ ],
+ 'environment' => {
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+)
+```
+
+- `roles/aptly-with-ssl-docker-compose.rb`: SSL setup role example.
+
+```ruby
+name 'aptly-with-ssl-docker-compose'
+description 'aptly with SSL by docker-compose'
+
+run_list(
+ 'recipe[ssl_cert::server_key_pairs]',
+ 'role[docker]',
+ 'recipe[apt_utils::aptly-docker-compose]',
+)
+
+aptly_port = '8080'
+aptly_api_port = '8081'
+cn = 'aptly.io.example.com'
+
+override_attributes(
+ 'ssl_cert' => {
+ 'common_names' => [
+ cn,
+ ],
+ },
+ 'apt_utils' => {
+ 'aptly' => {
+ 'with_ssl_cert_cookbook' => true,
+ 'ssl_cert' => {
+ 'common_name' => cn,
+ },
+ 'docker-compose' => {
+ 'config' => {
+ 'version' => '2',
+ 'services' => {
+ 'reverseproxy' => {
'ports' => [
"#{aptly_port}:8080",
"#{aptly_api_port}:8081",
],
'volumes' => [
+ # These volumes will be set by the apt_utils::aptly-docker-compose recipe automatically.
+ #"#{node['apt_utils']['aptly']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
+ # and server key pair volume conf.
+ ],
+ },
+ 'aptly' => {
+ 'restart' => 'always',
+ 'image' => 'whitestar/aptly',
+ 'volumes' => [
# This volume will be set by the apt_utils::aptly-docker-compose recipe automatically.
#"#{node['apt_utils']['aptly']['docker-compose']['data_dir']}:/aptly-data:rw",
],
)
```
+##### SSL server keys and certificates management by the `ssl_cert` cookbook
+
+- create vault items.
+
+```text
+$ ruby -rjson -e 'puts JSON.generate({"private" => File.read("aptly.io.example.com.prod.key")})' \
+> > ~/tmp/aptly.io.example.com.prod.key.json
+
+$ ruby -rjson -e 'puts JSON.generate({"public" => File.read("aptly.io.example.com.prod.crt")})' \
+> > ~/tmp/aptly.io.example.com.prod.crt.json
+
+$ cd $CHEF_REPO_PATH
+
+$ knife vault create ssl_server_keys aptly.io.example.com.prod \
+> --json ~/tmp/aptly.io.example.com.prod.key.json
+
+$ knife vault create ssl_server_certs aptly.io.example.com.prod \
+> --json ~/tmp/aptly.io.example.com.prod.crt.json
+```
+
+- grant reference permission to the Concourse host
+
+```text
+$ knife vault update ssl_server_keys aptly.io.example.com.prod -S 'name:aptly-host.example.com'
+$ knife vault update ssl_server_certs aptly.io.example.com.prod -S 'name:aptly-host.example.com'
+```
+
+- modify run_list and attributes
+
+```ruby
+run_list(
+ 'recipe[ssl_cert::server_key_pairs]',
+ 'recipe[apt_utils::aptly-docker-compose]',
+)
+
+override_attributes(
+ 'ssl_cert' => {
+ 'common_names' => [
+ 'aptly.io.example.com',
+ ],
+ },
+ 'aptly-grid' => {
+ 'with_ssl_cert_cookbook' => true,
+ 'ssl_cert' => {
+ 'common_name' => 'nexus.io.example.com',
+ },
+ # ...
+ },
+)
+```
+
#### apt_utils::conf
- deploys apt configuration files to the `/etc/apt/apt.conf.d` directory.
#'deb http://ftp.grid.example.com:3142/security.debian.org/ wheezy/updates main contrib non-free'
]
+default['apt_utils']['aptly']['with_ssl_cert_cookbook'] = false
+# If ['apt_utils']['aptly']['with_ssl_cert_cookbook'] is true,
+# node['apt_utils']['aptly']['docker-compose']['config']
+# are overridden by the following 'common_name' attributes.
+default['apt_utils']['aptly']['ssl_cert']['ca_names'] = []
+default['apt_utils']['aptly']['ssl_cert']['common_name'] = node['fqdn']
default['apt_utils']['aptly']['apt_repo'] = {
'keyserver' => 'keys.gnupg.net',
'recv-keys' => '9E3E53F19C7DE460',
'SwiftPublishEndpoints' => {},
}
default['apt_utils']['aptly']['docker-compose']['app_dir'] = "#{node['docker-grid']['compose']['app_dir']}/aptly"
+default['apt_utils']['aptly']['docker-compose']['etc_dir'] = "#{node['apt_utils']['aptly']['docker-compose']['app_dir']}/etc"
default['apt_utils']['aptly']['docker-compose']['data_dir'] = "#{node['apt_utils']['aptly']['docker-compose']['app_dir']}/data"
force_override['apt_utils']['aptly']['docker-compose']['config_format_version'] = '2'
version_2_config = {
# Version 2 docker-compose format
'version' => '2',
'services' => {
+ 'reverseproxy' => {
+ 'depends_on' => [
+ 'aptly',
+ ],
+ 'restart' => 'always',
+ 'image' => 'nginx:alpine',
+ 'expose' => [
+ '8080',
+ '8081',
+ ],
+ 'ports' => [
+ #'8080:8080', # distribution service
+ #'8081:8081', # API service
+ ],
+ 'volumes' => [
+ # This volume will be set by the apt_utils::aptly-docker-compose recipe automatically.
+ #"#{node['apt_utils']['aptly']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
+ ],
+ },
'aptly' => {
'restart' => 'always',
'image' => 'whitestar/aptly',
+ # -> reverseproxy
'ports' => [
#'8080:8080', # distribution service
#'8081:8081', # API service
# limitations under the License.
#
-#::Chef::Recipe.send(:include, SSLCert::Helper)
-
doc_url = 'https://www.aptly.info/doc/overview/'
include_recipe 'platform_utils::kernel_user_namespace'
app_dir = node['apt_utils']['aptly']['docker-compose']['app_dir']
data_dir = node['apt_utils']['aptly']['docker-compose']['data_dir']
-etc_dir = "#{app_dir}/etc"
+etc_dir = node['apt_utils']['aptly']['docker-compose']['etc_dir']
[
app_dir,
etc_dir,
+ "#{etc_dir}/nginx",
].each {|dir|
resources(directory: dir) rescue directory dir do
owner 'root'
config_srvs = node['apt_utils']['aptly']['docker-compose']['config']['services']
override_config_srvs = node.override['apt_utils']['aptly']['docker-compose']['config']['services']
#force_override_config_srvs = node.force_override['apt_utils']['aptly']['docker-compose']['config']['services']
-#envs_org = config_srvs['aptly']['environment']
-#envs = {}
-vols = config_srvs['aptly']['volumes'].to_a
+#aptly_envs_org = config_srvs['aptly']['environment']
+#aptly_envs = {}
+rproxy_vols = config_srvs['reverseproxy']['volumes'].to_a
+aptly_vols = config_srvs['aptly']['volumes'].to_a
+
+ports = config_srvs['reverseproxy']['ports']
+override_config_srvs['reverseproxy']['ports'] = ['8080:8080', '8081:8081'] if ports.empty?
+
+template "#{etc_dir}/nginx/nginx.conf" do
+ source 'opt/docker-compose/app/aptly/etc/nginx/nginx.conf'
+ owner 'root'
+ group 'root'
+ mode '0644'
+ action :create
+end
+
+rproxy_vols.push("#{etc_dir}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro")
override_aptly_conf['rootDir'] = '/aptly-data'
template "#{etc_dir}/aptly.conf" do
action :create
end
-vols.push("#{etc_dir}/aptly.conf:/etc/aptly.conf:rw")
+aptly_vols.push("#{etc_dir}/aptly.conf:/etc/aptly.conf:rw")
# Data persistent
if !data_dir.nil? && !data_dir.empty?
recursive true
end
- vols.push("#{data_dir}:/aptly-data:rw")
+ aptly_vols.push("#{data_dir}:/aptly-data:rw")
end
-ports = config_srvs['aptly']['ports']
-override_config_srvs['aptly']['ports'] = ['8080:8080', '8081:8081'] if ports.empty?
+if node['apt_utils']['aptly']['with_ssl_cert_cookbook']
+ ::Chef::Recipe.send(:include, SSLCert::Helper)
+ cn = node['apt_utils']['aptly']['ssl_cert']['common_name']
+ # Concourse web process owner is root.
+ rproxy_vols.push("#{server_cert_path(cn)}:/root/server.crt:ro")
+ rproxy_vols.push("#{server_key_path(cn)}:/root/server.key:ro")
+end
# merge environment hash
-#force_override_config_srvs['aptly']['environment'] = envs unless envs.empty?
+#force_override_config_srvs['aptly']['environment'] = envs unless aptly_envs.empty?
# reset vlumes array.
-override_config_srvs['aptly']['volumes'] = vols unless vols.empty?
+override_config_srvs['reverseproxy']['volumes'] = rproxy_vols unless rproxy_vols.empty?
+override_config_srvs['aptly']['volumes'] = aptly_vols unless aptly_vols.empty?
config_file = "#{app_dir}/docker-compose.yml"
template config_file do
--- /dev/null
+<%
+ssl_enabled = node['apt_utils']['aptly']['with_ssl_cert_cookbook']
+-%>
+worker_processes 1;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ sendfile on;
+
+ upstream docker-aptly {
+ server aptly:8080;
+ }
+
+ upstream docker-aptly-api {
+ server aptly:8081;
+ }
+
+ server {
+<% if ssl_enabled %>
+ listen 8080 default ssl;
+ ssl on;
+ ssl_certificate /root/server.crt;
+ ssl_certificate_key /root/server.key;
+<% else %>
+ listen 8080;
+<% end %>
+
+ location / {
+ proxy_pass http://docker-aptly;
+ proxy_redirect off;
+ proxy_set_header Host $http_host; # $host does not include the port number.
+ proxy_set_header X-Real-IP $remote_addr;
+<% if ssl_enabled %>
+ proxy_set_header X-Forwarded-Proto https;
+<% end %>
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Host $server_name;
+ }
+ }
+
+ server {
+<% if ssl_enabled %>
+ listen 8081 default ssl;
+ ssl on;
+ ssl_certificate /root/server.crt;
+ ssl_certificate_key /root/server.key;
+<% else %>
+ listen 8081;
+<% end %>
+
+ location / {
+ proxy_pass http://docker-aptly-api;
+ proxy_redirect off;
+ proxy_set_header Host $http_host; # $host does not include the port number.
+ proxy_set_header X-Real-IP $remote_addr;
+<% if ssl_enabled %>
+ proxy_set_header X-Forwarded-Proto https;
+<% end %>
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Host $server_name;
+ }
+ }
+}