Skip to content

Commit

Permalink
amazon-cloudwatch-agent: init at 1.300044.0
Browse files Browse the repository at this point in the history
**Amazon CloudWatch Agent** is an agent that collects data about the running
server and sends metrics and logs to the *Amazon CloudWatch* service.

This commit also introduces a corresponding NixOS service module to manage the
Amazon CloudWatch Agent via systemd.

Based on
https://github.com/wearetechnative/amazon-cloudwatch-agent-nix/blob/main/module.nix
  • Loading branch information
philipmw committed Sep 14, 2024
1 parent 18c0991 commit 1a6b5fa
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 0 deletions.
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2411.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@

- [ToDesk](https://www.todesk.com/linux.html), a remote desktop applicaton. Available as [services.todesk.enable](#opt-services.todesk.enable).

- [Amazon CloudWatch Agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html#install-CloudWatch-Agent-iam_user-first), an agent for collecting metrics and logs and sending them to *Amazon CloudWatch*.

## Backward Incompatibilities {#sec-release-24.11-incompatibilities}

- `transmission` package has been aliased with a `trace` warning to `transmission_3`. Since [Transmission 4 has been released last year](https://github.com/transmission/transmission/releases/tag/4.0.0), and Transmission 3 will eventually go away, it was decided perform this warning alias to make people aware of the new version. The `services.transmission.package` defaults to `transmission_3` as well because the upgrade can cause data loss in certain specific usage patterns (examples: [#5153](https://github.com/transmission/transmission/issues/5153), [#6796](https://github.com/transmission/transmission/issues/6796)). Please make sure to back up to your data directory per your usage:
Expand Down
147 changes: 147 additions & 0 deletions nixos/modules/services/monitoring/amazon-cloudwatch-agent.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
{
config,
lib,
pkgs,
...
}:

let
inherit (lib)
attrsets
mkEnableOption
mkOption
optionalAttrs
types
;

cfg = config.services.amazon-cloudwatch-agent;

assembledConfig = attrsets.mergeAttrsList [
(optionalAttrs (cfg.configAgent != null) { agent = cfg.configAgent; })
(optionalAttrs (cfg.configMetrics != null) { metrics = cfg.configMetrics; })
(optionalAttrs (cfg.configLogs != null) { logs = cfg.configLogs; })
(optionalAttrs (cfg.configTraces != null) { traces = cfg.configTraces; })
];

agentConfigFile = (pkgs.formats.json { }).generate "config.json" assembledConfig;

awsCredsFile = (pkgs.formats.ini { }).generate "aws-credentials" {
AmazonCloudWatchAgent = cfg.configAwsCreds;
};

commonConfigTomlFile = (pkgs.formats.toml { }).generate "common-config.toml" {
credentials = {
shared_credential_file = "${awsCredsFile}";
shared_credential_profile = "AmazonCloudWatchAgent";
};
};
in
{
options = {
services.amazon-cloudwatch-agent = {
package = lib.mkPackageOption pkgs "amazon-cloudwatch-agent" { };

enable = mkEnableOption ''
Amazon CloudWatch Amazon
'';

configAwsCreds = mkOption {
type = types.submodule {
freeformType = with types; attrsOf str;
};
description = "AWS credentials for CloudWatch Agent (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-on-premise.html)";
default = {
aws_access_key_id = "FILL-IN";
aws_secret_access_key = "FILL-IN";
region = "FILL-IN";
};
};

configAgent = mkOption {
type = types.submodule {
freeformType = types.oneOf [
(pkgs.formats.json { }).type
null
];
};
description = "Agent section of the CloudWatch Agent configuration (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)";
default = null;
};

configMetrics = mkOption {
type = types.submodule {
freeformType = types.oneOf [
(pkgs.formats.json { }).type
null
];
};
description = "Metrics section of the CloudWatch Agent configuration (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)";
default = null;
};

configLogs = mkOption {
type = types.nullOr (
types.submodule {
freeformType = (pkgs.formats.json { }).type;
}
);
description = "Logs section of the CloudWatch Agent configuration (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)";
default = null; # not empty object because, if we specify the key, we must also specify certain child attributes.
};

configTraces = mkOption {
type = types.nullOr (
types.submodule {
freeformType = (pkgs.formats.json { }).type;
}
);
description = "Traces section of the CloudWatch Agent configuration (https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)";
default = null; # not empty object because, if we specify the key, we must also specify certain child attributes.
};
};
};

config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ]; # FIXME: what does this do?

users.users.cwagent = {
description = "amazon-cloudwatch-agent daemon user";
isSystemUser = true;
group = "cwagent";
};

users.groups.cwagent = { };

systemd.tmpfiles.rules = [
"D /opt/aws/amazon-cloudwatch-agent/etc 750 cwagent cwagent" # for symlinks made by this file, and where the agent wants to write the toml config
"D /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d 750 cwagent cwagent" # where the agent wants to write to
"D /opt/aws/amazon-cloudwatch-agent/logs 750 cwagent cwagent"
"D /opt/aws/amazon-cloudwatch-agent/var 750 cwagent cwagent"
"L+ /opt/aws/amazon-cloudwatch-agent/etc/common-config.toml - - - - ${commonConfigTomlFile}"
"L+ /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json - - - - ${agentConfigFile}"
"L+ /opt/aws/amazon-cloudwatch-agent/bin - - - - ${cfg.package}/bin"
];

systemd.services.amazon-cloudwatch-agent = {
enable = true;
description = "Amazon CloudWatch Agent";
documentation = [
"https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html"
];

wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];

serviceConfig = {
# systemd runs the agent as root, then the agent will switch to the dedicated user
Type = "simple";
Restart = "on-failure";
RestartSec = 60;
ExecStart = "${cfg.package}/bin/start-amazon-cloudwatch-agent";
KillMode = "process";
# According to systemd documentation, the simple type does not need this, but we have it anyway, so can't hurt to specify it.
PIDFile = "/opt/aws/amazon-cloudwatch-agent/var/amazon-cloudwatch-agent.pid";
};
};
};
}
83 changes: 83 additions & 0 deletions pkgs/by-name/am/amazon-cloudwatch-agent/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
config,
lib,
buildGoModule,
fetchgit,
pkgs,
}:

