# @summary A concourse web node. # # # @param service # The name of the system service. # This service WILL be managed by us. # @param service_unit # Exact unit name (in terms of systemd) of the service. # @param conf_file # Where configuration environment variables will be stored. # Currently hard-coded in the service file. # @param conf_dir # Where additional environment files will be stored. Used (at # least) by each auth resource. # @param purge_conf_dir # Should the directory mentioned in `conf_dir` be purged. If this # is true then decomissioning sub-configurations are done by simply # removing that resource. # @param ensure # @param cluster # Which concourse this web node is part of. An # `nginx::resource::upstream::member` resource will be exported, # which can be realized by the `concourse::proxy::nginx` resource. # # @param peer_address # Address to use when connecting this node to the cluster. # Should preferably be a private address, since the cluster should # only be exposed publicly through the load balancer. # # Despite that, defaults to `$facts['ipaddress']`, since that # forces it to work. # # Note that concourse always binds on port 8080, this is currently # not configurable. # # @param postgres_user # @param postgres_password # @param session_signing_key # # Maps to `CONCOURSE_SESSION_SIGNING_KEY`, and is the key private key generated by # concourse generate-key -t rsa -f ./session_signing_key # That command will also emit a public key, but that key should be discarded since it's unused. # # This key is used for signing and verifying user session tokens. # # @param tsa_private_key # Private key used to validate SSH connections from workers. # # Generated by # concourse generate-key -t ssh -f ./tsa_host_key # # Maps to `CONCOURSE_TSA_HOST_KEY`, and the public part should be passed to each worker. # # @param worker_public_keys # @param key_dir # @param session_signing_key_file # @param tsa_host_key_file # @param tsa_authorized_keys_file # @param postgres_host # @param postgres_port # @param postgres_socket # @param postgres_database # @param external_url # Publicly facing url of this cluster. Mainly used by the web server to generate proper links. # # For example, 'https://concourse.example.com' # @param api_max_conns # @param backend_max_conns # @param packages class concourse::web ( String $cluster = $concourse::default_cluster, String $postgres_user = $concourse::configured_clusters[$cluster]['postgres_user'], Variant[String, Sensitive[String]] $postgres_password = $concourse::configured_clusters[$cluster]['postgres_password'], Variant[String, Sensitive[String]] $session_signing_key = $concourse::configured_clusters[$cluster]['session_signing_key'], Variant[String, Sensitive[String]] $tsa_private_key = $concourse::configured_clusters[$cluster]['tsa_private_key'], Array[String] $worker_public_keys = [], String $key_dir = $concourse::key_dir, String $session_signing_key_file = "${key_dir}/session_signing_key", String $tsa_host_key_file = "${key_dir}/tsa_host_key", String $tsa_authorized_keys_file = "${key_dir}/authorized_worker_keys", String $peer_address = $facts['ipaddress'], Optional[String] $postgres_host = undef, Optional[String] $postgres_port = undef, Optional[Stdlib::Unixpath] $postgres_socket = undef, Optional[String] $postgres_database = undef, String $external_url = "https://${concourse::configured_clusters[$cluster]['external_domain']}", Optional[Integer] $api_max_conns = undef, Optional[Integer] $backend_max_conns = undef, String $service = 'concourse', String $service_unit = "${service}.service", Stdlib::Absolutepath $conf_file = '/etc/conf.d/concourse', Stdlib::Absolutepath $conf_dir = '/etc/conf.d/concourse.d', Boolean $purge_conf_dir = true, Enum['absent', 'present'] $ensure = 'present', Array[String] $packages = [ 'concourse', 'concourse-resource-types', ], ) { include concourse ensure_packages($packages, { ensure => $ensure, }) $env = { 'CONCOURSE_SESSION_SIGNING_KEY' => $session_signing_key_file, 'CONCOURSE_TSA_HOST_KEY' => $tsa_host_key_file, 'CONCOURSE_TSA_AUTHORIZED_KEYS' => $tsa_authorized_keys_file, 'CONCOURSE_POSTGRES_USER' => $postgres_user, 'CONCOURSE_POSTGRES_PASSWORD' => $postgres_password ? { String => $postgres_password, default => $postgres_password.unwrap, }, 'CONCOURSE_CLUSTER' => $cluster, 'CONCOURSE_PEER_ADDRESS' => $peer_address, 'CONCOURSE_POSTGRES_HOST' => $postgres_host, 'CONCOURSE_POSTGRES_PORT' => $postgres_port, 'CONCOURSE_POSTGRES_SOCKET' => $postgres_socket, 'CONCOURSE_POSTGRES_DATABASE' => $postgres_database, 'CONCOURSE_EXTERNAL_URL' => $external_url, 'CONCOURSE_API_MAX_CONNS' => $api_max_conns, 'CONCOURSE_BACKEND_MAX_CONNS' => $backend_max_conns, } file { $conf_file: ensure => $ensure, mode => '0600', show_diff => false, content => epp("${module_name}/env.epp", { 'entries' => $env }), } file { $conf_dir: ensure => if $ensure == 'present' { 'directory' } else { 'absent' }, purge => $purge_conf_dir, recurse => true, notify => Service[$service], } file { $key_dir: ensure => if $ensure == 'present' { 'directory' } else { 'absent' }, # TODO this also chmod's all children... mode => '0700', recurse => true, force => true, } file { default: ensure => $ensure, mode => '0600', ; $session_signing_key_file: content => $session_signing_key, ; $tsa_host_key_file: content => $tsa_private_key, ; } concat { "authorized_worker_key - ${cluster}": path => $tsa_authorized_keys_file, warn => '# File managed by puppet, local changes WILL be overwritten', ensure_newline => true, } $worker_public_keys.each |$key| { concat::fragment { sha1($key): content => $key, target => "authorized_worker_keys - ${cluster}", } } Concourse::Worker_key <<| cluster == $cluster |>> systemd::unit_file { $service_unit: ensure => $ensure, source => "puppet:///modules/${module_name}/concourse-web.service", } ~> service { $service: ensure => if $ensure == 'present' { 'running' } else { 'stopped' }, enable => true, } # Exported resource @@nginx::resource::upstream::member { $trusted['certname']: ensure => $ensure, upstream => $cluster, server => $peer_address, port => 8080, } }