Skip to content

This module creates an AWS SSM document that can be used to deploy NixOS configurations to EC2 instances.

License

Notifications You must be signed in to change notification settings

MercuryTechnologies/terraform-aws-ssm-nixos-deploy-document

Repository files navigation

AWS SSM NixOS Deploy Document

This module creates an AWS SSM document that can be used to deploy NixOS configurations to EC2 instances.

More info about how Mercury is using this module in production can be found in this NixCon talk: NixCon2024 Scalable and secure NixOS deploys on AWS

Example usage

See examples for complete examples with step by step explanations.

module "nixos_deploy_document" {
  source = "github.com/MercuryTechnologies/terraform-aws-ssm-nixos-deploy-document"
  nix_config = <<-EOF
    extra-substituters        = s3://our-internal-cache
    extra-trusted-public-keys = our-internal-cache-1:GJSsQKjGT+cXUTmx5y5BEUGfPf25dMkZhpJZtVNklTk=
  EOF
}

Using aws ssm send-command

You can trigger deploys from the command line using aws ssm send-command:

out_path=$(nix build --print-out-paths '.#nixosConfigurations.webserver.config.system.build.toplevel')
nix copy --to "s3://our-internal-cache&secret-key=./key.sec" "$out_path"
aws ssm send-command \
  --document-name NixOS-Deploy \
  --targets 'Key=tag:Role,Values=webserver' 'Key=tag:Env,Values=production' \
  --parameters "installable=$out_path"

Deploying a flake ref using an SSM State Manager association

See examples/flakeref for a complete example.

resource "aws_ssm_association" "flakeref" {
  name = module.nixos_deploy_document.id
  targets {
    key    = "tag:Role"
    values = ["webserver"]
  }
  parameters = {
    installable = "github:MercuryTechnologies/nixos-configs#nixosConfigurations.webserver.config.system.build.toplevel"
  }
}

Deploying a nix store path an SSM State Manager association

See examples/flakeref for a complete example.

resource "aws_ssm_association" "store_path" {
  name = module.nixos_deploy_document.id
  targets {
    key    = "tag:Role"
    values = ["webserver"]
  }
  parameters = {
    installable = "/nix/store/2hf8wy165v5n5xzajbv13bqrlr70bh6y-nixos-system-webserver-24.11.20241216.3945713"
  }
}

Default values and parameters

All variables to the module are also re-exposed as parameters in the SSM document. This means you can set parameter defaults globally, but also override them using parameters on a case per case basis.

For example, we can define that by default deploys are always dry runs, and use our S3 bucket as a binary cache, but only enable deploys on specific associations by overriding the action parameter in the association.

module "nixos_deploy_document" {
  source = "github.com/mercury-technologies/terraform-aws-ssm-nixos-deploy-document"

  nix_config   = <<-EOF
    substituters = "s3://our-internal-cache"
  EOF
  action       = "dry-activate" # By default deploys are no-ops
}

resource "aws_ssm_association" "assoc1" {
  name = module.nixos_deploy_document.id
  targets {
    key    = "tag:Role"
    values = ["webserver"]
  }
  parameters = {
    action      = "switch"
    installable = var.nix_store_path
  }
}

resource "aws_ssm_association" "assoc2" {
  name = module.nixos_deploy_document.id
  targets {
    key    = "tag:Role"
    values = ["dbserver"]
  }
  parameters = {
    action      = "reboot"
    installable = var.nix_store_path
  }
}

IAM Permissions

Note

When Default Host Management Configuration is used, you need to attach any IAM policies that give access to S3 buckets and such mentioned in the document to the IAM role that was configured there. Else, the permissions need to be attached to the instance profile of the instances that are targeted by the SSM Document.

Requirements

Name Version
terraform >= 1.0
aws >= 5.46

Providers

Name Version
aws >= 5.46

Modules

No modules.

Resources

Name Type
aws_ssm_document.nixos_deploy resource

Inputs

Name Description Type Default Required
action The deploy action to perform. One of switch, test, boot, reboot or dry-activate string "switch" no
installable A nix store path to substitute or a flake output attribute to build. See https://nix.dev/manual/nix/latest/command-ref/new-cli/nix#installables string "/run/current-system" no
name The name of the SSM document string "NixOS-Deploy" no
nix_config Nix configuration to use. See https://nix.dev/manual/nix/latest/command-ref/conf-file for available options. Useful to set extra-substituters and extra-trusted-public-keys when using your own binary cache. string "" no
profile The profile to operate on. See https://nix.dev/manual/nix/latest/command-ref/new-cli/nix3-build#opt-profile string "/nix/var/nix/profiles/system" no
tags A mapping of tags to assign to the document map(string) {} no

Outputs

Name Description
arn The Amazon Resource Name (ARN) of the document
created_date The date the document was created
default_version The default version of the document
description The description of the document
document_version The document version
hash_type The hash type of the document. Valid values: Sha256, Sha1
id The name of the document
latest_version The latest version of the document
parameter The parameters of the document
platform_types The list of operating systems compatible with the document
schema_version The schema version of the document
status The status of the document
tags_all A map of tags assigned to the resource, including those inherited from the provider

About

This module creates an AWS SSM document that can be used to deploy NixOS configurations to EC2 instances.

Resources

License

Stars

Watchers

Forks

Packages

No packages published