buildGoModule rec {
pname = "amazon-cloudwatch-agent";
version = "1.300044.0";

src = fetchgit {
url = "https://github.com/aws/amazon-cloudwatch-agent.git";
rev = "v${version}";
sha256 = "sha256-sG0dvmTagpob23/5L2QB32bwFmmRygEQKrAmgAWgEOE=";
};

vendorHash = "sha256-a1xjnVXvSinYGqjFOmlCxJwWc9sc9OAfSuAMRCAlxCM=";

meta = with lib; {
description = "Amazon CloudWatch Agent";
homepage = "https://github.com/aws/amazon-cloudwatch-agent";
license = licenses.mit;
maintainers = with lib.maintainers; [ pmw ];
platforms = with lib.platforms; [
unix
windows
];
};

doCheck = false;

patchPhase = ''
echo "" >> Makefile
echo "amazon-cloudwatch-agent-nixos-linux: copy-version-file" >> Makefile
echo -e "\t@echo Building CloudWatchAgent for Linux,Debian with ARM64 and AMD64" >> Makefile
echo -e "\t\$(LINUX_AMD64_BUILD)/config-downloader github.com/aws/amazon-cloudwatch-agent/cmd/config-downloader" >> Makefile
echo -e "\t\$(LINUX_AMD64_BUILD)/config-translator github.com/aws/amazon-cloudwatch-agent/cmd/config-translator" >> Makefile
echo -e "\t\$(LINUX_AMD64_BUILD)/amazon-cloudwatch-agent github.com/aws/amazon-cloudwatch-agent/cmd/amazon-cloudwatch-agent" >> Makefile
echo -e "\t\$(LINUX_AMD64_BUILD)/start-amazon-cloudwatch-agent github.com/aws/amazon-cloudwatch-agent/cmd/start-amazon-cloudwatch-agent" >> Makefile
echo -e "\t\$(LINUX_AMD64_BUILD)/amazon-cloudwatch-agent-config-wizard github.com/aws/amazon-cloudwatch-agent/cmd/amazon-cloudwatch-agent-config-wizard" >> Makefile
'';

buildPhase = ''
export FAKEBUILD="false"
if [ $FAKEBUILD == "true" ]
then
mkdir -p build/bin/linux_amd64
touch build/bin/linux_amd64/fakebin
else
make amazon-cloudwatch-agent-nixos-linux
fi
'';

installPhase = ''
runHook preInstall
mkdir -p $out/etc
cp -av build/bin/linux_amd64 $out/bin
cp LICENSE $out/
cp NOTICE $out/
cp licensing/THIRD-PARTY-LICENSES $out/
cp RELEASE_NOTES $out/
cp packaging/dependencies/amazon-cloudwatch-agent-ctl $out/bin/
# TODO in patchPhase
mkdir -p /tmp/amazon-cloudwatch-agent
touch /tmp/amazon-cloudwatch-agent/amazon-cloudwatch-agent.log
ln -s /tmp/amazon-cloudwatch-agent/log $out/log
runHook postInstall
'';
}

0 comments on commit 1a6b5fa

Please sign in to comment.