From d2c1ac055cde364db897f2fb713acf4e42d2d5d2 Mon Sep 17 00:00:00 2001 From: Jack Peterson Date: Fri, 26 Jul 2024 13:09:03 -0700 Subject: [PATCH 01/22] update dependencies for compatibility expand range of stdlib to support up through version 9. Add additional supported OS versions (I'm testing on ubuntu 24.04) w/ Puppet 8. --- metadata.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/metadata.json b/metadata.json index 72f3911..7db2d40 100644 --- a/metadata.json +++ b/metadata.json @@ -11,7 +11,7 @@ "dependencies": [ { "name": "puppetlabs-stdlib", - "version_requirement": ">=3.2.0 <7.0.0" + "version_requirement": ">=3.2.0 <10.0.0" } ], "operatingsystem_support": [ @@ -32,18 +32,21 @@ { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ - "14.04" + "14.04", + "20.04", + "22.04", + "24.04" ] } ], "requirements": [ { "name": "pe", - "version_requirement": ">= 3.2.0 < 2015.4.0" + "version_requirement": ">= 3.2.0 < 2023.7.0" }, { "name": "puppet", - "version_requirement": ">= 3.4.0 < 5.0.0" + "version_requirement": ">= 3.4.0 < 9.0.0" } ] } From 926335bda93c7c1a873a34cf7c1145ed22475d8e Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 29 Jul 2024 15:50:32 -0700 Subject: [PATCH 02/22] update facts from global ::osfamily to $facts['os']['name'] --- manifests/config.pp | 2 +- manifests/install.pp | 2 +- manifests/params.pp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifests/config.pp b/manifests/config.pp index 2af0356..d164bf6 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -4,7 +4,7 @@ # class codedeploy::config { - case $::osfamily { + case $facts['os']['name'] { 'RedHat', 'Amazon': { file { $::codedeploy::config_location: ensure => file, diff --git a/manifests/install.pp b/manifests/install.pp index 9c2821d..e05e1f0 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -4,7 +4,7 @@ # class codedeploy::install { - case $::osfamily { + case $facts['os']['name'] { 'RedHat', 'Amazon': { package { $::codedeploy::package_name: ensure => present, diff --git a/manifests/params.pp b/manifests/params.pp index 4f0dc21..15df6da 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -4,7 +4,7 @@ # It sets variables according to platform. # class codedeploy::params { - case $::osfamily { + case $facts['os']['name'] { 'Debian': { $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent_all.deb' $package_name = 'codedeploy-agent' From 527bf8ae0414cc476dfdbc5623224caeb6d6f990 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 29 Jul 2024 16:42:32 -0700 Subject: [PATCH 03/22] update facts from global ::osfamily to $facts['os']['name'] --- manifests/params.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/params.pp b/manifests/params.pp index 15df6da..244aae4 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -39,7 +39,7 @@ $verbose = true } default: { - fail("${::operatingsystem} not supported") + fail("${facts['os']['name']} not supported") } } From a717f5ad621f5f1e0c2bd06428f109d9773a1ecd Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 29 Jul 2024 16:59:25 -0700 Subject: [PATCH 04/22] group debian and ubuntu together --- manifests/params.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/params.pp b/manifests/params.pp index 244aae4..d937a0d 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -5,7 +5,7 @@ # class codedeploy::params { case $facts['os']['name'] { - 'Debian': { + 'Debian', 'Ubuntu': { $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent_all.deb' $package_name = 'codedeploy-agent' $service_name = 'codedeploy-agent' From 89a43804a97b75c8c90a20720e4d17673eadf141 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 29 Jul 2024 17:15:00 -0700 Subject: [PATCH 05/22] get rid of proxy_uri --- manifests/init.pp | 1 - templates/codedeployagent.yml.erb | 1 - 2 files changed, 2 deletions(-) diff --git a/manifests/init.pp b/manifests/init.pp index 2ab1c58..54b197b 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -19,7 +19,6 @@ $root_dir = $::codedeploy::params::root_dir, $verbose = $::codedeploy::params::verbose, $wait_between_runs = $::codedeploy::params::wait_between_runs, - $proxy_uri = $::codedeploy::params::proxy_uri, $max_revisions = $::codedeploy::params::max_revisions, ) inherits ::codedeploy::params { diff --git a/templates/codedeployagent.yml.erb b/templates/codedeployagent.yml.erb index f4365c7..d3bcd72 100644 --- a/templates/codedeployagent.yml.erb +++ b/templates/codedeployagent.yml.erb @@ -11,5 +11,4 @@ :root_dir: <%= scope['codedeploy::root_dir'] %> :verbose: <%= scope['codedeploy::verbose'] %> :wait_between_runs: <%= scope['codedeploy::wait_between_runs'] %> -:proxy_uri: <%= scope['codedeploy::proxy_uri'] %> :max_revisions: <%= scope['codedeploy::max_revisions'] %> From 4b8a0796221049e18dfda812db37f2942dbf60ca Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 29 Jul 2024 17:26:12 -0700 Subject: [PATCH 06/22] fix install script --- manifests/install.pp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manifests/install.pp b/manifests/install.pp index e05e1f0..7e204aa 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -18,8 +18,8 @@ source => $::codedeploy::package_url, } } - 'Debian': { - if ! defined(Package['awscli']) { + 'Debian', 'Ubuntu': { + if !defined(Package['awscli']) { package { 'awscli': ensure => present, } @@ -45,7 +45,7 @@ } } default: { - fail("${::operatingsystem} not supported") + fail("${facts['os']['name']} not supported") } } } From afb0332b4f7e4ae2fc64ac723f3b34b7af26d6e2 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 5 Aug 2024 11:23:28 -0700 Subject: [PATCH 07/22] remove package dependency and instead rely on ```File['/usr/local/bin/aws']``` being defined. --- README.markdown | 5 +++++ manifests/install.pp | 7 +------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.markdown b/README.markdown index bb7498c..7c82271 100644 --- a/README.markdown +++ b/README.markdown @@ -15,6 +15,11 @@ This module installs and enables the AWS CodeDeploy agent. + +## IMPORTANT + +You must manually define `File['/usr/local/bin/aws']` in your upstream project somewhere. + ## Module Description The AWS Codedeploy allows you to automatically deploy applications to AWS instances from S3 or GitHub. This module installs any required packages followed by the CodeDeploy agent. It then enables the codedeploy-agent service and ensures that it is running. diff --git a/manifests/install.pp b/manifests/install.pp index 7e204aa..5a49ead 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -19,16 +19,11 @@ } } 'Debian', 'Ubuntu': { - if !defined(Package['awscli']) { - package { 'awscli': - ensure => present, - } - } exec { 'download_codedeploy_installer': command => '/usr/bin/aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1', cwd => '/tmp', creates => '/tmp/install', - require => Package['awscli'], + require => File['/usr/local/bin/aws'], } file { '/tmp/install': ensure => file, From 231487a025fa277e2097c09ba8f7d4bc1b891d20 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Mon, 5 Aug 2024 14:14:08 -0700 Subject: [PATCH 08/22] support /usr/bin/aws and /usr/local/bin/aws possible executable paths --- manifests/install.pp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manifests/install.pp b/manifests/install.pp index 5a49ead..a36363c 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -20,9 +20,10 @@ } 'Debian', 'Ubuntu': { exec { 'download_codedeploy_installer': - command => '/usr/bin/aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1', + command => 'aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1', cwd => '/tmp', creates => '/tmp/install', + path => ['/usr/bin', '/usr/local/bin'], require => File['/usr/local/bin/aws'], } file { '/tmp/install': From a3a8862da70ec3cffe4de70f29ddd2d7e82e93d1 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 12:00:51 -0700 Subject: [PATCH 09/22] CodeDeploy agent doesn't install on ubuntu 26.04 by default because of ruby 3.2 assumption. ubuntu 26.04 ships with Ruby 3.3. The workaround is to not use the default AWS installer script and just go straight to the referenced .deb or .rpm files in this module and not fuss with that junk. IDK why they made that decision -- it would've made more sense to just link the OS-dependent installers directly in docs. --- .gitignore | 1 + manifests/init.pp | 2 +- manifests/install.pp | 35 ++++++++++++++++------------------- manifests/params.pp | 4 +--- metadata.json | 27 +++++++++++++-------------- 5 files changed, 32 insertions(+), 37 deletions(-) diff --git a/.gitignore b/.gitignore index 6dfe023..1364d80 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ /log .yardoc coverage +/.idea diff --git a/manifests/init.pp b/manifests/init.pp index 54b197b..b4fb55c 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -8,7 +8,6 @@ # Explanation of what this parameter affects and what it defaults to. # class codedeploy ( - $package_url = $::codedeploy::params::package_url, $package_name = $::codedeploy::params::package_name, $service_name = $::codedeploy::params::service_name, $config_location = $::codedeploy::params::config_location, @@ -20,6 +19,7 @@ $verbose = $::codedeploy::params::verbose, $wait_between_runs = $::codedeploy::params::wait_between_runs, $max_revisions = $::codedeploy::params::max_revisions, + $aws_region = $::codedeploy::params::aws_region, ) inherits ::codedeploy::params { # validate parameters here diff --git a/manifests/install.pp b/manifests/install.pp index a36363c..b918706 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -6,38 +6,35 @@ case $facts['os']['name'] { 'RedHat', 'Amazon': { + $region = $::codedeploy::aws_region package { $::codedeploy::package_name: ensure => present, provider => 'rpm', - source => $::codedeploy::package_url, + source => "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent.noarch.rpm", } } 'windows': { + $region = $::codedeploy::aws_region package { $::codedeploy::package_name: ensure => present, - source => $::codedeploy::package_url, + source => "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent.msi", } } 'Debian', 'Ubuntu': { - exec { 'download_codedeploy_installer': - command => 'aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1', - cwd => '/tmp', - creates => '/tmp/install', - path => ['/usr/bin', '/usr/local/bin'], - require => File['/usr/local/bin/aws'], - } - file { '/tmp/install': - ensure => file, - owner => 'root', - group => 'root', - mode => '0740', - subscribe => Exec['download_codedeploy_installer'], - notify => Exec['install_codedeploy_agent'], + ensure_packages(['ruby-full'], { 'ensure' => 'present' }) + + $region = $::codedeploy::aws_region + $deb_url = "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent_all.deb" + + archive { '/tmp/codedeploy-agent.deb': + source => $deb_url, + creates => '/tmp/codedeploy-agent.deb', } exec { 'install_codedeploy_agent': - command => '/tmp/install auto', - cwd => '/tmp', - refreshonly => true, + command => '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', + unless => '/usr/bin/dpkg -s codedeploy-agent', + require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], + path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } } default: { diff --git a/manifests/params.pp b/manifests/params.pp index d937a0d..82cf0e5 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -6,7 +6,6 @@ class codedeploy::params { case $facts['os']['name'] { 'Debian', 'Ubuntu': { - $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent_all.deb' $package_name = 'codedeploy-agent' $service_name = 'codedeploy-agent' $config_location = '/etc/codedeploy-agent/conf/codedeployagent.yml' @@ -17,7 +16,6 @@ $verbose = false } 'RedHat', 'Amazon': { - $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent.noarch.rpm' $package_name = 'codedeploy-agent' $service_name = 'codedeploy-agent' $config_location = '/etc/codedeploy-agent/conf/codedeployagent.yml' @@ -28,7 +26,6 @@ $verbose = false } 'Windows': { - $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent.msi' $package_name = 'codedeployagent' $service_name = 'codedeployagent' $config_location = 'C:\ProgramData\Amazon\CodeDeploy\conf.yml' @@ -46,5 +43,6 @@ $log_aws_wire = false $wait_between_runs = 1 $max_revisions = 5 + $aws_region = 'us-west-1' } diff --git a/metadata.json b/metadata.json index 7db2d40..61e994e 100644 --- a/metadata.json +++ b/metadata.json @@ -11,42 +11,41 @@ "dependencies": [ { "name": "puppetlabs-stdlib", - "version_requirement": ">=3.2.0 <10.0.0" + "version_requirement": ">= 4.6.0 < 10.0.0" + }, + { + "name": "puppet-archive", + "version_requirement": ">= 4.0.0 < 8.0.0" } ], "operatingsystem_support": [ { "operatingsystem": "Debian", "operatingsystemrelease": [ - "6", - "7" + "12", + "13" ] }, { "operatingsystem": "RedHat", "operatingsystemrelease": [ - "6", - "7" + "8", + "9", + "10" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ - "14.04", - "20.04", - "22.04", - "24.04" + "24.04", + "26.04" ] } ], "requirements": [ - { - "name": "pe", - "version_requirement": ">= 3.2.0 < 2023.7.0" - }, { "name": "puppet", - "version_requirement": ">= 3.4.0 < 9.0.0" + "version_requirement": ">= 7.0.0 < 9.0.0" } ] } From 0e32bfdaf385de30739b04051491c409aa47c2d6 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 12:07:11 -0700 Subject: [PATCH 10/22] add github actions to validate. --- .github/workflows/test.yml | 31 ++++++++++++++++++ Dockerfile.test | 26 +++++++++++++++ Makefile | 6 ++++ README.markdown | 65 +++++++++++++++++++++++++++----------- 4 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 Dockerfile.test create mode 100644 Makefile diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..01ce4b8 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,31 @@ +name: Test CodeDeploy Module + +on: + push: + branches: [master, main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - base_image: ubuntu:24.04 + package_manager: apt + name: Ubuntu 24.04 + - base_image: ubuntu:26.04 + package_manager: apt + name: Ubuntu 26.04 + - base_image: amazonlinux:2023 + package_manager: yum + name: Amazon Linux 2023 + name: ${{ matrix.name }} + steps: + - uses: actions/checkout@v4 + - name: Build and test + run: | + docker build -f Dockerfile.test \ + --build-arg BASE_IMAGE=${{ matrix.base_image }} \ + --build-arg PACKAGE_MANAGER=${{ matrix.package_manager }} \ + -t puppet-codedeploy:test . diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000..5c40dbf --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,26 @@ +ARG BASE_IMAGE=ubuntu:24.04 +FROM ${BASE_IMAGE} + +ARG PACKAGE_MANAGER=apt +ENV DEBIAN_FRONTEND=noninteractive + +# Install puppet +RUN if [ "$PACKAGE_MANAGER" = "apt" ]; then \ + apt-get update && apt-get install -y puppet && apt-get clean; \ + else \ + rpm -Uvh https://yum.puppet.com/puppet8-release-el-9.noarch.rpm && \ + yum install -y puppet-agent procps && yum clean all; \ + fi + +ENV PATH="/opt/puppetlabs/bin:${PATH}" +RUN puppet module install puppet-archive --version 7.1.0 + +COPY . /etc/puppet/code/modules/codedeploy + +# Apply and verify the package installed (service may fail in Docker - that's OK) +RUN puppet apply -e "include codedeploy" --modulepath=/etc/puppet/code/modules || true +RUN if [ "$PACKAGE_MANAGER" = "apt" ]; then \ + dpkg -s codedeploy-agent; \ + else \ + rpm -q codedeploy-agent; \ + fi diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d9687a7 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +.PHONY: test + +test: + docker build -f Dockerfile.test --build-arg BASE_IMAGE=ubuntu:24.04 --build-arg PACKAGE_MANAGER=apt -t puppet-codedeploy:ubuntu-24.04 . + docker build -f Dockerfile.test --build-arg BASE_IMAGE=ubuntu:26.04 --build-arg PACKAGE_MANAGER=apt -t puppet-codedeploy:ubuntu-26.04 . + docker build -f Dockerfile.test --build-arg BASE_IMAGE=amazonlinux:2023 --build-arg PACKAGE_MANAGER=yum -t puppet-codedeploy:al2023 . diff --git a/README.markdown b/README.markdown index 7c82271..128c0f2 100644 --- a/README.markdown +++ b/README.markdown @@ -1,28 +1,20 @@ # AWS CodeDeploy Puppet Module -[![Build Status](https://travis-ci.org/walkamongus/puppet-codedeploy.svg?branch=master)](https://travis-ci.org/walkamongus/puppet-codedeploy) +[![Test](https://github.com/walkamongus/puppet-codedeploy/actions/workflows/test.yml/badge.svg)](https://github.com/walkamongus/puppet-codedeploy/actions/workflows/test.yml) -#### Table of Contents +## Build Status -1. [Overview](#overview) -2. [Module Description - What the module does and why it is useful](#module-description) -3. [Setup - The basics of getting started with codedeploy](#setup) - * [What codedeploy affects](#what-codedeploy-affects) -4. [Usage - Configuration options and additional functionality](#usage) -5. [Limitations - OS compatibility, etc.](#limitations) +- [x] Ubuntu 24.04 +- [x] Ubuntu 26.04 +- [x] Amazon Linux 2023 ## Overview This module installs and enables the AWS CodeDeploy agent. - -## IMPORTANT - -You must manually define `File['/usr/local/bin/aws']` in your upstream project somewhere. - ## Module Description -The AWS Codedeploy allows you to automatically deploy applications to AWS instances from S3 or GitHub. This module installs any required packages followed by the CodeDeploy agent. It then enables the codedeploy-agent service and ensures that it is running. +The AWS CodeDeploy service allows you to automatically deploy applications to AWS instances from S3 or GitHub. This module downloads and installs the CodeDeploy agent package directly from the regional S3 bucket, configures the agent, and ensures the service is running. ## Setup @@ -30,16 +22,51 @@ The AWS Codedeploy allows you to automatically deploy applications to AWS instan * Packages * codedeploy-agent - * awscli (Debian) + * ruby-full (Debian/Ubuntu) * Services * codedeploy-agent daemon +### Dependencies + +* [puppetlabs/stdlib](https://forge.puppet.com/modules/puppetlabs/stdlib) +* [puppet/archive](https://forge.puppet.com/modules/puppet/archive) + ## Usage -The codedeploy-agent package requires a version of Ruby > 2.0.x to be installed under /usr/bin/ruby. This dependency must be satisfied prior to installing the codedeploy-agent package. The recommended way of doing this is via the [puppetlabs/ruby](https://forge.puppetlabs.com/puppetlabs/ruby) module. +```puppet +include codedeploy +``` + +To specify a different AWS region: + +```puppet +class { 'codedeploy': + aws_region => 'eu-west-1', +} +``` + +## Parameters + +| Parameter | Default | Description | +|-----------|---------|-------------| +| `aws_region` | `us-west-1` | AWS region for the CodeDeploy S3 bucket | +| `service_name` | `codedeploy-agent` | Name of the service | +| `package_name` | `codedeploy-agent` | Name of the package | + +## Limitations + +Supported operating systems: + +* Ubuntu 24.04, 26.04 +* Debian 12, 13 +* Red Hat / Amazon Linux 8, 9, 10 + +Requires Puppet 7 or 8. -Install the AWS CodeDeploy agent and ensure the agent is running +## Testing - include '::ruby' - include '::codedeploy' +```bash +make test +``` +Runs the module in Docker containers for each supported platform and verifies the package installs successfully. From 3d04f7a61800ec5fe04660d8cedbfdb3c32019b1 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 12:31:32 -0700 Subject: [PATCH 11/22] align conventions with voxpupuli team's approach to puppet module linting, testing, etc. --- .fixtures.yml | 9 ++- .github/workflows/test.yml | 21 ++++- .rspec | 2 +- .travis.yml | 24 ------ Dockerfile.test | 11 ++- Gemfile | 26 +------ Guardfile | 5 -- README.markdown | 4 +- Rakefile | 55 +------------ manifests/config.pp | 15 ++-- manifests/init.pp | 58 +++++++------- manifests/install.pp | 19 +---- manifests/params.pp | 51 +++++------- manifests/service.pp | 10 +-- metadata.json | 8 +- spec/acceptance/class_spec.rb | 26 ------- spec/acceptance/nodesets/centos-511-x64.yml | 12 --- spec/acceptance/nodesets/centos-66-x64.yml | 11 --- spec/acceptance/nodesets/centos-7-x64.yml | 12 --- spec/acceptance/nodesets/debian-609-x64.yml | 12 --- spec/acceptance/nodesets/debian-76-x64.yml | 12 --- spec/acceptance/nodesets/default.yml | 12 --- spec/acceptance/nodesets/fedora-20-x64.yml | 12 --- .../nodesets/ubuntu-server-1204-x64.yml | 12 --- .../nodesets/ubuntu-server-1404-x64.yml | 12 --- spec/classes/coverage_spec.rb | 1 - spec/classes/init_spec.rb | 61 +++++++++------ spec/classes/install_spec.rb | 78 +++++++++++-------- spec/classes/service_spec.rb | 30 +++---- spec/spec_helper.rb | 4 +- spec/spec_helper_acceptance.rb | 30 ------- tests/init.pp | 12 --- 32 files changed, 205 insertions(+), 462 deletions(-) delete mode 100644 .travis.yml delete mode 100644 Guardfile delete mode 100644 spec/acceptance/class_spec.rb delete mode 100644 spec/acceptance/nodesets/centos-511-x64.yml delete mode 100644 spec/acceptance/nodesets/centos-66-x64.yml delete mode 100644 spec/acceptance/nodesets/centos-7-x64.yml delete mode 100644 spec/acceptance/nodesets/debian-609-x64.yml delete mode 100644 spec/acceptance/nodesets/debian-76-x64.yml delete mode 100644 spec/acceptance/nodesets/default.yml delete mode 100644 spec/acceptance/nodesets/fedora-20-x64.yml delete mode 100644 spec/acceptance/nodesets/ubuntu-server-1204-x64.yml delete mode 100644 spec/acceptance/nodesets/ubuntu-server-1404-x64.yml delete mode 100644 spec/classes/coverage_spec.rb delete mode 100644 spec/spec_helper_acceptance.rb delete mode 100644 tests/init.pp diff --git a/.fixtures.yml b/.fixtures.yml index ba1e662..f8f5552 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -1,5 +1,8 @@ fixtures: repositories: - stdlib: "https://github.com/puppetlabs/puppetlabs-stdlib.git" - symlinks: - codedeploy: "#{source_dir}" + stdlib: + repo: "https://github.com/puppetlabs/puppetlabs-stdlib.git" + ref: "v9.7.0" + archive: + repo: "https://github.com/voxpupuli/puppet-archive.git" + ref: "v7.1.0" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01ce4b8..ebf1100 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,8 +6,25 @@ on: pull_request: jobs: - test: + lint: runs-on: ubuntu-latest + name: Lint & Unit Tests + steps: + - uses: actions/checkout@v5 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + - name: Run lint + run: bundle exec rake lint + - name: Run spec + run: bundle exec rake spec + - name: Validate metadata + run: bundle exec metadata-json-lint metadata.json + + integration: + runs-on: ubuntu-latest + needs: lint strategy: matrix: include: @@ -22,7 +39,7 @@ jobs: name: Amazon Linux 2023 name: ${{ matrix.name }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Build and test run: | docker build -f Dockerfile.test \ diff --git a/.rspec b/.rspec index 8c18f1a..16f9cdb 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ ---format documentation --color +--format documentation diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0090db9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ ---- -language: ruby -bundler_args: --without development -before_install: - - rm Gemfile.lock || true - - gem update bundler -rvm: - - 1.9.3 - - 2.0.0 - - 2.1.0 -script: bundle exec rake test -env: - - PUPPET_GEM_VERSION="~> 3.6.0" STRICT_VARIABLES=yes - - PUPPET_GEM_VERSION="~> 3.7.0" STRICT_VARIABLES=yes - - PUPPET_GEM_VERSION="~> 3.7.0" STRICT_VARIABLES=yes FUTURE_PARSER=yes - - PUPPET_GEM_VERSION="~> 3.8.0" STRICT_VARIABLES=yes FUTURE_PARSER=yes - - PUPPET_GEM_VERSION="~> 4.0.0" STRICT_VARIABLES=yes - - PUPPET_GEM_VERSION="~> 4.1.0" STRICT_VARIABLES=yes - - PUPPET_GEM_VERSION="~> 4.2.0" STRICT_VARIABLES=yes - - PUPPET_GEM_VERSION="~> 4.3.0" STRICT_VARIABLES=yes -matrix: - exclude: - - rvm: 2.1.0 - env: PUPPET_VERSION="~> 3.4.0" diff --git a/Dockerfile.test b/Dockerfile.test index 5c40dbf..c6dc8b0 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -17,10 +17,17 @@ RUN puppet module install puppet-archive --version 7.1.0 COPY . /etc/puppet/code/modules/codedeploy -# Apply and verify the package installed (service may fail in Docker - that's OK) +# Apply module (service may fail in Docker - that's expected) RUN puppet apply -e "include codedeploy" --modulepath=/etc/puppet/code/modules || true + +# Validate package is installed RUN if [ "$PACKAGE_MANAGER" = "apt" ]; then \ - dpkg -s codedeploy-agent; \ + dpkg -s codedeploy-agent | grep "Status: install ok installed"; \ else \ rpm -q codedeploy-agent; \ fi + +# Validate expected binaries exist +RUN test -x /opt/codedeploy-agent/bin/codedeploy-agent && \ + test -x /opt/codedeploy-agent/bin/codedeploy-local && \ + test -x /opt/codedeploy-agent/bin/install diff --git a/Gemfile b/Gemfile index 68a9b76..edb7c64 100644 --- a/Gemfile +++ b/Gemfile @@ -1,24 +1,6 @@ source "https://rubygems.org" -group :test do - gem "rake" - gem "puppet", ENV['PUPPET_VERSION'] || '~> 3.8.0' - gem "rspec", '< 3.2.0' - gem "rspec-puppet", :git => 'https://github.com/rodjek/rspec-puppet.git' - gem "puppetlabs_spec_helper" - gem "metadata-json-lint" - gem "rspec-puppet-facts" -end - -group :development do - gem "travis" - gem "travis-lint" - gem "vagrant-wrapper" - gem "puppet-blacksmith" - gem "guard-rake" -end - -group :system_tests do - gem "beaker" - gem "beaker-rspec" -end +gem "puppet", ENV['PUPPET_VERSION'] || '~> 8.0' +gem "rake" +gem "voxpupuli-test", "~> 14.0" +gem "metadata-json-lint" diff --git a/Guardfile b/Guardfile deleted file mode 100644 index fd50602..0000000 --- a/Guardfile +++ /dev/null @@ -1,5 +0,0 @@ -notification :off - -guard 'rake', :task => 'test' do - watch(%r{^manifests\/(.+)\.pp$}) -end diff --git a/README.markdown b/README.markdown index 128c0f2..712ce32 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,6 @@ # AWS CodeDeploy Puppet Module -[![Test](https://github.com/walkamongus/puppet-codedeploy/actions/workflows/test.yml/badge.svg)](https://github.com/walkamongus/puppet-codedeploy/actions/workflows/test.yml) +[![Test](https://github.com/jackdpeterson/puppet-codedeploy/actions/workflows/test.yml/badge.svg)](https://github.com/jackdpeterson/puppet-codedeploy/actions/workflows/test.yml) ## Build Status @@ -61,7 +61,7 @@ Supported operating systems: * Debian 12, 13 * Red Hat / Amazon Linux 8, 9, 10 -Requires Puppet 7 or 8. +Requires Puppet 8. ## Testing diff --git a/Rakefile b/Rakefile index 1778d2a..8dbff16 100644 --- a/Rakefile +++ b/Rakefile @@ -1,56 +1,3 @@ -require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet/version' -require 'puppet/vendor/semantic/lib/semantic' unless Puppet.version.to_f < 3.6 -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' +require 'voxpupuli/test/rake' -# These gems aren't always present, for instance -# on Travis with --without development -begin - require 'puppet_blacksmith/rake_tasks' -rescue LoadError -end - -Rake::Task[:lint].clear - -PuppetLint.configuration.relative = true -PuppetLint.configuration.send("disable_80chars") -PuppetLint.configuration.log_format = "%{path}:%{linenumber}:%{check}:%{KIND}:%{message}" -PuppetLint.configuration.fail_on_warnings = true - -# Forsake support for Puppet 2.6.2 for the benefit of cleaner code. -# http://puppet-lint.com/checks/class_parameter_defaults/ -PuppetLint.configuration.send('disable_class_parameter_defaults') -# http://puppet-lint.com/checks/class_inherits_from_params_class/ PuppetLint.configuration.send('disable_class_inherits_from_params_class') - -exclude_paths = [ - "bundle/**/*", - "pkg/**/*", - "vendor/**/*", - "spec/**/*", -] -PuppetLint.configuration.ignore_paths = exclude_paths -PuppetSyntax.exclude_paths = exclude_paths - -desc "Run acceptance tests" -RSpec::Core::RakeTask.new(:acceptance) do |t| - t.pattern = 'spec/acceptance' -end - -desc "Populate CONTRIBUTORS file" -task :contributors do - system("git log --format='%aN' | sort -u > CONTRIBUTORS") -end - -task :metadata do - sh "metadata-json-lint metadata.json" -end - -desc "Run syntax, lint, and spec tests." -task :test => [ - :syntax, - :lint, - :spec, - :metadata, -] diff --git a/manifests/config.pp b/manifests/config.pp index d164bf6..ba9446d 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -1,20 +1,15 @@ -# == Class codedeploy::config -# -# This class is called from codedeploy. -# +# @summary Configures the CodeDeploy agent. class codedeploy::config { - case $facts['os']['name'] { 'RedHat', 'Amazon': { - file { $::codedeploy::config_location: + file { $codedeploy::config_location: ensure => file, content => template('codedeploy/codedeployagent.yml.erb'), mode => '0644', - owner => root, - group => root, + owner => 'root', + group => 'root', } } - default: { - } + default: {} } } diff --git a/manifests/init.pp b/manifests/init.pp index b4fb55c..14e6c10 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,31 +1,33 @@ -# == Class: codedeploy -# -# Full description of class codedeploy here. -# -# === Parameters -# -# [*sample_parameter*] -# Explanation of what this parameter affects and what it defaults to. +# @summary Installs and configures the AWS CodeDeploy agent. # +# @param package_name Name of the codedeploy-agent package. +# @param service_name Name of the codedeploy-agent service. +# @param config_location Path to the agent configuration file. +# @param log_aws_wire Enable AWS wire logging. +# @param log_dir Directory for agent logs. +# @param pid_dir Directory for agent PID files. +# @param program_name Program name for the agent. +# @param root_dir Root directory for deployments. +# @param verbose Enable verbose logging. +# @param wait_between_runs Seconds between agent polling runs. +# @param max_revisions Maximum number of deployment revisions to retain. +# @param aws_region AWS region for the CodeDeploy S3 bucket. class codedeploy ( - $package_name = $::codedeploy::params::package_name, - $service_name = $::codedeploy::params::service_name, - $config_location = $::codedeploy::params::config_location, - $log_aws_wire = $::codedeploy::params::log_aws_wire, - $log_dir = $::codedeploy::params::log_dir, - $pid_dir = $::codedeploy::params::pid_dir, - $program_name = $::codedeploy::params::program_name, - $root_dir = $::codedeploy::params::root_dir, - $verbose = $::codedeploy::params::verbose, - $wait_between_runs = $::codedeploy::params::wait_between_runs, - $max_revisions = $::codedeploy::params::max_revisions, - $aws_region = $::codedeploy::params::aws_region, -) inherits ::codedeploy::params { - - # validate parameters here - - class { '::codedeploy::install': } -> - class { '::codedeploy::config': } ~> - class { '::codedeploy::service': } -> - Class['::codedeploy'] + String $package_name = $codedeploy::params::package_name, + String $service_name = $codedeploy::params::service_name, + String $config_location = $codedeploy::params::config_location, + Boolean $log_aws_wire = $codedeploy::params::log_aws_wire, + String $log_dir = $codedeploy::params::log_dir, + Optional[String] $pid_dir = $codedeploy::params::pid_dir, + Optional[String] $program_name = $codedeploy::params::program_name, + String $root_dir = $codedeploy::params::root_dir, + Boolean $verbose = $codedeploy::params::verbose, + Integer $wait_between_runs = $codedeploy::params::wait_between_runs, + Integer $max_revisions = $codedeploy::params::max_revisions, + String $aws_region = $codedeploy::params::aws_region, +) inherits codedeploy::params { + class { 'codedeploy::install': } + -> class { 'codedeploy::config': } + ~> class { 'codedeploy::service': } + -> Class['codedeploy'] } diff --git a/manifests/install.pp b/manifests/install.pp index b918706..99b317d 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -1,29 +1,18 @@ -# == Class codedeploy::install -# -# This class is called from codedeploy for install. -# +# @summary Installs the AWS CodeDeploy agent. class codedeploy::install { - case $facts['os']['name'] { 'RedHat', 'Amazon': { - $region = $::codedeploy::aws_region - package { $::codedeploy::package_name: + $region = $codedeploy::aws_region + package { $codedeploy::package_name: ensure => present, provider => 'rpm', source => "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent.noarch.rpm", } } - 'windows': { - $region = $::codedeploy::aws_region - package { $::codedeploy::package_name: - ensure => present, - source => "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent.msi", - } - } 'Debian', 'Ubuntu': { ensure_packages(['ruby-full'], { 'ensure' => 'present' }) - $region = $::codedeploy::aws_region + $region = $codedeploy::aws_region $deb_url = "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent_all.deb" archive { '/tmp/codedeploy-agent.deb': diff --git a/manifests/params.pp b/manifests/params.pp index 82cf0e5..956e87d 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,48 +1,33 @@ -# == Class codedeploy::params -# -# This class is meant to be called from codedeploy. -# It sets variables according to platform. -# +# @summary Default parameters for the CodeDeploy module. class codedeploy::params { case $facts['os']['name'] { 'Debian', 'Ubuntu': { - $package_name = 'codedeploy-agent' - $service_name = 'codedeploy-agent' + $package_name = 'codedeploy-agent' + $service_name = 'codedeploy-agent' $config_location = '/etc/codedeploy-agent/conf/codedeployagent.yml' - $log_dir = '/var/log/aws/codedeploy-agent/' - $pid_dir = '/opt/codedeploy-agent/state/.pid/' - $program_name = 'codedeploy-agent' - $root_dir = '/opt/codedeploy-agent/deployment-root' - $verbose = false + $log_dir = '/var/log/aws/codedeploy-agent/' + $pid_dir = '/opt/codedeploy-agent/state/.pid/' + $program_name = 'codedeploy-agent' + $root_dir = '/opt/codedeploy-agent/deployment-root' + $verbose = false } 'RedHat', 'Amazon': { - $package_name = 'codedeploy-agent' - $service_name = 'codedeploy-agent' + $package_name = 'codedeploy-agent' + $service_name = 'codedeploy-agent' $config_location = '/etc/codedeploy-agent/conf/codedeployagent.yml' - $log_dir = '/var/log/aws/codedeploy-agent/' - $pid_dir = '/opt/codedeploy-agent/state/.pid/' - $program_name = 'codedeploy-agent' - $root_dir = '/opt/codedeploy-agent/deployment-root' - $verbose = false - } - 'Windows': { - $package_name = 'codedeployagent' - $service_name = 'codedeployagent' - $config_location = 'C:\ProgramData\Amazon\CodeDeploy\conf.yml' - $log_dir = 'C:\ProgramData\Amazon\CodeDeploy\log' - $pid_dir = undef - $program_name = undef - $root_dir = 'C:\ProgramData\Amazon\CodeDeploy' - $verbose = true + $log_dir = '/var/log/aws/codedeploy-agent/' + $pid_dir = '/opt/codedeploy-agent/state/.pid/' + $program_name = 'codedeploy-agent' + $root_dir = '/opt/codedeploy-agent/deployment-root' + $verbose = false } default: { fail("${facts['os']['name']} not supported") } } - $log_aws_wire = false + $log_aws_wire = false $wait_between_runs = 1 - $max_revisions = 5 - $aws_region = 'us-west-1' - + $max_revisions = 5 + $aws_region = 'us-west-1' } diff --git a/manifests/service.pp b/manifests/service.pp index 4d45d76..ebb052d 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -1,15 +1,9 @@ -# == Class codedeploy::service -# -# This class is meant to be called from codedeploy. -# It ensure the service is running. -# +# @summary Ensures the CodeDeploy agent service is running. class codedeploy::service { - - service { $::codedeploy::service_name: + service { $codedeploy::service_name: ensure => running, enable => true, hasstatus => true, hasrestart => true, } - } diff --git a/metadata.json b/metadata.json index 61e994e..d695d2c 100644 --- a/metadata.json +++ b/metadata.json @@ -4,9 +4,9 @@ "author": "Chadwick Banning", "summary": "Puppet module to manage the AWS CodeDeploy agent", "license": "Apache-2.0", - "source": "git@github.com:walkamongus/puppet-codedeploy.git", - "project_page": "https://github.com/walkamongus/puppet-codedeploy/", - "issues_url": "https://github.com/walkamongus/puppet-codedeploy/issues", + "source": "git@github.com:jackdpeterson/puppet-codedeploy.git", + "project_page": "https://github.com/jackdpeterson/puppet-codedeploy/", + "issues_url": "https://github.com/jackdpeterson/puppet-codedeploy/issues", "tags": [ "codedeploy", "aws" ], "dependencies": [ { @@ -45,7 +45,7 @@ "requirements": [ { "name": "puppet", - "version_requirement": ">= 7.0.0 < 9.0.0" + "version_requirement": ">= 8.0.0 < 9.0.0" } ] } diff --git a/spec/acceptance/class_spec.rb b/spec/acceptance/class_spec.rb deleted file mode 100644 index 55543b6..0000000 --- a/spec/acceptance/class_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper_acceptance' - -describe 'codedeploy class' do - - context 'default parameters' do - # Using puppet_apply as a helper - it 'should work idempotently with no errors' do - pp = <<-EOS - class { 'codedeploy': } - EOS - - # Run it twice and test for idempotency - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) - end - - describe package('codedeploy') do - it { is_expected.to be_installed } - end - - describe service('codedeploy') do - it { is_expected.to be_enabled } - it { is_expected.to be_running } - end - end -end diff --git a/spec/acceptance/nodesets/centos-511-x64.yml b/spec/acceptance/nodesets/centos-511-x64.yml deleted file mode 100644 index 155926d..0000000 --- a/spec/acceptance/nodesets/centos-511-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-511-x64: - roles: - - master - platform: el-5-x86_64 - box: puppetlabs/centos-5.11-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-5.11-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/centos-66-x64.yml b/spec/acceptance/nodesets/centos-66-x64.yml deleted file mode 100644 index 07843d5..0000000 --- a/spec/acceptance/nodesets/centos-66-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - centos-66-x64: - roles: - - master - platform: el-6-x86_64 - box: puppetlabs/centos-6.6-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/centos-6.6-64-nocm - hypervisor: vagrant -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/centos-7-x64.yml b/spec/acceptance/nodesets/centos-7-x64.yml deleted file mode 100644 index 8e73537..0000000 --- a/spec/acceptance/nodesets/centos-7-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-7-x64: - roles: - - master - platform: el-7-x86_64 - box: chef/centos-7.0 - box_url: https://vagrantcloud.com/chef/boxes/centos-7.0 - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/debian-609-x64.yml b/spec/acceptance/nodesets/debian-609-x64.yml deleted file mode 100644 index e2451ea..0000000 --- a/spec/acceptance/nodesets/debian-609-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - debian-609-x64: - roles: - - master - platform: debian-6-amd64 - box: puppetlabs/debian-6.0.9-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/debian-6.0.9-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/debian-76-x64.yml b/spec/acceptance/nodesets/debian-76-x64.yml deleted file mode 100644 index 683e635..0000000 --- a/spec/acceptance/nodesets/debian-76-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - debian-76-x64: - roles: - - master - platform: debian-7-amd64 - box: puppetlabs/debian-7.6-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/debian-7.6-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml deleted file mode 100644 index 3f2dcaa..0000000 --- a/spec/acceptance/nodesets/default.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - ubuntu-server-1204-x64: - roles: - - master - platform: ubuntu-1204-amd64 - box: puppetlabs/ubuntu-12.04-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-12.04-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/fedora-20-x64.yml b/spec/acceptance/nodesets/fedora-20-x64.yml deleted file mode 100644 index 138341f..0000000 --- a/spec/acceptance/nodesets/fedora-20-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - fedora-20-x64: - roles: - - master - platform: el-7-x86_64 - box: chef/fedora-20 - box_url: https://vagrantcloud.com/chef/boxes/fedora-20 - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1204-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1204-x64.yml deleted file mode 100644 index 3f2dcaa..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-1204-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - ubuntu-server-1204-x64: - roles: - - master - platform: ubuntu-1204-amd64 - box: puppetlabs/ubuntu-12.04-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-12.04-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml deleted file mode 100644 index 4e33625..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - ubuntu-server-1404-x64: - roles: - - master - platform: ubuntu-1404-amd64 - box: puppetlabs/ubuntu-14.04-64-nocm - box_url: https://vagrantcloud.com/puppetlabs/boxes/ubuntu-14.04-64-nocm - hypervisor: vagrant - -CONFIG: - log_level: verbose - type: foss diff --git a/spec/classes/coverage_spec.rb b/spec/classes/coverage_spec.rb deleted file mode 100644 index 12513b8..0000000 --- a/spec/classes/coverage_spec.rb +++ /dev/null @@ -1 +0,0 @@ -at_exit { RSpec::Puppet::Coverage.report! } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index bb5902d..3a7909d 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,33 +1,48 @@ require 'spec_helper' describe 'codedeploy' do - context 'supported operating systems' do - on_supported_os.each do |os, facts| - context "on #{os}" do - let(:facts) do - facts - end - - context "codedeploy class without any parameters" do - let(:params) {{ }} - - it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_class('codedeploy::params') } - it { is_expected.to contain_class('codedeploy::install').that_comes_before('codedeploy::service') } - it { is_expected.to contain_class('codedeploy::service').that_requires('codedeploy::install') } - end - end + context "on Ubuntu" do + let(:facts) do + { + os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + } end + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_class('codedeploy::params') } + it { is_expected.to contain_class('codedeploy::install').that_comes_before('Class[codedeploy::config]') } + it { is_expected.to contain_class('codedeploy::config').that_notifies('Class[codedeploy::service]') } + it { is_expected.to contain_class('codedeploy::service') } end - context 'unsupported operating system' do - describe 'codedeploy class without any parameters on Solaris/Nexenta' do - let(:facts) {{ - :osfamily => 'Solaris', - :operatingsystem => 'Nexenta', - }} + context "on RedHat" do + let(:facts) do + { + os: { 'name' => 'RedHat', 'family' => 'RedHat' }, + } + end - it { expect { is_expected.to contain_package('codedeploy') }.to raise_error(Puppet::Error, /Nexenta not supported/) } + it { is_expected.to compile.with_all_deps } + end + + context "with custom parameters" do + let(:facts) do + { + os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + } end + let(:params) { { aws_region: 'ap-southeast-1' } } + + it { is_expected.to compile.with_all_deps } + end + + context "unsupported OS" do + let(:facts) do + { + os: { 'name' => 'Solaris', 'family' => 'Solaris' }, + } + end + + it { is_expected.to compile.and_raise_error(%r{Solaris not supported}) } end end diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 794905a..76e5290 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -1,56 +1,70 @@ require 'spec_helper' -describe 'codedeploy' do - context "on redhat-x86_64" do +describe 'codedeploy::install' do + context "on RedHat" do let(:facts) do { - :osfamily => 'RedHat', - :operatingsystem => 'RedHat', + os: { 'name' => 'RedHat', 'family' => 'RedHat' }, } end + let(:pre_condition) { 'include codedeploy' } - context "codedeploy class without any parameters" do - let(:params) {{ }} - - it { is_expected.to compile.with_all_deps } - - it { is_expected.to contain_package('codedeploy-agent').with_ensure('present') } - end + it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_package('codedeploy-agent').with( + ensure: 'present', + provider: 'rpm', + source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent.noarch.rpm', + ) + } end - context "on windows-x86_64" do + + context "on Ubuntu" do let(:facts) do { - :osfamily => 'Windows', - :operatingsystem => 'Windows', + os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, } end + let(:pre_condition) { 'include codedeploy' } - context "codedeploy class without any parameters" do - let(:params) {{ }} - - it { is_expected.to compile.with_all_deps } - - it { is_expected.to contain_package('codedeployagent').with_ensure('present') } - end + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_package('ruby-full').with_ensure('installed') } + it { + is_expected.to contain_archive('/tmp/codedeploy-agent.deb').with( + source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', + ) + } + it { + is_expected.to contain_exec('install_codedeploy_agent').with( + command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', + unless: '/usr/bin/dpkg -s codedeploy-agent', + ) + } end - context "on debian-x86_64" do + context "with custom region" do let(:facts) do { - :osfamily => 'Debian', - :operatingsystem => 'Debian', + os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, } end + let(:pre_condition) { "class { 'codedeploy': aws_region => 'eu-west-1' }" } - context "codedeploy class without any parameters" do - let(:params) {{ }} - - it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_archive('/tmp/codedeploy-agent.deb').with( + source: 'https://aws-codedeploy-eu-west-1.s3.eu-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', + ) + } + end - it { is_expected.to contain_exec('download_codedeploy_installer').with_command('/usr/bin/aws s3 cp s3://aws-codedeploy-us-east-1/latest/install . --region us-east-1') } - it { is_expected.to contain_exec('install_codedeploy_agent').with_command('/tmp/install auto') } - it { is_expected.to contain_file('/tmp/install').with({'mode' => '0740'}) } - it { is_expected.to contain_package('awscli').with({'ensure' => 'present'}) } + context "on unsupported OS" do + let(:facts) do + { + os: { 'name' => 'Solaris', 'family' => 'Solaris' }, + } end + let(:pre_condition) { 'include codedeploy' } + + it { is_expected.to compile.and_raise_error(%r{Solaris not supported}) } end end diff --git a/spec/classes/service_spec.rb b/spec/classes/service_spec.rb index 30ad51c..fd07253 100644 --- a/spec/classes/service_spec.rb +++ b/spec/classes/service_spec.rb @@ -1,20 +1,20 @@ require 'spec_helper' -describe 'codedeploy' do - context 'supported operating systems' do - on_supported_os.each do |os, facts| - context "on #{os}" do - let(:facts) do - facts - end - - context "codedeploy class without any parameters" do - let(:params) {{ }} - - it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_service('codedeploy-agent') } - end - end +describe 'codedeploy::service' do + context "on Ubuntu" do + let(:facts) do + { + os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + } end + let(:pre_condition) { 'include codedeploy' } + + it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_service('codedeploy-agent').with( + ensure: 'running', + enable: true, + ) + } end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1ffdf17..dd6ca22 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1 @@ -require 'puppetlabs_spec_helper/module_spec_helper' -require 'rspec-puppet-facts' -include RspecPuppetFacts +require 'voxpupuli/test/spec_helper' diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb deleted file mode 100644 index 5fe2deb..0000000 --- a/spec/spec_helper_acceptance.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'beaker-rspec/spec_helper' -require 'beaker-rspec/helpers/serverspec' - -unless ENV['BEAKER_provision'] == 'no' - hosts.each do |host| - # Install Puppet - if host.is_pe? - install_pe - else - install_puppet - end - end -end - -RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - - # Readable test descriptions - c.formatter = :documentation - - # Configure all nodes in nodeset - c.before :suite do - # Install module and dependencies - puppet_module_install(:source => proj_root, :module_name => 'codedeploy') - hosts.each do |host| - on host, puppet('module', 'install', 'puppetlabs-stdlib'), { :acceptable_exit_codes => [0,1] } - end - end -end diff --git a/tests/init.pp b/tests/init.pp deleted file mode 100644 index 605d50b..0000000 --- a/tests/init.pp +++ /dev/null @@ -1,12 +0,0 @@ -# The baseline for module testing used by Puppet Labs is that each manifest -# should have a corresponding test manifest that declares that class or defined -# type. -# -# Tests are then run by using puppet apply --noop (to check for compilation -# errors and view a log of events) or by fully applying the test in a virtual -# environment (to compare the resulting system state to the desired state). -# -# Learn more about module testing here: -# http://docs.puppetlabs.com/guides/tests_smoke.html -# -include ::codedeploy From f04ba557ee2b117549fa16b7aa614e12f15d3a3d Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 12:51:10 -0700 Subject: [PATCH 12/22] update name; upstream not taking merges. --- metadata.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata.json b/metadata.json index d695d2c..a87695a 100644 --- a/metadata.json +++ b/metadata.json @@ -1,7 +1,7 @@ { - "name": "walkamongus-codedeploy", + "name": "jackdpeterson-codedeploy", "version": "1.0.1", - "author": "Chadwick Banning", + "author": "Jack Peterson", "summary": "Puppet module to manage the AWS CodeDeploy agent", "license": "Apache-2.0", "source": "git@github.com:jackdpeterson/puppet-codedeploy.git", From 696f5fe740f7a0d7caa1b5a3a6ec4a0e8be4ed39 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 13:00:41 -0700 Subject: [PATCH 13/22] make the PDK --- .github/workflows/release.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..748d385 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,25 @@ +name: Build & Release + +on: + push: + tags: + - 'v*' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + - name: Install PDK + run: gem install pdk + - name: Build module tarball + run: pdk build + - name: Upload tarball + uses: actions/upload-artifact@v4 + with: + name: module-tarball + path: pkg/*.tar.gz From 32564d70dad6c1e66dd119d8c317dbcd1027101b Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 13:17:45 -0700 Subject: [PATCH 14/22] more PDK release fun --- .github/workflows/release.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 748d385..727e0a9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,9 @@ on: tags: - 'v*' +permissions: + contents: write + jobs: build: runs-on: ubuntu-latest @@ -18,8 +21,7 @@ jobs: run: gem install pdk - name: Build module tarball run: pdk build - - name: Upload tarball - uses: actions/upload-artifact@v4 + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 with: - name: module-tarball - path: pkg/*.tar.gz + files: pkg/*.tar.gz From ff53cd9c27414f6989c653e2e6d1667a1814a94e Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 13:33:11 -0700 Subject: [PATCH 15/22] Automate release: set version from tag, attach tarball to GitHub Release --- .github/workflows/release.yml | 17 +++++++++++------ metadata.json | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 727e0a9..e39c2aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Build & Release +name: Release on: push: @@ -9,7 +9,8 @@ permissions: contents: write jobs: - build: + release: + name: Build & Release runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 @@ -19,9 +20,13 @@ jobs: bundler-cache: true - name: Install PDK run: gem install pdk + - name: Set version from tag + run: | + VERSION="${GITHUB_REF_NAME#v}" + sed -i "s/\"version\": \".*\"/\"version\": \"${VERSION}\"/" metadata.json - name: Build module tarball - run: pdk build + run: pdk build --force - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - files: pkg/*.tar.gz + env: + GH_TOKEN: ${{ github.token }} + run: gh release create ${{ github.ref_name }} pkg/*.tar.gz --generate-notes diff --git a/metadata.json b/metadata.json index a87695a..657e624 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "jackdpeterson-codedeploy", - "version": "1.0.1", + "version": "1.0.0", "author": "Jack Peterson", "summary": "Puppet module to manage the AWS CodeDeploy agent", "license": "Apache-2.0", From 4dad411f45e178f2fc351f09a5b2a993002041f1 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 14:36:11 -0700 Subject: [PATCH 16/22] workaround the absence of ruby 3.2 on ubuntu 26.04 for installing codedeploy agent. This might work --- manifests/install.pp | 16 ++++++++++++++-- spec/classes/init_spec.rb | 4 ++-- spec/classes/install_spec.rb | 31 ++++++++++++++++++++++++++++--- spec/classes/service_spec.rb | 2 +- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/manifests/install.pp b/manifests/install.pp index 99b317d..88cf45a 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -10,7 +10,19 @@ } } 'Debian', 'Ubuntu': { - ensure_packages(['ruby-full'], { 'ensure' => 'present' }) + if versioncmp($facts['os']['release']['major'], '26') >= 0 { + exec { 'install_ruby32_snap': + command => '/usr/bin/snap install ruby --classic --channel=3.2/stable', + unless => '/usr/bin/snap list ruby', + path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], + } + + $ruby_require = Exec['install_ruby32_snap'] + } else { + ensure_packages(['ruby-full'], { 'ensure' => 'present' }) + + $ruby_require = Package['ruby-full'] + } $region = $codedeploy::aws_region $deb_url = "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent_all.deb" @@ -22,7 +34,7 @@ exec { 'install_codedeploy_agent': command => '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', unless => '/usr/bin/dpkg -s codedeploy-agent', - require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], + require => [Archive['/tmp/codedeploy-agent.deb'], $ruby_require], path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } } diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 3a7909d..32a4bed 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -4,7 +4,7 @@ context "on Ubuntu" do let(:facts) do { - os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } end @@ -28,7 +28,7 @@ context "with custom parameters" do let(:facts) do { - os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } end let(:params) { { aws_region: 'ap-southeast-1' } } diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 76e5290..cb67816 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -19,16 +19,17 @@ } end - context "on Ubuntu" do + context "on Ubuntu 24.04" do let(:facts) do { - os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } end let(:pre_condition) { 'include codedeploy' } it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('ruby-full').with_ensure('installed') } + it { is_expected.not_to contain_exec('install_ruby32_snap') } it { is_expected.to contain_archive('/tmp/codedeploy-agent.deb').with( source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', @@ -38,14 +39,38 @@ is_expected.to contain_exec('install_codedeploy_agent').with( command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', unless: '/usr/bin/dpkg -s codedeploy-agent', + ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Package[ruby-full]']) + } + end + + context "on Ubuntu 26.04" do + let(:facts) do + { + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '26' } }, + } + end + let(:pre_condition) { 'include codedeploy' } + + it { is_expected.to compile.with_all_deps } + it { is_expected.not_to contain_package('ruby-full') } + it { + is_expected.to contain_exec('install_ruby32_snap').with( + command: '/usr/bin/snap install ruby --classic --channel=3.2/stable', + unless: '/usr/bin/snap list ruby', ) } + it { + is_expected.to contain_exec('install_codedeploy_agent').with( + command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', + unless: '/usr/bin/dpkg -s codedeploy-agent', + ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Exec[install_ruby32_snap]']) + } end context "with custom region" do let(:facts) do { - os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } end let(:pre_condition) { "class { 'codedeploy': aws_region => 'eu-west-1' }" } diff --git a/spec/classes/service_spec.rb b/spec/classes/service_spec.rb index fd07253..f8a79b4 100644 --- a/spec/classes/service_spec.rb +++ b/spec/classes/service_spec.rb @@ -4,7 +4,7 @@ context "on Ubuntu" do let(:facts) do { - os: { 'name' => 'Ubuntu', 'family' => 'Debian' }, + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } end let(:pre_condition) { 'include codedeploy' } From af2688eeb6adf771913388851e926cd0411fd26c Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 14:46:45 -0700 Subject: [PATCH 17/22] Use system Ruby on all Ubuntu versions; agent verified compatible with Ruby 3.3 The codedeploy-agent .deb declares dependencies on Ruby <= 3.2, but source analysis confirms the agent runs correctly on Ruby 3.3 (Ubuntu 26.04). Removed snap-based Ruby 3.2 workaround in favor of using the system ruby-full package with dpkg --force-depends. - Simplified install.pp (no version-specific branching) - Updated tests and README with compatibility note - Added extracted_deb/ to .gitignore --- .gitignore | 1 + README.markdown | 8 ++++++++ manifests/install.pp | 19 +++++-------------- spec/classes/install_spec.rb | 11 ++--------- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index 1364d80..6254ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ .yardoc coverage /.idea +/extracted_deb \ No newline at end of file diff --git a/README.markdown b/README.markdown index 712ce32..b8ab170 100644 --- a/README.markdown +++ b/README.markdown @@ -63,6 +63,14 @@ Supported operating systems: Requires Puppet 8. +### Ruby Compatibility + +The `codedeploy-agent` `.deb` package declares dependencies on Ruby <= 3.2. +However, analysis of the agent's Ruby source code confirms it is fully +compatible with Ruby 3.3 (shipped with Ubuntu 26.04). This module uses +`dpkg --force-depends` to bypass the packaging constraint on all +Debian/Ubuntu versions. + ## Testing ```bash diff --git a/manifests/install.pp b/manifests/install.pp index 88cf45a..53e8d29 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -10,19 +10,7 @@ } } 'Debian', 'Ubuntu': { - if versioncmp($facts['os']['release']['major'], '26') >= 0 { - exec { 'install_ruby32_snap': - command => '/usr/bin/snap install ruby --classic --channel=3.2/stable', - unless => '/usr/bin/snap list ruby', - path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], - } - - $ruby_require = Exec['install_ruby32_snap'] - } else { - ensure_packages(['ruby-full'], { 'ensure' => 'present' }) - - $ruby_require = Package['ruby-full'] - } + ensure_packages(['ruby-full'], { 'ensure' => 'present' }) $region = $codedeploy::aws_region $deb_url = "https://aws-codedeploy-${region}.s3.${region}.amazonaws.com/latest/codedeploy-agent_all.deb" @@ -31,10 +19,13 @@ source => $deb_url, creates => '/tmp/codedeploy-agent.deb', } + # The codedeploy-agent .deb declares dependencies on ruby <= 3.2, but + # the agent code is verified compatible with Ruby 3.3 (Ubuntu 26.04). + # We use --force-depends to bypass the packaging constraint. exec { 'install_codedeploy_agent': command => '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', unless => '/usr/bin/dpkg -s codedeploy-agent', - require => [Archive['/tmp/codedeploy-agent.deb'], $ruby_require], + require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } } diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index cb67816..086c64f 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -29,7 +29,6 @@ it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('ruby-full').with_ensure('installed') } - it { is_expected.not_to contain_exec('install_ruby32_snap') } it { is_expected.to contain_archive('/tmp/codedeploy-agent.deb').with( source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', @@ -52,18 +51,12 @@ let(:pre_condition) { 'include codedeploy' } it { is_expected.to compile.with_all_deps } - it { is_expected.not_to contain_package('ruby-full') } - it { - is_expected.to contain_exec('install_ruby32_snap').with( - command: '/usr/bin/snap install ruby --classic --channel=3.2/stable', - unless: '/usr/bin/snap list ruby', - ) - } + it { is_expected.to contain_package('ruby-full').with_ensure('installed') } it { is_expected.to contain_exec('install_codedeploy_agent').with( command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', unless: '/usr/bin/dpkg -s codedeploy-agent', - ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Exec[install_ruby32_snap]']) + ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Package[ruby-full]']) } end From 0c730b8650b387fc8ff7e934cc2e250fce395ec5 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 14:48:25 -0700 Subject: [PATCH 18/22] Hold codedeploy-agent package to prevent apt broken dependency errors After dpkg --force-depends, apt considers the system broken because the ruby3.2 dependency is unsatisfied. This blocks all subsequent apt operations. apt-mark hold prevents apt from flagging the package. --- manifests/install.pp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/manifests/install.pp b/manifests/install.pp index 53e8d29..a46a0d5 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -28,6 +28,14 @@ require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } + # Mark the package as hold to prevent apt from complaining about + # unsatisfied dependencies on subsequent installs. + exec { 'hold_codedeploy_agent': + command => '/usr/bin/apt-mark hold codedeploy-agent', + unless => '/usr/bin/apt-mark showhold | /usr/bin/grep -q codedeploy-agent', + require => Exec['install_codedeploy_agent'], + path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], + } } default: { fail("${facts['os']['name']} not supported") From d49a56225071ea7deb5827de118830a76a173a6a Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 14:55:29 -0700 Subject: [PATCH 19/22] Repack codedeploy-agent .deb to add ruby3.3 dependency Instead of using dpkg --force-depends (which breaks subsequent apt operations), repack the upstream .deb to add ruby3.3 as an alternative in the Depends field. This allows clean dpkg installation with no broken dependency state. Verified: apt install works normally after the patched package is installed on Ruby 3.3 (Ubuntu 26.04/Debian 13). --- manifests/install.pp | 26 ++++++++++++-------------- spec/classes/install_spec.rb | 19 +++++++++++-------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/manifests/install.pp b/manifests/install.pp index a46a0d5..e7af221 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -19,22 +19,20 @@ source => $deb_url, creates => '/tmp/codedeploy-agent.deb', } - # The codedeploy-agent .deb declares dependencies on ruby <= 3.2, but - # the agent code is verified compatible with Ruby 3.3 (Ubuntu 26.04). - # We use --force-depends to bypass the packaging constraint. - exec { 'install_codedeploy_agent': - command => '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', - unless => '/usr/bin/dpkg -s codedeploy-agent', - require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], + # The upstream .deb only lists ruby <= 3.2 in Depends, but the agent + # is verified compatible with Ruby 3.3. Patch the control file to add + # ruby3.3 as an alternative so dpkg/apt are satisfied natively. + exec { 'patch_codedeploy_deb': + command => '/bin/bash -c "set -e; cd /tmp; mkdir -p codedeploy-repack; dpkg-deb -R codedeploy-agent.deb codedeploy-repack; sed -i s/ruby3.2/ruby3.2\\ |\\ ruby3.3/ codedeploy-repack/DEBIAN/control; dpkg-deb -b codedeploy-repack codedeploy-agent-patched.deb; rm -rf codedeploy-repack"', + creates => '/tmp/codedeploy-agent-patched.deb', + require => Archive['/tmp/codedeploy-agent.deb'], path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } - # Mark the package as hold to prevent apt from complaining about - # unsatisfied dependencies on subsequent installs. - exec { 'hold_codedeploy_agent': - command => '/usr/bin/apt-mark hold codedeploy-agent', - unless => '/usr/bin/apt-mark showhold | /usr/bin/grep -q codedeploy-agent', - require => Exec['install_codedeploy_agent'], - path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], + package { $codedeploy::package_name: + ensure => present, + provider => 'dpkg', + source => '/tmp/codedeploy-agent-patched.deb', + require => [Exec['patch_codedeploy_deb'], Package['ruby-full']], } } default: { diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 086c64f..10956a1 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -34,11 +34,13 @@ source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', ) } + it { is_expected.to contain_exec('patch_codedeploy_deb').that_requires('Archive[/tmp/codedeploy-agent.deb]') } it { - is_expected.to contain_exec('install_codedeploy_agent').with( - command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', - unless: '/usr/bin/dpkg -s codedeploy-agent', - ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Package[ruby-full]']) + is_expected.to contain_package('codedeploy-agent').with( + ensure: 'present', + provider: 'dpkg', + source: '/tmp/codedeploy-agent-patched.deb', + ).that_requires(['Exec[patch_codedeploy_deb]', 'Package[ruby-full]']) } end @@ -52,11 +54,12 @@ it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('ruby-full').with_ensure('installed') } + it { is_expected.to contain_exec('patch_codedeploy_deb') } it { - is_expected.to contain_exec('install_codedeploy_agent').with( - command: '/usr/bin/dpkg --force-depends -i /tmp/codedeploy-agent.deb', - unless: '/usr/bin/dpkg -s codedeploy-agent', - ).that_requires(['Archive[/tmp/codedeploy-agent.deb]', 'Package[ruby-full]']) + is_expected.to contain_package('codedeploy-agent').with( + provider: 'dpkg', + source: '/tmp/codedeploy-agent-patched.deb', + ) } end From 9a3a4e93baa1f93d05af4c669c3206c6795620b8 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 14:59:35 -0700 Subject: [PATCH 20/22] Extract deb repack logic to idempotent shell script - files/patch_codedeploy_deb.sh handles repacking with ruby3.3 - Script is idempotent: no-ops if already patched or upstream includes ruby3.3 - Puppet unless guard skips exec entirely when upstream deb has ruby3.3 - Will self-disable when AWS patches codedeploy-agent --- files/patch_codedeploy_deb.sh | 29 +++++++++++++++++++++++++++++ manifests/install.pp | 11 ++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100755 files/patch_codedeploy_deb.sh diff --git a/files/patch_codedeploy_deb.sh b/files/patch_codedeploy_deb.sh new file mode 100755 index 0000000..00abdfa --- /dev/null +++ b/files/patch_codedeploy_deb.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Repack codedeploy-agent .deb to add ruby3.3 as a dependency alternative. +# Idempotent: exits 0 if ruby3.3 is already present in the control file. +set -e + +DEB="/tmp/codedeploy-agent.deb" +PATCHED="/tmp/codedeploy-agent-patched.deb" +WORKDIR="/tmp/codedeploy-repack" + +# Check if already patched +if [ -f "$PATCHED" ]; then + if dpkg-deb -I "$PATCHED" | grep -q "ruby3.3"; then + exit 0 + fi +fi + +# Check if upstream already includes ruby3.3 +if dpkg-deb -I "$DEB" | grep -q "ruby3.3"; then + cp "$DEB" "$PATCHED" + exit 0 +fi + +# Repack with ruby3.3 added +rm -rf "$WORKDIR" +mkdir -p "$WORKDIR" +dpkg-deb -R "$DEB" "$WORKDIR" +sed -i 's/ruby3\.2/ruby3.2 | ruby3.3/' "$WORKDIR/DEBIAN/control" +dpkg-deb -b "$WORKDIR" "$PATCHED" +rm -rf "$WORKDIR" diff --git a/manifests/install.pp b/manifests/install.pp index e7af221..94f083f 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -22,10 +22,15 @@ # The upstream .deb only lists ruby <= 3.2 in Depends, but the agent # is verified compatible with Ruby 3.3. Patch the control file to add # ruby3.3 as an alternative so dpkg/apt are satisfied natively. + file { '/tmp/patch_codedeploy_deb.sh': + ensure => file, + source => 'puppet:///modules/codedeploy/patch_codedeploy_deb.sh', + mode => '0755', + } exec { 'patch_codedeploy_deb': - command => '/bin/bash -c "set -e; cd /tmp; mkdir -p codedeploy-repack; dpkg-deb -R codedeploy-agent.deb codedeploy-repack; sed -i s/ruby3.2/ruby3.2\\ |\\ ruby3.3/ codedeploy-repack/DEBIAN/control; dpkg-deb -b codedeploy-repack codedeploy-agent-patched.deb; rm -rf codedeploy-repack"', - creates => '/tmp/codedeploy-agent-patched.deb', - require => Archive['/tmp/codedeploy-agent.deb'], + command => '/tmp/patch_codedeploy_deb.sh', + unless => '/usr/bin/dpkg-deb -I /tmp/codedeploy-agent.deb | /usr/bin/grep -q ruby3.3', + require => [Archive['/tmp/codedeploy-agent.deb'], File['/tmp/patch_codedeploy_deb.sh']], path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], } package { $codedeploy::package_name: From ac5ca8bb3671770bd108b8e75061b7d6e25832f0 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 15:02:48 -0700 Subject: [PATCH 21/22] Only patch deb when system Ruby is 3.3+ On systems with Ruby <= 3.2, the upstream deb installs cleanly without patching. The repack logic now only runs when the ruby fact reports version >= 3.3. --- manifests/install.pp | 45 ++++++++++++++++++++++++------------ spec/classes/install_spec.rb | 18 +++++++-------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/manifests/install.pp b/manifests/install.pp index 94f083f..54f83bd 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -22,22 +22,37 @@ # The upstream .deb only lists ruby <= 3.2 in Depends, but the agent # is verified compatible with Ruby 3.3. Patch the control file to add # ruby3.3 as an alternative so dpkg/apt are satisfied natively. - file { '/tmp/patch_codedeploy_deb.sh': - ensure => file, - source => 'puppet:///modules/codedeploy/patch_codedeploy_deb.sh', - mode => '0755', + # Only needed when the system Ruby is 3.3+. + $ruby_version = $facts['ruby'] ? { + undef => '0', + default => $facts['ruby']['version'], } - exec { 'patch_codedeploy_deb': - command => '/tmp/patch_codedeploy_deb.sh', - unless => '/usr/bin/dpkg-deb -I /tmp/codedeploy-agent.deb | /usr/bin/grep -q ruby3.3', - require => [Archive['/tmp/codedeploy-agent.deb'], File['/tmp/patch_codedeploy_deb.sh']], - path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], - } - package { $codedeploy::package_name: - ensure => present, - provider => 'dpkg', - source => '/tmp/codedeploy-agent-patched.deb', - require => [Exec['patch_codedeploy_deb'], Package['ruby-full']], + + if versioncmp($ruby_version, '3.3') >= 0 { + file { '/tmp/patch_codedeploy_deb.sh': + ensure => file, + source => 'puppet:///modules/codedeploy/patch_codedeploy_deb.sh', + mode => '0755', + } + exec { 'patch_codedeploy_deb': + command => '/tmp/patch_codedeploy_deb.sh', + unless => '/usr/bin/dpkg-deb -I /tmp/codedeploy-agent.deb | /usr/bin/grep -q ruby3.3', + require => [Archive['/tmp/codedeploy-agent.deb'], File['/tmp/patch_codedeploy_deb.sh']], + path => ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin'], + } + package { $codedeploy::package_name: + ensure => present, + provider => 'dpkg', + source => '/tmp/codedeploy-agent-patched.deb', + require => [Exec['patch_codedeploy_deb'], Package['ruby-full']], + } + } else { + package { $codedeploy::package_name: + ensure => present, + provider => 'dpkg', + source => '/tmp/codedeploy-agent.deb', + require => [Archive['/tmp/codedeploy-agent.deb'], Package['ruby-full']], + } } } default: { diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 10956a1..57467db 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -19,35 +19,32 @@ } end - context "on Ubuntu 24.04" do + context "on Ubuntu 24.04 with Ruby 3.2" do let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, + ruby: { 'version' => '3.2.0' }, } end let(:pre_condition) { 'include codedeploy' } it { is_expected.to compile.with_all_deps } it { is_expected.to contain_package('ruby-full').with_ensure('installed') } - it { - is_expected.to contain_archive('/tmp/codedeploy-agent.deb').with( - source: 'https://aws-codedeploy-us-west-1.s3.us-west-1.amazonaws.com/latest/codedeploy-agent_all.deb', - ) - } - it { is_expected.to contain_exec('patch_codedeploy_deb').that_requires('Archive[/tmp/codedeploy-agent.deb]') } + it { is_expected.not_to contain_exec('patch_codedeploy_deb') } it { is_expected.to contain_package('codedeploy-agent').with( ensure: 'present', provider: 'dpkg', - source: '/tmp/codedeploy-agent-patched.deb', - ).that_requires(['Exec[patch_codedeploy_deb]', 'Package[ruby-full]']) + source: '/tmp/codedeploy-agent.deb', + ) } end - context "on Ubuntu 26.04" do + context "on Ubuntu 26.04 with Ruby 3.3" do let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '26' } }, + ruby: { 'version' => '3.3.0' }, } end let(:pre_condition) { 'include codedeploy' } @@ -67,6 +64,7 @@ let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, + ruby: { 'version' => '3.2.0' }, } end let(:pre_condition) { "class { 'codedeploy': aws_region => 'eu-west-1' }" } From c8d200e47c8ae1b1e6ab9880dd16e3ba96532786 Mon Sep 17 00:00:00 2001 From: jackdpeterson Date: Tue, 5 May 2026 15:19:20 -0700 Subject: [PATCH 22/22] Fix: use OS version instead of ruby fact for patch condition The ruby fact reflects the puppet agent's Ruby at catalog compile time, not the system Ruby that will be installed. Use OS release version (Ubuntu 26.04+ ships Ruby 3.3) which is always available and reliable. --- manifests/install.pp | 9 ++------- spec/classes/install_spec.rb | 7 ++----- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/manifests/install.pp b/manifests/install.pp index 54f83bd..5baa772 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -22,13 +22,8 @@ # The upstream .deb only lists ruby <= 3.2 in Depends, but the agent # is verified compatible with Ruby 3.3. Patch the control file to add # ruby3.3 as an alternative so dpkg/apt are satisfied natively. - # Only needed when the system Ruby is 3.3+. - $ruby_version = $facts['ruby'] ? { - undef => '0', - default => $facts['ruby']['version'], - } - - if versioncmp($ruby_version, '3.3') >= 0 { + # Only needed on OS versions that ship Ruby 3.3+ (Ubuntu 26.04+). + if $facts['os']['name'] == 'Ubuntu' and versioncmp($facts['os']['release']['major'], '26') >= 0 { file { '/tmp/patch_codedeploy_deb.sh': ensure => file, source => 'puppet:///modules/codedeploy/patch_codedeploy_deb.sh', diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 57467db..c333cef 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -19,11 +19,10 @@ } end - context "on Ubuntu 24.04 with Ruby 3.2" do + context "on Ubuntu 24.04" do let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, - ruby: { 'version' => '3.2.0' }, } end let(:pre_condition) { 'include codedeploy' } @@ -40,11 +39,10 @@ } end - context "on Ubuntu 26.04 with Ruby 3.3" do + context "on Ubuntu 26.04" do let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '26' } }, - ruby: { 'version' => '3.3.0' }, } end let(:pre_condition) { 'include codedeploy' } @@ -64,7 +62,6 @@ let(:facts) do { os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, - ruby: { 'version' => '3.2.0' }, } end let(:pre_condition) { "class { 'codedeploy': aws_region => 'eu-west-1' }" }