diff options
author | Hugo Hörnquist <hugo@lysator.liu.se> | 2023-06-15 19:03:23 +0200 |
---|---|---|
committer | Hugo Hörnquist <hugo@lysator.liu.se> | 2023-06-15 19:03:23 +0200 |
commit | 73b98210f69455b33116f8c2ca3aab6daf473bab (patch) | |
tree | 1c059346ab41ac895ddbf1e7b4cc10918b6cdb18 | |
parent | Initial commit. (diff) | |
download | concourse-73b98210f69455b33116f8c2ca3aab6daf473bab.tar.gz concourse-73b98210f69455b33116f8c2ca3aab6daf473bab.tar.xz |
Initial add.
-rw-r--r-- | README.md | 77 | ||||
-rw-r--r-- | TODO.md | 3 | ||||
-rw-r--r-- | files/concourse-web.service | 10 | ||||
-rw-r--r-- | files/concourse-worker.service | 9 | ||||
-rw-r--r-- | lib/facter/concourse_worker_key.rb | 8 | ||||
-rw-r--r-- | manifests/auth/ldap.pp | 49 | ||||
-rw-r--r-- | manifests/auth/local.pp | 72 | ||||
-rw-r--r-- | manifests/database.pp | 13 | ||||
-rw-r--r-- | manifests/fly.pp | 12 | ||||
-rw-r--r-- | manifests/init.pp | 11 | ||||
-rw-r--r-- | manifests/keys.pp | 8 | ||||
-rw-r--r-- | manifests/proxy/nginx.pp | 34 | ||||
-rw-r--r-- | manifests/web.pp | 165 | ||||
-rw-r--r-- | manifests/worker.pp | 140 | ||||
-rw-r--r-- | manifests/worker_key.pp | 10 | ||||
-rw-r--r-- | metadata.json | 44 | ||||
-rw-r--r-- | templates/env.epp | 9 |
17 files changed, 674 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..6f51548 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +Concourse +========= + +Manages all parts of [Concourse](CONCOURSE), including web nodes, worker +nodes, and databases. + +Usage +----- + +### Nodes + +#### Web node +Web nodes acts as the front-end, and dispatcher. + +Each web node is stateless, and manages its state through a shared +database. If multiple nodes are used, then a +[web node cluster](#web node cluster) +should be used. + +(technically clusters are always used, and default to the cluster "default"). + +```puppet +class { 'concourse::web': + postgres_user => '', + postgres_password => '', +} +``` + +##### Authentication + +#### Worker Node + +#### Database + +#### Fly Client + +#### Web node cluster + + +### Special Hiera Keys +- `concourse::${cluster}::postgres_user` +- `concourse::${cluster}::postgres_password` +- `concourse::${cluster}::session_signing_key` +- `concourse::${cluster}::tsa_private_key` +- `concourse::${cluster}::tsa_public_key` + +Keys +---- +### Session signing key +Used by the web node for signing and verifying user session tokens. + +### TSA host key +Used by the web node for the SSH worker registration gateway server ("TSA"). + +The public key is given to each worker node to verify the remote host wthen +connecting via SSH. + +### Worker key + +Each worker node verifies its registration with the web node via a SSH key. + +The public key must be listed in the web node's *authorized worker keys* file +in order for the worker to register. + +Hiera Examples +-------------- + +```yaml +concourse::cluster::tsa_host: concourse.example.com +concourse::cluster::postgres_user: concourse +concourse::cluster::postgres_password: MySuperSecretPassword +concourse::cluster::session_signing_key: 'A valid key' +concourse::cluster::tsa_private_key: 'A valid key' +concourse::cluster::tsa_private_key: 'A valid key' +``` + +[CONCOURSE]: https://concourse-ci.org/ @@ -0,0 +1,3 @@ +## nginx rev_proxy ssh +Worker nodes connect to the master through ssh, on port 2222 (by default). This +should be load balanced through the nginx proxy to go to any of the web nodes. diff --git a/files/concourse-web.service b/files/concourse-web.service new file mode 100644 index 0000000..05b74e9 --- /dev/null +++ b/files/concourse-web.service @@ -0,0 +1,10 @@ +[Unit] +Description=Continous thing-doer. + +[Service] +ExecStart=concourse web +Exec=kill -HUP $MAINPID +EnvironmentFile=/etc/conf.d/concourse + +[Install] +WantedBy=multi-user.target diff --git a/files/concourse-worker.service b/files/concourse-worker.service new file mode 100644 index 0000000..3aa492d --- /dev/null +++ b/files/concourse-worker.service @@ -0,0 +1,9 @@ +[Unit] +Description=Worker for Concourse + +[Service] +ExecStart=concourse worker --healthcheck-bind-ip="${HEALTHCHECK_BIND_IP}" --bealthcheck-bind-port="${HEALTHCHECK_BIND_PORT}" --healthcheck-timeout="${HEALTHCHECK_TIMEOUT}" +EnvironmentFile=/etc/conf.d/concourse-worker + +[Install] +WantedBy=multi-user.target diff --git a/lib/facter/concourse_worker_key.rb b/lib/facter/concourse_worker_key.rb new file mode 100644 index 0000000..f0d9398 --- /dev/null +++ b/lib/facter/concourse_worker_key.rb @@ -0,0 +1,8 @@ +Facter.add(:concourse_worker_key) do + confine do + File.exists? '/usr/lib/concourse/worker_key.pub' + end + setcode do + Facter::Core::Execution.execute('cat /usr/lib/concourse/worker_key.pub') + end +end diff --git a/manifests/auth/ldap.pp b/manifests/auth/ldap.pp new file mode 100644 index 0000000..7e4472b --- /dev/null +++ b/manifests/auth/ldap.pp @@ -0,0 +1,49 @@ +# @summary Concourse local authentication +# @param users +# List of local users. +# @param main_team_users +# List of users which should be added to the "main" team. +# @param main_team_group +# Ignored, but here to keep the same "API" with the other auth modules. +class concourse::auth::local ( + Array[Struct[{ + 'name' => String, + 'password' => Variant[String, Sensitive[String]], + }]] $users, + Optional[Array[String]] $main_team_user, + Optional[Array[String]] $main_team_group, # ignored + Enum['absent', 'present'] $ensure = 'present', +) { + $env_file = "${concourse::web::conf_dir}/auth-local" + + $environment = { + 'CONCOURSE_ADD_LOCAL_USER' => $users.map |$user| { + $name = $user['name'] + $pass = $user['password'] ? { + String => $user['password'], + default => $user['password'].unwrap, + } + "${name}:${pass}" + }.join(','), + 'CONCOURSE_MAIN_TEAM_LOCAL_USER' => $main_team_group ? { + Array => $main_team_group.join(','), + default => undef, + }, + } + + file { $env_file: + ensure => $ensure, + content => epp("${module_name}/env.epp", $environment), + # To not show new password + show_diff => false, + mode => '0600', + } + + systemd::manage_dropin { 'concourse-local-auth': + ensure => $ensure, + unit => $concourse::web::service, + service_entry => { + 'EnvironmentFile' => $env_file, + }, + } +} diff --git a/manifests/auth/local.pp b/manifests/auth/local.pp new file mode 100644 index 0000000..289ce15 --- /dev/null +++ b/manifests/auth/local.pp @@ -0,0 +1,72 @@ +# @summary Concourse LDAP authentication +# Most attributes maps directly to concourse's options, but with +# `CONCOURSE_LDAP_` prefixed. +class concourse::auth::ldap ( + String $host, + String $bind_dn, + Variant[String, Sensitive[String]] $bind_pw, + String $user_search_base_dn, + String $user_search_username = 'uid', + Optional[String] $display_name = undef, + Optional[String] $user_search_filter = undef, + Optioal[String] $user_search_id_attr = undef, + Optional[String] $user_search_email_attr = undef, + Optional[String] $user_search_name_attr = undef, + Optional[Stdlib::Absolutepath] $ca_cert = undef, + Boolean $insecure_no_ssl = false, + Optional[String] $group_search_base_dn = undef, + String $group_search_name_attr = 'ou', + String $group_search_user_attr = 'uid', + String $group_search_group_attr = 'members', + Optional[String] $group_search_filter = undef, + Optional[Array[String]] $main_team_user, + Optional[Array[String]] $main_team_group, + + Enum['absent', 'present'] $ensure = 'present', +) { + $env_file = "${concourse::web::conf_dir}/auth-ldap" + + $environment = { + 'CONCOURSE_LDAP_HOST' => $host, + 'CONCOURSE_LDAP_BIND_DN' => $bind_dn, + 'CONCOURSE_LDAP_BIND_PW' => $bind_pw, + 'CONCOURSE_LDAP_USER_SEARCH_BASE_DN' => $user_search_base_dn, + 'CONCOURSE_LDAP_USER_SEARCH_USERNAME' => $user_search_username, + 'CONCOURSE_LDAP_DISPLAY_NAME' => $display_name, + 'CONCOURSE_LDAP_USER_SEARCH_FILTER' => $user_search_filter, + 'CONCOURSE_LDAP_USER_SEARCH_ID_ATTR' => $user_search_id_attr, + 'CONCOURSE_LDAP_USER_SEARCH_EMAIL_ATTR' => $user_search_email_attr, + 'CONCOURSE_LDAP_USER_SEARCH_NAME_ATTR' => $user_search_name_attr, + 'CONCOURSE_LDAP_CA_CERT' => $ca_cert, + 'CONCOURSE_LDAP_INSECURE_NO_SSL' => $insecure_no_ssl, + 'CONCOURSE_LDAP_GROUP_SEARCH_BASE_DN' => $group_search_base_dn, + 'CONCOURSE_LDAP_GROUP_SEARCH_NAME_ATTR' => $group_search_name_attr, + 'CONCOURSE_LDAP_GROUP_SEARCH_USER_ATTR' => $group_search_user_attr, + 'CONCOURSE_LDAP_GROUP_SEARCH_GROUP_ATTR' => $group_search_group_attr, + 'CONCOURSE_LDAP_GROUP_SEARCH_FILTER' => $group_search_filter, + 'CONCOURSE_LDAP_MAIN_TEAM_LDAP_USER' => $main_team_user ? { + Array => $main_team_user.join(','), + default => undef, + }, + 'CONCOURSE_LDAP_MAIN_TEAM_LDAP_GROUP' => $main_team_group ? { + Array => $main_team_user.join(','), + default => undef, + }, + } + + file { $env_file: + ensure => $ensure, + content => epp("${module_name}/env.epp", $environment), + # To not show new password + show_diff => false, + mode => '0600', + } + + systemd::manage_dropin { 'concourse-ldap-auth': + ensure => $ensure, + unit => $concourse::web::service, + service_entry => { + 'EnvironmentFile' => $env_file, + }, + } +} diff --git a/manifests/database.pp b/manifests/database.pp new file mode 100644 index 0000000..d921cc9 --- /dev/null +++ b/manifests/database.pp @@ -0,0 +1,13 @@ +class concourse::database ( + String $username = lookup("concourse::${cluster}::postgres_user"),, + Variant[String, Sensitive[String]] $password = lookup("concourse::${cluster}::postgres_user"), + String $db_name = "atc-${cluster}", + String $cluster = $concourse::default_cluster, +) { + postgresql::server::db { $db_name: + user => $username, + password => $password, + grant => 'ALL', + comment => 'Concourse CI', + } +} diff --git a/manifests/fly.pp b/manifests/fly.pp new file mode 100644 index 0000000..b9e1e71 --- /dev/null +++ b/manifests/fly.pp @@ -0,0 +1,12 @@ +# @summary Manage a concourse client node +# +# Fly is the name of the concourse client command line. +# +# @param ensure +class concourse::fly ( + Enum['absent', 'present'] $ensure = 'present', +) { + ensure_packages(['concourse-fly-cli'], { + 'ensure' => $ensure, + }) +} diff --git a/manifests/init.pp b/manifests/init.pp new file mode 100644 index 0000000..8b70bd6 --- /dev/null +++ b/manifests/init.pp @@ -0,0 +1,11 @@ +# Global defaults for defined resource types. +# @param worker_work_dir +# Default work dir for each worker +# @param default_cluster +# Cluster used by all resources if no specific cluster is specified. +class concourse ( + String $worker_work_dir = '/opt/concourse/worker', + String $default_cluster = 'default', + String $worker_service = 'concourse-worker', +) { +} diff --git a/manifests/keys.pp b/manifests/keys.pp new file mode 100644 index 0000000..dc5fe19 --- /dev/null +++ b/manifests/keys.pp @@ -0,0 +1,8 @@ +define concourse::keys ( +) { + @@tsa_host_key { + } + + @@kj +} + diff --git a/manifests/proxy/nginx.pp b/manifests/proxy/nginx.pp new file mode 100644 index 0000000..7e4b9a2 --- /dev/null +++ b/manifests/proxy/nginx.pp @@ -0,0 +1,34 @@ +define concourse::proxy::nginx ( + String $server_name, + String $cluster, + Enum['absent', 'present'] $ensure = 'present', +) { + include concourse + + nginx::resource::upstream { "concourse - ${cluster}": + ensure => $ensure, + } + + nginx::resource::server { $server_name: + } + + nginx::resource::location { "${server_name} - /": + location => '/', + proxy_pass => "http://${cluster}", + } + + nginx::resource::location { "${server_name} - ~ /hijack$": + location => '~ /hijack$', + proxy_pass => "http://${cluster}", + proxy_set_header => [ + 'Host $host', + 'X-Real-IP $remote_addr', + 'X-Forwarded-For $proxy_add_x_forwarded_for', + 'X-Forwarded-Host $host', + 'X-Forwarded-Proto $scheme', + 'Proxy ""', + 'Upgrade $http_upgrade', + 'Connection "upgrade"', + ], + } +} diff --git a/manifests/web.pp b/manifests/web.pp new file mode 100644 index 0000000..f89ac4e --- /dev/null +++ b/manifests/web.pp @@ -0,0 +1,165 @@ +# @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 +# If this web node is part of a cluster of web nodes, name that +# cluster. This will create an `nginx::resoruce::upstream::member` +# resource for this node, which should be realized by +# `concourse::proxy::nginx` +# +# Also requires `peer_address` to be set +# +# @param peer_address +# Peer address used when used in a cluster +# +# Also requires `cluster` to be set. +# +# Remaining keys maps directly to concourse configurations. +class concourse::web ( + String $postgres_user = lookup("concourse::${cluster}::postgres_user"), + Variant[String, Sensitive[String]] $postgres_password = lookup("concourse::${cluster}::postgres_password"), + + Variant[String, Sensitive[String]] $session_signing_key = lookup("concourse::${cluster}::session_signing_key"), + Variant[String, Sensitive[String]] $tsa_private_key = lookup("concourse::${cluster}::tsa_private_key"), + Variant[String, Sensitive[String]] $tsa_public_key = lookup("concourse::${cluster}::tsa_public_key"), + Array[String] $worker_public_keys = [], + + String $key_dir = '/usr/lib/concourse', + 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 $cluster = 'default', + Optional[String] $peer_address = undef, + + Optional[String] $postgres_host = undef, + Optional[String] $postgres_port = undef, + Optional[Stdlib::Unixpath] $postgres_socket = undef, + + Optional[String] $postgres_database = undef, + + Optional[String] $external_url = undef, + + Optional[Integer] $api_max_conns = undef, + Optional[Integer] $backend_max_conns = undef, + + String $service = 'concourse', + String $service_unit = "${service}.service", + Std::AbsolutePath $conf_file = '/etc/conf.d/concourse', + Std::AbsolutePath $conf_dir = '/etc/conf.d/concourse.d', + Boolean $purge_conf_dir = true, + Enum['absent', 'present'] $ensure = 'present', + + Array[String] $packages = [ + 'concourse', + 'councourse-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", $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' }, + mode => '0700', + recurse => true, + forge => true, + } + + file { + default: + ensure => $ensure, + mode => '0600', + ; + $session_signing_key_file: + content => $session_signing_key, + ; + $tsa_host_key_file: + conent => $tsa_private_key, + ; + "${tsa_host_key_file}.pub": + content => $tsa_public_key, + ; + } + + concat { "authorized_workers_key - ${cluster}": + target => $tsa_authorized_keys_file, + warning => '# 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}", + } + } + + 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, + } + + if $peer_address { + @@nginx::resource::upstream::member { $facts['trusted']['certname']: + ensure => $ensure, + upstream => "concourse - ${cluster}", + server => $peer_address, + } + } +} diff --git a/manifests/worker.pp b/manifests/worker.pp new file mode 100644 index 0000000..18703f2 --- /dev/null +++ b/manifests/worker.pp @@ -0,0 +1,140 @@ +# @summary A Concourse workre +# +# Declared as a class, since the upstream documentation explicitly states +# that multiple workers on a single node is nonsensical. This may however +# change in future versions of this module, since you the option to limit +# a worker to a specific team or tag exists, and linux can limit the amount +# of resources given to a given process (this gets even easier through systemd, +# which the module currently uses extensively). + +# @param key_dir +# Directory in which keys should be stored. +# @param worker_key_file +# File in which the worker's public key should be stored +# @param worker_private_key_file +# File in which the worker ns private key should be stored. +# @param cluster +# Which concourse cluster this worker should be part of. +# @param service +# Name of the worker service +# @param service_unit +# Name of the (systemd) service unit for the worker. +# @param ensure +# @param work_dir +# Working directory for the worker. +# @param tsa_host +# Network address to the master (web) node that this worker should connect to. +# @param tsa_public_key +# Public key of this workers master. +# @param worker_public_key +# Public key of this worker. Only used if `$manage_private_key` is +# false, otherwise a key will be automatically generated. +# public key exported as a fact. +# @param worker_private_key +# Private key of this worker. Like `worker_public_key`, will only +# be used if `$manage_private_key` is false. This value will however +# *not* be exported. +# @param manage_private_key +# Should this node manage and generate its own public key. If true +# (the default) then a key will automatically be generated, and the +# public portion exported as a fact. +# @param export_public_key +# Should an exported resource with this nodes public key be created. +# This reads the fact from `$worker_public_key` and creates an exported +# resource of type `concourse::worker_key`, which will allow the master +# to realize it. +# @param tag +# List of arbitrary tags to connnect to this worker. Can be used by +# pipelines which requires specific environments. +# @param team +# Limit this worker to a specific team. +# @param healthcheck_bind_ip +# Address to bind the healthcheck endpoint to. +# @param healthcheck_bind_port +# Port to bind the health endpoint to. +# @param healthcheck_timeout +# Timeout for health check. +# @param extra_env +# A hash of extra environment variables which will be passed directly +# to the worker process. +class concourse::worker ( + Std::AbsolutePath $key_dir = '/usr/lib/concourse', + Std::AbsolutePath $worker_key_file = "${key_dir}/worker_key", + Std::AbsolutePath $worker_private_key_file = "${worker_key_file}.pub", + String $cluster = $concourse::default_cluster, + String $service = $concourse::worker_service, + String $service_unit = "${service}.service", + Enum['absent', 'present'] $ensure = 'present', + + String $work_dir = $concourse::worker_work_dir, + String $tsa_host = lookup("concourse::${cluster}::tsa_host"), + String $tsa_public_key = lookup("concourse::${cluster}::tsa_public_key"), + Optinal[String] $worker_public_key = undef, + Optinal[String] $worker_private_key = undef, + Boolean $manage_private_key = $worker_private_key == undef, + Boolean $export_public_key = true, + Optional[Array[String]] $tag = undef, + Optinal[String] $team = undef, + + String $healthcheck_bind_ip = '0.0.0.0', + Stdlib::Port $healthcheck_bind_port = 8888, + String $healthcheck_timeout = '5s', + + Hash[String, Any] $extra_env = {}, +) { + ensure_packages([ + 'concourse', + ]) + + if $manage_private_key { + exec { 'Concourse generate worker key': + command => ['concourse', 'generate-key', '-t', 'ssh', '-f', $worker_key_file], + creates => $worker_private_key_file, # and worker_key_file + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin',] + } + } else { + file { $worker_key_file: + content => $worker_public_key, + } + + file { $worker_private_key_file: + mode => '0600', + content => $worker_private_key, + } + } + + if $export_public_key { + @@concourse::worker_key { "${facts['trusted']['certname']} worker key": + content => $facts['concourse_worker_key'], + cluster => $cluster, + } + } + + systemd::unit_file { $service_unit: + ensure => $ensure, + soruce => "puppet:///modules/${module_name}/concourse-worker.service", + } ~> service { $service: + ensure => if $ensure == 'present' { 'running' } else { 'stopped' }, + enable => true, + } + + $env = { + 'CONCOURSE_WORK_DIR' => $work_dir, + 'CONCOURSE_TSA_HOST' => $tsa_host, + 'CONCOURSE_TSA_PUBLIC_KEY' => $tsa_public_key, + 'CONCOURSE_TSA_WORKER_PRIVATE_KEY' => $worker_private_key_file, + 'CONCOURSE_TAG' => $tag, + 'CONCOURSE_TEAM' => $team, + 'HEALTHCHECK_BIND_IP' => $healthcheck_bind_ip, + 'HEALTHCHECK_BIND_PORT' => $healthcheck_bind_port, + 'HEALTHCHECK_TIMEOUT' => $healthcheck_timeout, + } + $extra_env + + + file { '/etc/conf.d/concourse-worker': + ensure => $ensure, + mode => '0600', + show_diff => false, + content => epp("${module_name}/env.epp", $env), + } +} diff --git a/manifests/worker_key.pp b/manifests/worker_key.pp new file mode 100644 index 0000000..320bba1 --- /dev/null +++ b/manifests/worker_key.pp @@ -0,0 +1,10 @@ +# @api private +define concourse::worker_key ( + String $content, + String $cluster, +) { + concat::fragment { $name: + content => $content, + target => "authorized_worker_keys - ${cluster}", + } +} diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..7e74703 --- /dev/null +++ b/metadata.json @@ -0,0 +1,44 @@ +{ + "name": "HugoNikanor-concourse", + "version": "0.1.0", + "author": "Hugo Hörnquist", + "license": "Apache-2.0", + "summary": "Configures the Concourse CI", + "source": "https://git.hornquist.se/puppet/concourse", + "dependencies": [ + { + "name": "puppetlabs/stdlib", + "version_requirement": ">= 6.0.0 < 9.0.0" + }, + { + "name": "puppet/systemd", + "version_requirement": ">= 3.5.0 < 4.0.0" + }, + { + "name": "puppet/nginx", + "version_requirement": >= 3.3.0 < 4.0.0" + }, + { + "name": "puppetlabs/postgresql", + "version_requirement": ">= 7.5.0 < 8.0.0" + }, + { + "name": "puppetlabs/concat", + "version_requirement": ">= 8.0.0 < 9.0.0" + } + ], + "requirements": [ + { + "name": "puppet", + "version_requirement": ">= 5.5.10 < 8.0.0" + } + ], + "operatingsystem_support": [ + { + "operatingsystem": "Archlinux" + } + ], + "pdk-version": "2.5.0", + "template-url": "pdk-default#2.5.0", + "template-ref": "tags/2.5.0-0-g369d483" +} diff --git a/templates/env.epp b/templates/env.epp new file mode 100644 index 0000000..8648088 --- /dev/null +++ b/templates/env.epp @@ -0,0 +1,9 @@ +<%- | Hash[String, Any] $entries + | -%> +# Environment file for concourse.service +# File managed by Puppet. Local changes WILL be overwritten. +<%- $entries.each |$key, $value| { -%> +<%- unless $value == undef { -%> +<%= $key %>=<%= $value =%> +<%- } -%> +<%- } -%> |