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:
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
}
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"
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"
}
}
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"
}
}
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
}
}
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.
Name | Version |
---|---|
terraform | >= 1.0 |
aws | >= 5.46 |
Name | Version |
---|---|
aws | >= 5.46 |
No modules.
Name | Type |
---|---|
aws_ssm_document.nixos_deploy | resource |
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 |
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 |