Skip to content

MercuryTechnologies/aws-ssm-update-association-action

Repository files navigation

aws-ssm-update-association-action

GitHub Super-Linter CI Check dist/ CodeQL Coverage

Description

GitHub Action for updating AWS SSM State Manager association with new parameters.

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

Usage

This action is similar to https://github.com/MercuryTechnologies/aws-ssm-send-command-action, However unlike a single command, an association is continously applied. If new instances are launched, the association will send commands to the new instances as well.

For example, you could create an association like this in Terraform, using the NixOS deploy document from https://github.com/MercuryTechnologies/terraform-aws-ssm-nixos-deploy-document:

resource "aws_ssm_association" "prometheus" {
  name = module.ssm_nixos_deploy_document.id
  targets {
    key    = "tag:Role"
    values = ["prometheus"]
  }
  max_errors      = "50%"
  max_concurrency = "50%"
}

output "association_id" {
  value = aws_ssm_association.prometheus.id
}

then in your deploy pipeline, you could update the association with the latest version of your NixOS image:

- uses: MercuryTechnologies/aws-ssm-update-association-action@v0
  with:
    association-id: '${{ steps.terraform-output.outputs.association_id }}'
    targets: '[{"Key":"tag:Role","Values":["prometheus"]}]'
    parameters: '{"installable":[toJSON(steps.build-nixos.outputs.store-path)]}'
    wait-until-association-updated: true
    max-wait-time: 600

Inputs

name description required default
association-id

The ID of the association you want to update.

true ""
parameters

The parameters you want to update for the association.

false ""
wait-until-association-updated

Wait until the association is updated.

false false
max-wait-time

The maximum time to wait for the association to be updated.

false 300
log-failed-command-invocations

Log the command invocations that failed for the association. If the command target is targeting hundreds or thousands of instances, this can be slow.

false false

Credentials

By default, this action relies on the default behavior of the AWS SDK for JavasSript to determine AWS credentials and region. You can use the aws-actions/configure-aws-credentials action to configure the GitHub Actions environment with environment variables containing AWS credentials and your desired region.

- uses: 'aws-actions/configure-aws-credentials@v4'
  with:
    role-to-assume: 'arn:aws:iam::123456789012:role/MyRole'
    aws-region: 'us-west-2'

Permissions

Updating an association requires the ssm:UpdateAssociation and ssm:DescribeAssociation permission. It's recommended to write a policy that allows sending commands to specific resources, rather than allowing all resources. See the AWS documentation for more information.

For example, the following policy only allows updating associations in the production environment, does not allow changing the document, and only allows updating associations for instances in the production environment:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UpdateAssociation",
      "Effect": "Allow",
      "Action": "ssm:UpdateAssociation",
      "Resource": [
        "arn:aws:ssm::*:association/*",
        "arn:aws:ec2:*:*:instance/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Environment": "production"
        }
      }
    },
    {
      "Sid": "DescribeAssociation",
      "Effect": "Allow",
      "Action": "ssm:DescribeAssociation",
      "Resource": "*"
    }
  ]
}

When using the log-failed-command-invocations the following extra permissions are required:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "LogFailedCommandInvocations",
      "Effect": "Allow",
      "Action": [
        "ssm:DescribeAssociationExecutions",
        "ssm:DescribeAssociationExecutionTargets",
        "ssm:GetCommandInvocation"
      ],
      "Resource": "*"
    }
  ]
}

Runs

This action is a node20 action.