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/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e39c2aa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,32 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + release: + name: Build & Release + 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: 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 --force + - name: Create GitHub Release + env: + GH_TOKEN: ${{ github.token }} + run: gh release create ${{ github.ref_name }} pkg/*.tar.gz --generate-notes diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..ebf1100 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,48 @@ +name: Test CodeDeploy Module + +on: + push: + branches: [master, main] + pull_request: + +jobs: + 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: + - 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@v5 + - 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/.gitignore b/.gitignore index 6dfe023..6254ce3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ /log .yardoc coverage +/.idea +/extracted_deb \ No newline at end of file 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 new file mode 100644 index 0000000..c6dc8b0 --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,33 @@ +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 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 | 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/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 bb7498c..b8ab170 100644 --- a/README.markdown +++ b/README.markdown @@ -1,15 +1,12 @@ # 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/jackdpeterson/puppet-codedeploy/actions/workflows/test.yml/badge.svg)](https://github.com/jackdpeterson/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 @@ -17,7 +14,7 @@ This module installs and enables the AWS CodeDeploy agent. ## 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 @@ -25,16 +22,59 @@ 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 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. -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. 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/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/config.pp b/manifests/config.pp index 2af0356..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 $::osfamily { + 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 2ab1c58..14e6c10 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,32 +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_url = $::codedeploy::params::package_url, - $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, - $proxy_uri = $::codedeploy::params::proxy_uri, - $max_revisions = $::codedeploy::params::max_revisions, -) 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 9c2821d..5baa772 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -1,51 +1,57 @@ -# == Class codedeploy::install -# -# This class is called from codedeploy for install. -# +# @summary Installs the AWS CodeDeploy agent. class codedeploy::install { - - case $::osfamily { + case $facts['os']['name'] { 'RedHat', 'Amazon': { - package { $::codedeploy::package_name: + $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': { - package { $::codedeploy::package_name: - ensure => present, - source => $::codedeploy::package_url, + 'Debian', 'Ubuntu': { + 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', } - } - 'Debian': { - if ! defined(Package['awscli']) { - package { 'awscli': - ensure => present, + # 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 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', + 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']], } - } - 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'], - } - file { '/tmp/install': - ensure => file, - owner => 'root', - group => 'root', - mode => '0740', - subscribe => Exec['download_codedeploy_installer'], - notify => Exec['install_codedeploy_agent'], - } - exec { 'install_codedeploy_agent': - command => '/tmp/install auto', - cwd => '/tmp', - refreshonly => true, } } default: { - fail("${::operatingsystem} not supported") + fail("${facts['os']['name']} not supported") } } } diff --git a/manifests/params.pp b/manifests/params.pp index 4f0dc21..956e87d 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,50 +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 $::osfamily { - 'Debian': { - $package_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent_all.deb' - $package_name = 'codedeploy-agent' - $service_name = 'codedeploy-agent' + case $facts['os']['name'] { + 'Debian', 'Ubuntu': { + $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_url = 'https://s3.amazonaws.com/aws-codedeploy-us-east-1/latest/codedeploy-agent.noarch.rpm' - $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_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' - $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("${::operatingsystem} not supported") + fail("${facts['os']['name']} not supported") } } - $log_aws_wire = false + $log_aws_wire = false $wait_between_runs = 1 - $max_revisions = 5 - + $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 72f3911..657e624 100644 --- a/metadata.json +++ b/metadata.json @@ -1,49 +1,51 @@ { - "name": "walkamongus-codedeploy", - "version": "1.0.1", - "author": "Chadwick Banning", + "name": "jackdpeterson-codedeploy", + "version": "1.0.0", + "author": "Jack Peterson", "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": [ { "name": "puppetlabs-stdlib", - "version_requirement": ">=3.2.0 <7.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" + "24.04", + "26.04" ] } ], "requirements": [ - { - "name": "pe", - "version_requirement": ">= 3.2.0 < 2015.4.0" - }, { "name": "puppet", - "version_requirement": ">= 3.4.0 < 5.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..32a4bed 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', 'release' => { 'major' => '24' } }, + } 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', 'release' => { 'major' => '24' } }, + } 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..c333cef 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -1,56 +1,86 @@ 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 24.04" do let(:facts) do { - :osfamily => 'Windows', - :operatingsystem => 'Windows', + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } 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 compile.with_all_deps } + it { is_expected.to contain_package('ruby-full').with_ensure('installed') } + 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.deb', + ) + } + end - it { is_expected.to contain_package('codedeployagent').with_ensure('present') } + 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.to contain_package('ruby-full').with_ensure('installed') } + it { is_expected.to contain_exec('patch_codedeploy_deb') } + it { + is_expected.to contain_package('codedeploy-agent').with( + provider: 'dpkg', + source: '/tmp/codedeploy-agent-patched.deb', + ) + } end - context "on debian-x86_64" do + context "with custom region" do let(:facts) do { - :osfamily => 'Debian', - :operatingsystem => 'Debian', + os: { 'name' => 'Ubuntu', 'family' => 'Debian', 'release' => { 'major' => '24' } }, } 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..f8a79b4 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', 'release' => { 'major' => '24' } }, + } 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/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'] %> 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