Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
puppet-code (0.1.0-1build270) noble; urgency=medium

* commit event. see changes history in git log

-- root <packager@infrahouse.com> Sat, 27 Dec 2025 15:33:40 +0000

puppet-code (0.1.0-1build269) noble; urgency=medium

* commit event. see changes history in git log
Expand Down
10 changes: 3 additions & 7 deletions environments/sandbox/modules/profile/manifests/auditd.pp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
String $log_file = '/var/log/audit/audit.log',
String $log_file_mode = '0640',
String $log_file_owner = 'root',
String $log_file_group = 'root',
String $log_file_group = 'adm',
) {

package { 'auditd':
Expand Down Expand Up @@ -95,12 +95,8 @@
require => Service['auditd'],
}

# Log rotation for audit logs
# Remove logrotate config - auditd handles rotation natively
file { '/etc/logrotate.d/audit':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => template('profile/auditd/logrotate.erb'),
ensure => absent,
}
}
146 changes: 146 additions & 0 deletions environments/sandbox/modules/profile/manifests/cloudwatch_agent.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Shared CloudWatch agent base class
#
# Provides common resources and configuration for CloudWatch agent:
# - CloudWatch agent package, user, and service
# - Systemd drop-in for supplementary groups (adm group for log access)
# - Monitoring script
# - Common logs and metrics configuration
#
# Service-specific classes should include this class and pass their
# extra_logs and extra_procstat parameters for service-specific collection.
#
# @param cloudwatch_log_group CloudWatch log group name (required)
# @param cloudwatch_namespace CloudWatch metrics namespace (required)
# @param extra_logs Array of service-specific log configs [{path, stream}]
# @param extra_procstat Array of additional process patterns to monitor
# @param audit_log_file Path to the audit log file
# @param audit_log_dir Path to the audit log directory
# @param config_file Path to the CloudWatch agent config file
#
class profile::cloudwatch_agent (
String $cloudwatch_log_group,
String $cloudwatch_namespace,
Array $extra_logs = [],
Array $extra_procstat = [],
String $audit_log_file = '/var/log/audit/audit.log',
String $audit_log_dir = '/var/log/audit',
String $config_file = '/etc/aws/amazon-cloudwatch-agent.json',
) {

# Common logs collected by all services
$common_logs = [
{ 'path' => '/var/log/audit/audit.log', 'stream' => 'audit/security' },
{ 'path' => '/var/log/auth.log', 'stream' => 'auth/ssh' },
{ 'path' => '/var/log/syslog', 'stream' => 'system/syslog' },
{ 'path' => '/var/log/kern.log', 'stream' => 'system/kernel' },
{ 'path' => '/var/log/dpkg.log', 'stream' => 'system/packages' },
{ 'path' => '/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log', 'stream' => 'cloudwatch/agent' },
]

# Common process patterns monitored by all services
$common_procstat = ['auditd']

# Merge common + service-specific
$all_logs = $common_logs + $extra_logs
$all_procstat = $common_procstat + $extra_procstat

# Ensure the CloudWatch agent package is installed
package { 'amazon-cloudwatch-agent':
ensure => installed,
}

# Add cwagent user to groups needed to read log files
# adm: for /var/log/syslog, /var/log/auth.log, /var/log/kern.log
user { 'cwagent':
ensure => present,
groups => ['adm'],
membership => minimum,
require => Package['amazon-cloudwatch-agent'],
}

# Ensure config directory exists
file { '/etc/aws':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
require => Package['amazon-cloudwatch-agent'],
}

# Systemd drop-in to ensure CloudWatch agent gets supplementary groups
# The default unit file doesn't call initgroups(), so we must specify groups explicitly
file { '/etc/systemd/system/amazon-cloudwatch-agent.service.d':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}

file { '/etc/systemd/system/amazon-cloudwatch-agent.service.d/groups.conf':
ensure => file,
owner => 'root',
group => 'root',
mode => '0644',
content => "[Service]\nSupplementaryGroups=adm\n",
require => File['/etc/systemd/system/amazon-cloudwatch-agent.service.d'],
notify => Exec['systemctl-daemon-reload-cloudwatch'],
}

exec { 'systemctl-daemon-reload-cloudwatch':
command => '/bin/systemctl daemon-reload',
refreshonly => true,
}

# Monitoring script for checking CloudWatch agent status
file { '/usr/local/bin/check-cloudwatch-agent':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => '#!/bin/bash
# Check CloudWatch agent status
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a query -m ec2
',
}

# Deploy CloudWatch agent configuration
file { $config_file:
ensure => file,
owner => 'root',
group => 'root',
mode => '0640',
content => template('profile/cloudwatch_agent/amazon-cloudwatch-agent.json.erb'),
require => [
File['/etc/aws'],
Package['amazon-cloudwatch-agent'],
],
notify => Exec['configure-cloudwatch-agent'],
}

# Configure the CloudWatch agent (triggered by config file changes)
exec { 'configure-cloudwatch-agent':
command => "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -c file:${config_file}",
refreshonly => true,
require => [
File['/etc/aws'],
User['cwagent'],
],
notify => Service['amazon-cloudwatch-agent'],
}

# Manage the CloudWatch agent service
# Subscribe to daemon-reload to restart after systemd config changes
service { 'amazon-cloudwatch-agent':
ensure => running,
enable => true,
require => [
Package['amazon-cloudwatch-agent'],
User['cwagent'],
Exec['configure-cloudwatch-agent'],
],
subscribe => Exec['systemctl-daemon-reload-cloudwatch'],
}

}
Original file line number Diff line number Diff line change
@@ -1,140 +1,24 @@
# CloudWatch agent configuration for Jumphost
#
# @param audit_log_file Path to the audit log file (should match profile::auditd::log_file)
# This class configures the CloudWatch agent for Jumphost by including
# the shared base class with Jumphost-specific log collection.
#
class profile::jumphost::cloudwatch_agent (
String $audit_log_file = '/var/log/audit/audit.log',
) {
# Jumphost-specific logs:
# - /var/log/fail2ban.log - Intrusion prevention
#
class profile::jumphost::cloudwatch_agent {

# Only configure if CloudWatch log group is provided via Terraform facts
if $facts['jumphost'] and $facts['jumphost']['cloudwatch_log_group'] {

$cloudwatch_log_group = $facts['jumphost']['cloudwatch_log_group']
$cloudwatch_namespace = $facts['jumphost']['cloudwatch_namespace']
$config_dir = '/etc/aws'
$config_file = "${config_dir}/amazon-cloudwatch-agent.json"
$audit_log_dir = dirname($audit_log_file)
$ec2_hostname = $facts['networking']['hostname']

# Ensure config directory exists
file { $config_dir:
ensure => directory,
owner => 'root',
group => 'root',
mode => '0755',
}

# Install CloudWatch agent
package { 'amazon-cloudwatch-agent':
ensure => installed,
}

# Add cwagent user to groups needed to read log files
# adm: for /var/log/syslog, /var/log/auth.log, /var/log/kern.log
user { 'cwagent':
ensure => present,
groups => ['adm'],
membership => minimum,
require => Package['amazon-cloudwatch-agent'],
notify => Service['amazon-cloudwatch-agent'],
}

# Ensure acl package is installed for setting file ACLs
package { 'acl':
ensure => installed,
}

# Deploy ACL setup script
file { '/usr/local/bin/set-audit-acl':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => template('profile/jumphost/set-audit-acl.sh.erb'),
}

# Deploy ACL verification script
file { '/usr/local/bin/check-audit-acl':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => template('profile/jumphost/check-audit-acl.sh.erb'),
}

# Allow CloudWatch agent to read audit logs
# Set ACL on audit log directory and files so cwagent user can read logs
# Note: Depends on sudo class (managed separately) for ACL verification
exec { 'set-audit-log-acl':
command => '/usr/local/bin/set-audit-acl',
unless => '/usr/local/bin/check-audit-acl',
require => [
Class['sudo'],
Package['acl'],
User['cwagent'],
File['/usr/local/bin/set-audit-acl'],
File['/usr/local/bin/check-audit-acl'],
# Include shared CloudWatch agent base class with Jumphost-specific extras
class { 'profile::cloudwatch_agent':
cloudwatch_log_group => $facts['jumphost']['cloudwatch_log_group'],
cloudwatch_namespace => pick($facts['jumphost']['cloudwatch_namespace'], 'Jumphost/System'),
extra_logs => [
{ 'path' => '/var/log/fail2ban.log', 'stream' => 'security/fail2ban' },
],
}

# Deploy CloudWatch agent configuration
file { $config_file:
ensure => file,
owner => 'root',
group => 'root',
mode => '0640',
content => template('profile/jumphost/amazon-cloudwatch-agent.json.erb'),
require => [
File[$config_dir],
Package['amazon-cloudwatch-agent'],
],
notify => [
Exec['configure-cloudwatch-agent-jumphost'],
Service['amazon-cloudwatch-agent'],
],
}

# Configure and start CloudWatch agent
exec { 'configure-cloudwatch-agent-jumphost':
command => "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a fetch-config -m ec2 -c file:${config_file}",
refreshonly => true,
require => [
File[$config_file],
User['cwagent'],
],
notify => Service['amazon-cloudwatch-agent'],
}

# Ensure CloudWatch agent service is running
service { 'amazon-cloudwatch-agent':
ensure => running,
enable => true,
require => [
Package['amazon-cloudwatch-agent'],
User['cwagent'],
Exec['configure-cloudwatch-agent-jumphost'],
],
}

# Create monitoring script
file { '/usr/local/bin/check-cloudwatch-agent':
ensure => file,
owner => 'root',
group => 'root',
mode => '0755',
content => '#!/bin/bash
# Check CloudWatch agent status for jumphost
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
-a query -m ec2
',
}

# Ensure agent stays running
cron { 'ensure-cloudwatch-agent-running':
command => '/usr/bin/systemctl is-active --quiet amazon-cloudwatch-agent || /usr/bin/systemctl start amazon-cloudwatch-agent',
minute => '*/5',
require => Service['amazon-cloudwatch-agent'],
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# Custom CloudWatch metrics for Jumphost
#
# Publishes security and operational metrics to CloudWatch:
# - ServiceStatus: auditd process health
# - DiskSpaceUsed: root filesystem usage
# - AuditEventsLost: audit event loss detection
# - FailedLogins: SSH authentication failures
# - ServiceStatus: auditd process health (1=running, 0=stopped)
# - AuditEventsLost: delta of lost audit events since last check
# - FailedLogins: SSH authentication failures (from journalctl)
#
class profile::jumphost::custom_metrics {

Expand Down Expand Up @@ -32,7 +31,6 @@
}

# Schedule metrics collection every minute
# (ServiceStatus, AuditEventsLost, FailedLogins need 60s interval)
cron { 'publish-jumphost-metrics':
command => '/usr/local/bin/publish-jumphost-metrics',
user => 'root',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
}

include 'profile::openvpn_server::nat'
include 'profile::openvpn_server::auditd'
include 'profile::openvpn_server::cloudwatch_agent'

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @summary: Auditd configuration for OpenVPN server.
#
# Includes the base auditd profile for SOC2/ISO27001 compliance logging.
#
class profile::openvpn_server::auditd {

include 'profile::auditd'

}
Loading