{"id":13574273,"url":"https://github.com/aws/aws-node-termination-handler","last_synced_at":"2026-03-05T03:02:18.571Z","repository":{"id":37547854,"uuid":"216631734","full_name":"aws/aws-node-termination-handler","owner":"aws","description":"Gracefully handle EC2 instance shutdown within Kubernetes","archived":false,"fork":false,"pushed_at":"2026-02-17T15:05:19.000Z","size":2300,"stargazers_count":1747,"open_issues_count":17,"forks_count":277,"subscribers_count":18,"default_branch":"main","last_synced_at":"2026-03-02T21:49:43.391Z","etag":null,"topics":["aws-ec2","eks","golang","kubernetes","maintenance-events","spot-instances"],"latest_commit_sha":null,"homepage":"https://aws.amazon.com/ec2","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aws.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-10-21T17:57:15.000Z","updated_at":"2026-03-02T18:25:47.000Z","dependencies_parsed_at":"2023-02-19T09:15:46.023Z","dependency_job_id":"c25214f3-f8c2-41ec-8195-ddaf7862bbc1","html_url":"https://github.com/aws/aws-node-termination-handler","commit_stats":{"total_commits":608,"total_committers":100,"mean_commits":6.08,"dds":0.694078947368421,"last_synced_commit":"498fc02ddf35bc587bebe1798f37eab073d961cf"},"previous_names":[],"tags_count":56,"template":false,"template_full_name":"amazon-archives/__template_Apache-2.0","purl":"pkg:github/aws/aws-node-termination-handler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-node-termination-handler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-node-termination-handler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-node-termination-handler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-node-termination-handler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aws","download_url":"https://codeload.github.com/aws/aws-node-termination-handler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aws%2Faws-node-termination-handler/sbom","scorecard":{"id":219416,"data":{"date":"2025-08-11","repo":{"name":"github.com/aws/aws-node-termination-handler","commit":"d2057875680d324bc2731022bf60fbd9fbcb34c1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build-and-test.yaml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yaml:9","Warn: no topLevel permission defined: .github/workflows/stale.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.25.2 not signed: https://api.github.com/repos/aws/aws-node-termination-handler/releases/234714733","Warn: release artifact v1.25.1 not signed: https://api.github.com/repos/aws/aws-node-termination-handler/releases/215269203","Warn: release artifact v1.25.0 not signed: https://api.github.com/repos/aws/aws-node-termination-handler/releases/203103848","Warn: release artifact v1.24.0 not signed: https://api.github.com/repos/aws/aws-node-termination-handler/releases/197461971","Warn: release artifact v1.23.1 not signed: https://api.github.com/repos/aws/aws-node-termination-handler/releases/191751846","Warn: release artifact v1.25.2 does not have provenance: https://api.github.com/repos/aws/aws-node-termination-handler/releases/234714733","Warn: release artifact v1.25.1 does not have provenance: https://api.github.com/repos/aws/aws-node-termination-handler/releases/215269203","Warn: release artifact v1.25.0 does not have provenance: https://api.github.com/repos/aws/aws-node-termination-handler/releases/203103848","Warn: release artifact v1.24.0 does not have provenance: https://api.github.com/repos/aws/aws-node-termination-handler/releases/197461971","Warn: release artifact v1.23.1 does not have provenance: https://api.github.com/repos/aws/aws-node-termination-handler/releases/191751846"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/aws/.github/SECURITY.md:1","Info: Found linked content: github.com/aws/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/aws/.github/SECURITY.md:1","Info: Found text in security policy: github.com/aws/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/asg-launch-lifecycle-sqs-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/asg-lifecycle-sqs-heartbeat-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/asg-lifecycle-sqs-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/ec2-state-change-sqs-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/rebalance-recommendation-sqs-node-not-found-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/rebalance-recommendation-sqs-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/scheduled-change-event-sqs-test:0","Info: Possibly incomplete results: error parsing shell code: \"[x]\" must be followed by =: test/e2e/spot-interruption-sqs-test:0","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:82: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:87: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:90: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:106: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:111: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:120: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:133: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:138: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:141: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:165: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:170: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:173: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:197: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:202: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:205: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:65: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build-and-test.yaml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/build-and-test.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/stale.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/stale.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/stale.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/aws/aws-node-termination-handler/stale.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:26","Warn: containerImage not pinned by hash: Dockerfile.windows:4","Warn: containerImage not pinned by hash: Dockerfile.windows:25","Warn: containerImage not pinned by hash: test/readme-test/spellcheck-Dockerfile:1: pin your Docker image by updating golang:1.20 to golang:1.20@sha256:8f9af7094d0cb27cc783c697ac5ba25efdc4da35f8526db21f7aebb0b0b4f18a","Warn: containerImage not pinned by hash: test/webhook-test-proxy/Dockerfile:2","Warn: containerImage not pinned by hash: test/webhook-test-proxy/Dockerfile:22","Warn: containerImage not pinned by hash: test/webhook-test-proxy/Dockerfile.windows:4","Warn: containerImage not pinned by hash: test/webhook-test-proxy/Dockerfile.windows:18","Info:   0 out of  28 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   9 containerImage dependencies pinned","Info:   1 out of   1 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":4,"reason":"6 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0635","Warn: Project is vulnerable to: GO-2022-0646","Warn: Project is vulnerable to: GO-2025-3487 / GHSA-hcg3-q754-cr77","Warn: Project is vulnerable to: GO-2025-3503 / GHSA-qxp5-gwg8-xv66","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw","Warn: Project is vulnerable to: GO-2025-3488 / GHSA-6v2p-p543-phr9"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T02:12:03.418Z","repository_id":37547854,"created_at":"2025-08-17T02:12:03.419Z","updated_at":"2025-08-17T02:12:03.419Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30106136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T01:39:18.192Z","status":"online","status_checked_at":"2026-03-05T02:00:06.710Z","response_time":93,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-ec2","eks","golang","kubernetes","maintenance-events","spot-instances"],"created_at":"2024-08-01T15:00:49.273Z","updated_at":"2026-03-05T03:02:18.555Z","avatar_url":"https://github.com/aws.png","language":"Go","funding_links":[],"categories":["Workloads","Go","Data plane management","Tools and Libraries"],"sub_categories":["Tools","Miscellaneous"],"readme":"\u003ch1\u003eAWS Node Termination Handler\u003c/h1\u003e\n\n\u003ch4\u003eGracefully handle EC2 instance shutdown within Kubernetes\u003c/h4\u003e\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/kubernetes/kubernetes/releases\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Kubernetes-%3E%3D%201.23-brightgreen\" alt=\"kubernetes\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://golang.org/doc/go1.25\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/go-mod/go-version/aws/aws-node-termination-handler?color=blueviolet\" alt=\"go-version\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-Apache%202.0-ff69b4.svg\" alt=\"license\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/aws/aws-node-termination-handler\"\u003e\n    \u003cimg src=\"https://img.shields.io/codecov/c/github/aws/aws-node-termination-handler\" alt=\"build-status\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://gallery.ecr.aws/aws-ec2/aws-node-termination-handler\"\u003e\n    \u003cimg src=\"https://img.shields.io/docker/pulls/amazon/aws-node-termination-handler\" alt=\"docker-pulls\"\u003e\n  \u003c/a\u003e\n    \u003ca href=\"https://github.com/aws/aws-node-termination-handler/workflows\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/workflow/status/aws/aws-node-termination-handler/Build%20and%20Test?label=Builds%20%26%20Tests\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv\u003e\n\u003chr\u003e\n\u003c/div\u003e\n\n\n## Project Summary\n\nThis project ensures that the Kubernetes control plane responds appropriately to events that can cause your EC2 instance to become unavailable, such as [EC2 maintenance events](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html), [EC2 Spot interruptions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html), [ASG Scale-In](https://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html#as-lifecycle-scale-in), ASG AZ Rebalance, and EC2 Instance Termination via the API or Console.  If not handled, your application code may not stop gracefully, take longer to recover full availability, or accidentally schedule work to nodes that are going down.\n\nThe aws-node-termination-handler (NTH) can operate in two different modes: Instance Metadata Service (IMDS) or the Queue Processor.\n\nThe aws-node-termination-handler **[Instance Metadata Service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) Monitor** will run a small pod on each host to perform monitoring of IMDS paths like `/spot` or `/events` and react accordingly to drain and/or cordon the corresponding node.\n\nThe aws-node-termination-handler **Queue Processor** will monitor an SQS queue of events from Amazon EventBridge for ASG lifecycle events, EC2 status change events, Spot Interruption Termination Notice events, and Spot Rebalance Recommendation events. When NTH detects an instance is going down, we use the Kubernetes API to cordon the node to ensure no new work is scheduled there, then drain it, removing any existing work. The termination handler **Queue Processor** requires AWS IAM permissions to monitor and manage the SQS queue and to query the EC2 API.\n\nYou can run the termination handler on any Kubernetes cluster running on AWS, including self-managed clusters and those created with Amazon [Elastic Kubernetes Service](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html). If you're using [EKS managed node groups](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html), you don't need the aws-node-termination-handler.\n\n\u003e ⚠️ Note: Windows Server 2019 support has been removed as GitHub Actions no longer supports this version. Please migrate to Windows Server 2022. For more details, see [GitHub's deprecation announcement](https://github.com/actions/runner-images/issues/12045).\n\n## Major Features\n\nBoth modes (IMDS and Queue Processor) monitor for events affecting your EC2 instances, but each supports different types of events. Both modes have the following:\n\n- Helm installation and event configuration support\n- Webhook feature to send shutdown or restart notification messages\n- Unit \u0026 integration tests\n\n### Instance Metadata Service (IMDS) Processor\nMust be deployed as a Kubernetes **DaemonSet**.\n\n- Monitors EC2 Instance Metadata for:\n   - [Spot Instance Termination Notifications](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-instance-termination-notices.html)\n   - [Scheduled Events](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.html)\n   - [Instance Rebalance Recommendations](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/rebalance-recommendations.html)\n   - [Autoscaling Group Target Lifecycle State changes](https://docs.aws.amazon.com/autoscaling/ec2/userguide/retrieving-target-lifecycle-state-through-imds.html)\n\n#### IMDS Processor with ASG Target Lifecycle State change\nPlease note that IMDS does **not** support lifecycle *hooks*, but it does support lifecycle *state* change. When using IMDS mode with the ASG target lifecycle state, ASG will update instance metadata to be **Terminated** before it terminates the node. NTH will monitor the path latest/meta-data/autoscaling/target-lifecycle-state for changes and will cordon and drain when the target state is set to **Terminated**.\n\n### Queue Processor\nMust be deployed as a Kubernetes **Deployment**. Also requires some **additional infrastructure setup** (including SQS queue, EventBridge rules).\n\n- Monitors an SQS Queue for:\n   - Spot Instance Termination Notifications\n   - Scheduled Events (via AWS Health)\n   - Instance Rebalance Recommendations\n   - ASG Termination Lifecycle Hooks to handle the following:\n     - [ASG Scale-In](https://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html)\n     - [Availability Zone Rebalance](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#:~:text=are%20replaced%20first.-,Availability%20Zone%20rebalancing,-Amazon%20EC2%20Auto)\n     - [Unhealthy Instances](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-health-checks.html), and more\n   - [Instance State Change events](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-instance-state-changes.html)\n\nWe can use the **Queue Processor** for both ASG Lifecycle Termination Hooks and Instance State Change Events for termination of nodes. Below listed are the details on how AWS EC2 takes actions for graceful shutdowns. You can pick one that is best suitable for your use, based on the configuration and workloads.\n\n#### Queue Processor with ASG Lifecycle Hooks\nWhen using the ASG Lifecycle Hooks, ASG first sends the lifecycle action notification then waits until it has been completed or times out. This allows time for NTH to receive the notification via SQS, cordon and drain the node, and then complete the lifecycle action. Once the ASG receives the completion it then instructs EC2 to terminate the instance.\n\n#### Queue Processor with Instance State Change Events\nWhen using the EC2 Console or EC2 API to terminate the instance, a state-change notification is sent and the instance termination is started. EC2 does not wait for a \"continue\" signal before beginning to terminate the instance. When you terminate an EC2 instance, it should trigger a graceful operating system shutdown which will send a SIGTERM to the kubelet, which will in-turn start shutting down pods by propagating that SIGTERM to the containers on the node. If the containers do not shut down by the kubelet's `podTerminationGracePeriod (k8s default is 30s)`, then it will send a SIGKILL to forcefully terminate the containers. Setting the `podTerminationGracePeriod` to a max of 90sec (probably a bit less than that) will delay the termination of pods, which helps in graceful shutdown.\n\n#### Issuing Lifecycle Heartbeats\n\nYou can set NTH to send heartbeats to ASG in Queue Processor mode. This allows for a much longer grace period (up to 48 hours) for termination than the maximum heartbeat timeout of two hours. The feature is useful when pods require long time to drain or when you need a shorter heartbeat timeout with a longer grace period.\n\n##### How it works\n\n- When NTH receives an ASG lifecycle termination event, it starts sending heartbeats to ASG to renew the heartbeat timeout associated with the ASG's termination lifecycle hook.\n- The heartbeat timeout acts as a timer that starts when the termination event begins.\n- Before the timeout reaches zero, the termination process is halted at the `Terminating:Wait` stage.\n- By issuing heartbeats, graceful termination duration can be extended up to 48 hours, limited by the global timeout.\n\n##### How to use\n\n- Configure a termination lifecycle hook on ASG (required). Set the heartbeat timeout value to be longer than the `Heartbeat Interval`. Each heartbeat signal resets this timeout, extending the duration that an instance remains in the `Terminating:Wait` state. Without this lifecycle hook, the instance will terminate immediately when termination event occurs.\n- Configure `Heartbeat Interval` (required) and `Heartbeat Until` (optional). NTH operates normally without heartbeats if neither value is set. If only the interval is specified, `Heartbeat Until` defaults to 172800 seconds (48 hours) and heartbeats will be sent. `Heartbeat Until` must be provided with a valid `Heartbeat Interval`, otherwise NTH will fail to start. Any invalid values (wrong type or out of range) will also prevent NTH from starting.\n\n##### Configurations\n###### `Heartbeat Interval` (Required)\n- Time period between consecutive heartbeat signals (in seconds)\n- Specifying this value triggers heartbeat\n- Range: 30 to 3600 seconds (30 seconds to 1 hour)\n- Flag for custom resource definition by *.yaml / helm: `heartbeatInterval`\n- CLI flag: `heartbeat-interval`\n- Default value: X\n\n###### `Heartbeat Until` (Optional)\n- Duration over which heartbeat signals are sent (in seconds)\n- Must be provided with a valid `Heartbeat Interval`\n- Range: 60 to 172800 seconds (1 minute to 48 hours)\n- Flag for custom resource definition by *.yaml / helm: `heartbeatUntil`\n- CLI flag: `heartbeat-until`\n- Default value: 172800 (48 hours)\n\n###### Example Case\n\n- `Heartbeat Interval`: 1000 seconds\n- `Heartbeat Until`: 4500 seconds\n- `Heartbeat Timeout`: 3000 seconds \n\n| Time (s) | Event | Heartbeat Timeout (HT) | Heartbeat Until (HU) | Action |\n|----------|-------------|------------------|----------------------|--------|\n| 0        | Start       | 3000            | 4500                  | Termination Event Received |\n| 1000     | HB1 Issued  | 2000 -\u003e 3000    | 3500                  | Send Heartbeat |\n| 2000     | HB2 Issued  | 2000 -\u003e 3000    | 2500                  | Send Heartbeat |\n| 3000     | HB3 Issued  | 2000 -\u003e 3000    | 1500                  | Send Heartbeat |\n| 4000     | HB4 Issued  | 2000 -\u003e 3000    | 500                   | Send Heartbeat |\n| 4500     | HB Expires  | 2500            | 0                     | Stop Heartbeats |\n| 7000     | Termination | -               | -                     | Instance Terminates |\n\nNote: The instance can terminate earlier if its pods finish draining and are ready for termination.\n\n##### Example Helm Command\n\n```sh\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set enableSqsTerminationDraining=true \\\n  --set heartbeatInterval=1000 \\\n  --set heartbeatUntil=4500 \\\n  // other inputs..\n```\n\n##### Important Notes\n\n- Be aware of global timeout. Instances cannot remain in a wait state indefinitely. The global timeout is 48 hours or 100 times the heartbeat timeout, whichever is smaller. This is the maximum amount of time that you can keep an instance in `terminating:wait` state.\n- Lifecycle heartbeats are only supported in Queue Processor mode. Setting `enableSqsTerminationDraining=false` and specifying heartbeat flags is prevented in Helm. Directly editing deployment settings to bypass this will cause NTH to fail.\n- The heartbeat interval should be sufficiently shorter than the heartbeat timeout. There's a time gap between instance startup and NTH initialization. Setting the interval just slightly smaller than or equal to the timeout causes the heartbeat timeout to expire before the first heartbeat is issued. Provide adequate buffer time for NTH to complete initialization.\n- Issuing heartbeats is part of the termination process. The maximum number of instances that NTH can handle termination concurrently is limited by the number of workers. This implies that heartbeats can only be issued for up to the number of instances specified by the `workers` flag simultaneously.\n\n### Which one should I use?\n|                    Feature                    | IMDS Processor | Queue Processor |\n| :-------------------------------------------: | :------------: | :-------------: |\n| Spot Instance Termination Notifications (ITN) |       ✅        |        ✅        |\n|               Scheduled Events                |       ✅        |        ✅        |\n|       Instance Rebalance Recommendation       |       ✅        |        ✅        |\n|        ASG Termination Lifecycle Hooks        |       ❌        |        ✅        |\n|     ASG Termination Lifecycle State Change    |       ✅        |        ❌        |\n|         AZ Rebalance Recommendation           |       ❌        |        ✅        |\n|         Instance State Change Events          |       ❌        |        ✅        |\n|          Issue Lifecycle Heartbeats           |       ❌        |        ✅        |\n\n### Kubernetes Compatibility\n\n|                                      NTH Release                                      | K8s v1.32 | K8s v1.31 | K8s v1.30 | K8s v1.29 | K8s v1.28 | K8s v1.27 | K8s v1.26 | K8s v1.25 |\n| :-----------------------------------------------------------------------------------: | :-------: | :-------: | :-------: | :-------: | :-------: | :-------: | :-------: | :-------: |\n|  [v1.25.5](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.5)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.25.4](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.4)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.25.3](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.3)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.25.2](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.2)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.25.1](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.1)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.25.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.25.0)  |     ✅    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.24.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.24.0)  |     ❌    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.23.1](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.23.1)  |     ❌    |     ✅    |     ✅    |     ✅    |     ❌    |     ❌    |     ❌    |     ❌    |\n|  [v1.23.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.23.0)  |     ❌    |     ❌    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |\n|  [v1.22.1](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.22.1)  |     ❌    |     ❌    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |\n|  [v1.22.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.22.0)  |     ❌    |     ❌    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |\n|  [v1.21.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.21.0)  |     ❌    |     ❌    |     ❌    |     ✅    |     ✅    |     ✅    |     ✅    |     ✅    |\n|  [v1.20.0](https://github.com/aws/aws-node-termination-handler/releases/tag/v1.20.0)  |     ❌    |     ❌    |     ❌    |     ❌    |     ✅    |     ✅    |     ✅    |     ✅    |\n\nA ✅ indicates that a specific aws-node-termination-handler release has been tested with a specific Kubernetes version. A ❌ indicates that a specific aws-node-termination-handler release has not been tested with a specific Kubernetes version.\n\n## Installation and Configuration\n\nThe aws-node-termination-handler can operate in two different modes: IMDS Processor and Queue Processor. The `enableSqsTerminationDraining` helm configuration key or the `ENABLE_SQS_TERMINATION_DRAINING` environment variable are used to enable the Queue Processor mode of operation. If `enableSqsTerminationDraining` is set to true, then IMDS paths will NOT be monitored. If the `enableSqsTerminationDraining` is set to false, then IMDS Processor Mode will be enabled. Queue Processor Mode and IMDS Processor Mode cannot be run at the same time.\n\nIMDS Processor Mode allows for a fine-grained configuration of IMDS paths that are monitored. There are currently 3 paths supported that can be enabled or disabled by using the following helm configuration keys:\n - `enableSpotInterruptionDraining`\n - `enableRebalanceMonitoring`\n - `enableScheduledEventDraining`\n\nBy default, IMDS mode will only Cordon in response to a Rebalance Recommendation event (all other events are Cordoned and Drained). Cordon is the default for a rebalance event because it's not known if an ASG is being utilized and if that ASG is configured to replace the instance on a rebalance event. If you are using an ASG w/ rebalance recommendations enabled, then you can set the `enableRebalanceDraining` flag to true to perform a Cordon and Drain when a rebalance event is received.\n\nRebalance Recommendation is an early indicator to notify the Spot Instances that they can be interrupted soon. Node Termination Handler supports AZ Rebalance Recommendation only in Queue Processor mode using ASG Lifecycle Hooks. For AZ rebalances the instances are just terminated, using Lifecycle Hooks and EventBridge rule for `EC2 Instance-terminate Lifecycle Action` we can handle OD Instances.\n\nThe `enableSqsTerminationDraining` must be set to false for these configuration values to be considered.\n\nThe Queue Processor Mode does not allow for fine-grained configuration of which events are handled through helm configuration keys. Instead, you can modify your Amazon EventBridge rules to not send certain types of events to the SQS Queue so that NTH does not process those events. All events when operating in Queue Processor mode are Cordoned and Drained unless the `cordon-only` flag is set to true.\n\nThe `enableSqsTerminationDraining` flag turns on Queue Processor Mode. When Queue Processor Mode is enabled, IMDS mode will be disabled, even if you explicitly enabled any of the IMDS configuration keys. NTH cannot respond to queue events AND monitor IMDS paths. In this case, it is safe to disable IMDS for the NTH pod.\n\n\u003cdetails opened\u003e\n\u003csummary\u003eAWS Node Termination Handler - IMDS Processor\u003c/summary\u003e\n\u003cbr\u003e\n\n### Installation and Configuration\n\nThe termination handler DaemonSet installs into your cluster a [ServiceAccount](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/), [ClusterRole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/), [ClusterRoleBinding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/), and a [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/). All four of these Kubernetes constructs are required for the termination handler to run properly.\n\n#### Pod Security Admission\n\nWhen using Kubernetes [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) it is recommended to assign the `[privileged](https://kubernetes.io/docs/concepts/security/pod-security-standards/#privileged)` level.\n\n#### Kubectl Apply\n\nYou can use kubectl to directly add all of the above resources with the default configuration into your cluster.\n\n```\nkubectl apply -f https://github.com/aws/aws-node-termination-handler/releases/download/v1.25.5/all-resources.yaml\n```\n\nFor a full list of releases and associated artifacts see our [releases page](https://github.com/aws/aws-node-termination-handler/releases).\n\n#### Helm\n\nThe easiest way to configure the various options of the termination handler is via [helm](https://helm.sh/). The chart for this project is hosted in [helm/aws-node-termination-handler](https://gallery.ecr.aws/aws-ec2/helm/aws-node-termination-handler)\n\nTo get started you need to authenticate your helm client\n\n```\naws ecr-public get-login-password \\\n  --region us-east-1 | helm registry login \\\n  --username AWS \\\n  --password-stdin public.ecr.aws\n```\n\nOnce that is complete you can install the termination handler. We've provided some sample setup options below. Make sure to replace CHART_VERSION with the version you want to install.\n\nZero Config:\n\n```sh\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nEnabling Features:\n\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set enableSpotInterruptionDraining=\"true\" \\\n  --set enableRebalanceMonitoring=\"true\" \\\n  --set enableScheduledEventDraining=\"false\" \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nThe `enable*` configuration flags above enable or disable IMDS monitoring paths.\n\nRunning Only On Specific Nodes:\n\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set nodeSelector.lifecycle=spot \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nWebhook Configuration:\n\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set webhookURL=https://hooks.slack.com/services/YOUR/SLACK/URL \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nAlternatively, pass Webhook URL as a Secret:\n\n```\nWEBHOOKURL_LITERAL=\"webhookurl=https://hooks.slack.com/services/YOUR/SLACK/URL\"\n\nkubectl create secret -n kube-system generic webhooksecret --from-literal=$WEBHOOKURL_LITERAL\n```\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set webhookURLSecretName=webhooksecret \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nFor a full list of configuration options see our [Helm readme](https://github.com/aws/aws-node-termination-handler/blob/v1.25.5/config/helm/aws-node-termination-handler#readme).\n\n\u003c/details\u003e\n\n\n\u003cdetails closed\u003e\n\u003csummary\u003eAWS Node Termination Handler - Queue Processor (requires AWS IAM Permissions)\u003c/summary\u003e\n\n\u003cbr\u003e\n\n### Infrastructure Setup\n\nThe termination handler requires some infrastructure prepared before deploying the application. In a multi-cluster environment, you will need to repeat the following steps for each cluster.\n\nYou'll need the following AWS infrastructure components:\n\n1. Amazon Simple Queue Service (SQS) Queue\n2. AutoScaling Group Termination Lifecycle Hook\n3. Instance Tagging\n4. Amazon EventBridge Rule\n5. IAM Role for the aws-node-termination-handler Queue Processing Pods\n\nOptional AWS infrastructure components:\n1. AutoScaling Group Launch Lifecycle Hook\n\n#### 1. Create an SQS Queue:\n\nHere is the AWS CLI command to create an SQS queue to hold termination events from ASG and EC2, although this should really be configured via your favorite infrastructure-as-code tool like CloudFormation (template [here](docs/cfn-template.yaml)) or Terraform:\n\n```\n## Queue Policy\nQUEUE_POLICY=$(cat \u003c\u003cEOF\n{\n    \"Version\": \"2012-10-17\",\n    \"Id\": \"MyQueuePolicy\",\n    \"Statement\": [{\n        \"Effect\": \"Allow\",\n        \"Principal\": {\n            \"Service\": [\"events.amazonaws.com\", \"sqs.amazonaws.com\"]\n        },\n        \"Action\": \"sqs:SendMessage\",\n        \"Resource\": [\n            \"arn:aws:sqs:${AWS_REGION}:${ACCOUNT_ID}:${SQS_QUEUE_NAME}\"\n        ]\n    }]\n}\nEOF\n)\n\n## make sure the queue policy is valid JSON\necho \"$QUEUE_POLICY\" | jq .\n\n## Save queue attributes to a temp file\ncat \u003c\u003c EOF \u003e /tmp/queue-attributes.json\n{\n  \"MessageRetentionPeriod\": \"300\",\n  \"Policy\": \"$(echo $QUEUE_POLICY | sed 's/\\\"/\\\\\"/g' | tr -d -s '\\n' \" \")\",\n  \"SqsManagedSseEnabled\": \"true\"\n}\nEOF\n\naws sqs create-queue --queue-name \"${SQS_QUEUE_NAME}\" --attributes file:///tmp/queue-attributes.json\n```\n\nIf you are sending Lifecycle termination events from ASG directly to SQS, instead of through EventBridge, then you will also need to create an IAM service role to give Amazon EC2 Auto Scaling access to your SQS queue. Please follow [these linked instructions to create the IAM service role: link.](https://docs.aws.amazon.com/autoscaling/ec2/userguide/configuring-lifecycle-hook-notifications.html#sqs-notifications)\nNote the ARNs for the SQS queue and the associated IAM role for Step 2.\n\nThere are some caveats when using [server side encryption with SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-server-side-encryption.html):\n* using [SSE-KMS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sse-existing-queue.html) with a [customer managed key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-mgmt) requires [changing the KMS key policy](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-troubleshooting.html#eb-sqs-encrypted) to allow EventBridge to publish events to SQS.\n* using [SSE-KMS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sse-existing-queue.html) with an [AWS managed key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-mgmt) is not supported as the KMS key policy can't be updated to allow EventBridge to publish events to SQS.\n* using [SSE-SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-sqs-sse-queue.html) doesn't require extra setup and works out of the box as SQS queues without encryption at rest.\n\n#### 2. Create an ASG Termination Lifecycle Hook:\n\nHere is the AWS CLI command to create a termination lifecycle hook on an existing ASG when using EventBridge, although this should really be configured via your favorite infrastructure-as-code tool like CloudFormation or Terraform:\n\n```\naws autoscaling put-lifecycle-hook \\\n  --lifecycle-hook-name=my-k8s-term-hook \\\n  --auto-scaling-group-name=my-k8s-asg \\\n  --lifecycle-transition=autoscaling:EC2_INSTANCE_TERMINATING \\\n  --default-result=CONTINUE \\\n  --heartbeat-timeout=300\n```\n\nIf you want to avoid using EventBridge and instead send ASG Lifecycle events directly to SQS, instead use the following command, using the ARNs from Step 1:\n\n```\naws autoscaling put-lifecycle-hook \\\n  --lifecycle-hook-name=my-k8s-term-hook \\\n  --auto-scaling-group-name=my-k8s-asg \\\n  --lifecycle-transition=autoscaling:EC2_INSTANCE_TERMINATING \\\n  --default-result=CONTINUE \\\n  --heartbeat-timeout=300 \\\n  --notification-target-arn \u003cyour queue ARN here\u003e \\\n  --role-arn \u003cyour SQS access role ARN here\u003e\n```\n\n#### 3. Tag the Instances:\n\nBy default the aws-node-termination-handler will only manage terminations for instances tagged with `key=aws-node-termination-handler/managed`.\nThe value of the key does not matter.\n\nTo tag ASGs and propagate the tags to your instances (recommended):\n```\naws autoscaling create-or-update-tags \\\n  --tags ResourceId=my-auto-scaling-group,ResourceType=auto-scaling-group,Key=aws-node-termination-handler/managed,Value=,PropagateAtLaunch=true\n```\n\nTo tag an individual EC2 instance:\n```\naws ec2 create-tags \\\n    --resources i-1234567890abcdef0 \\\n    --tags 'Key=\"aws-node-termination-handler/managed\",Value='\n```\n\nTagging your EC2 instances in this way is helpful if you only want aws-node-termination-handler to manage the lifecycle of instances in certain ASGs. For example, if your account also has other ASGs that do not contain Kubernetes nodes, this tagging mechanism will ensure that NTH does not manage the lifecycle of any instances in those non-Kubernetes ASGs.\n\nHowever, if the only ASGs in your account are for your Kubernetes cluster, then you can turn off the tag check by setting the flag `--check-tag-before-draining=false` or environment variable `CHECK_TAG_BEFORE_DRAINING=false`.\n\nYou can also control what resources NTH manages by adding the resource ARNs to your Amazon EventBridge rules.\n\nTake a look at the docs on how to [create rules that only manage certain ASGs](https://docs.aws.amazon.com/autoscaling/ec2/userguide/cloud-watch-events.html), and read about all the [supported ASG events](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-event-reference.html).\n\n#### 4. Create Amazon EventBridge Rules\n\nYou may skip this step if sending events from ASG to SQS directly.\n\nIf we use ASG with capacity-rebalance enabled on ASG, then we do not need Spot and Rebalance events enabled with EventBridge. ASG will send a termination lifecycle hook for spot interrruptions while it's launching a new instance and for Rebalance events ASG will send a termination lifecycle hook after it brings a new node in the ASG.\n\nIf we use ASG without capacity-rebalance enabled, then spot interruptions will cause a termination lifecycle hook after the interruption occurs but not while launching the new instance.\n\nHere are AWS CLI commands to create Amazon EventBridge rules so that ASG termination events, Spot Interruptions, Instance state changes, Rebalance Recommendations, and AWS Health Scheduled Changes are sent to the SQS queue created in the previous step. This should really be configured via your favorite infrastructure-as-code tool like CloudFormation (template [here](docs/cfn-template.yaml)) or Terraform:\n\n```\naws events put-rule \\\n  --name MyK8sASGTermRule \\\n  --event-pattern \"{\\\"source\\\":[\\\"aws.autoscaling\\\"],\\\"detail-type\\\":[\\\"EC2 Instance-terminate Lifecycle Action\\\"]}\"\n\naws events put-targets --rule MyK8sASGTermRule \\\n  --targets \"Id\"=\"1\",\"Arn\"=\"arn:aws:sqs:us-east-1:123456789012:MyK8sTermQueue\"\n\naws events put-rule \\\n  --name MyK8sSpotTermRule \\\n  --event-pattern \"{\\\"source\\\": [\\\"aws.ec2\\\"],\\\"detail-type\\\": [\\\"EC2 Spot Instance Interruption Warning\\\"]}\"\n\naws events put-targets --rule MyK8sSpotTermRule \\\n  --targets \"Id\"=\"1\",\"Arn\"=\"arn:aws:sqs:us-east-1:123456789012:MyK8sTermQueue\"\n\naws events put-rule \\\n  --name MyK8sRebalanceRule \\\n  --event-pattern \"{\\\"source\\\": [\\\"aws.ec2\\\"],\\\"detail-type\\\": [\\\"EC2 Instance Rebalance Recommendation\\\"]}\"\n\naws events put-targets --rule MyK8sRebalanceRule \\\n  --targets \"Id\"=\"1\",\"Arn\"=\"arn:aws:sqs:us-east-1:123456789012:MyK8sTermQueue\"\n\naws events put-rule \\\n  --name MyK8sInstanceStateChangeRule \\\n  --event-pattern \"{\\\"source\\\": [\\\"aws.ec2\\\"],\\\"detail-type\\\": [\\\"EC2 Instance State-change Notification\\\"]}\"\n\naws events put-targets --rule MyK8sInstanceStateChangeRule \\\n  --targets \"Id\"=\"1\",\"Arn\"=\"arn:aws:sqs:us-east-1:123456789012:MyK8sTermQueue\"\n\naws events put-rule \\\n  --name MyK8sScheduledChangeRule \\\n  --event-pattern \"{\\\"source\\\": [\\\"aws.health\\\"],\\\"detail-type\\\": [\\\"AWS Health Event\\\"],\\\"detail\\\": {\\\"service\\\": [\\\"EC2\\\"],\\\"eventTypeCategory\\\": [\\\"scheduledChange\\\"]}}\"\n\naws events put-targets --rule MyK8sScheduledChangeRule \\\n  --targets \"Id\"=\"1\",\"Arn\"=\"arn:aws:sqs:us-east-1:123456789012:MyK8sTermQueue\"\n```\n\n#### 5. Create an IAM Role for the Pods\n\nThere are many different ways to allow the aws-node-termination-handler pods to assume a role:\n\n1. [Amazon EKS IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)\n2. [IAM Instance Profiles for EC2](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)\n3. [Kiam](https://github.com/uswitch/kiam)\n4. [kube2iam](https://github.com/jtblin/kube2iam)\n\nIAM Policy for aws-node-termination-handler Deployment:\n\n```\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"autoscaling:CompleteLifecycleAction\",\n                \"autoscaling:DescribeAutoScalingInstances\",\n                \"autoscaling:DescribeTags\",\n                \"ec2:DescribeInstances\",\n                \"sqs:DeleteMessage\",\n                \"sqs:ReceiveMessage\"\n            ],\n            \"Resource\": \"*\"\n        }\n    ]\n}\n```\n\n#### 1. Handle ASG Instance Launch Lifecycle Notifications (optional):\n\nNTH can monitor for new instances launched by an ASG and notify the ASG when the instance is available in the EKS cluster.\n\nNTH will need to receive notifications of new instance launches within the ASG.  We can add a lifecycle hook to the ASG that will send instance launch notifications via EventBridge:\n\n```\naws autoscaling put-lifecycle-hook \\\n  --lifecycle-hook-name=my-k8s-launch-hook \\\n  --auto-scaling-group-name=my-k8s-asg \\\n  --lifecycle-transition=autoscaling:EC2_INSTANCE_LAUNCHING \\\n  --default-result=\"ABANDON\" \\\n  --heartbeat-timeout=300\n```\n\nAlternatively, ASG can send the instance launch notification directly to an SQS Queue:\n\n```\naws autoscaling put-lifecycle-hook \\\n  --lifecycle-hook-name=my-k8s-launch-hook \\\n  --auto-scaling-group-name=my-k8s-asg \\\n  --lifecycle-transition=autoscaling:EC2_INSTANCE_LAUNCHING \\\n  --default-result=\"ABANDON\" \\\n  --heartbeat-timeout=300 \\\n  --notification-target-arn \u003cyour queue ARN here\u003e \\\n  --role-arn \u003cyour SQS access role ARN here\u003e\n```    \n\nWhen NTH receives a launch notification, it will periodically check for a node backed by the EC2 instance to join the cluster and for the node to have a status of 'ready.' Once a node becomes ready, NTH will complete the lifecycle hook, prompting the ASG to proceed with terminating the previous instance. If the lifecycle hook is not completed before the timeout, the ASG will take the default action. If the default action is 'ABANDON', the new instance will be terminated, and the notification process will be repeated with another new instance.\n\n### Installation\n\n#### Pod Security Admission\n\nWhen using Kubernetes [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) it is recommended to assign the `[baseline](https://kubernetes.io/docs/concepts/security/pod-security-standards/#baseline)` level.\n\n#### Helm\n\nThe easiest way to configure the various options of the termination handler is via [helm](https://helm.sh/). The chart for this project is hosted in [helm/aws-node-termination-handler](https://gallery.ecr.aws/aws-ec2/helm/aws-node-termination-handler)\n\nTo get started you need to authenticate your helm client\n\n```\naws ecr-public get-login-password \\\n     --region us-east-1 | helm registry login \\\n     --username AWS \\\n     --password-stdin public.ecr.aws\n```\n\nOnce that is complete you can install the termination handler. We've provided some sample setup options below. Make sure to replace CHART_VERSION with the version you want to install.\n\nMinimal Config:\n\n```sh\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set enableSqsTerminationDraining=true \\\n  --set queueURL=https://sqs.us-east-1.amazonaws.com/0123456789/my-term-queue \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nWebhook Configuration:\n\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set enableSqsTerminationDraining=true \\\n  --set queueURL=https://sqs.us-east-1.amazonaws.com/0123456789/my-term-queue \\\n  --set webhookURL=https://hooks.slack.com/services/YOUR/SLACK/URL \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nAlternatively, pass Webhook URL as a Secret:\n\n```\nWEBHOOKURL_LITERAL=\"webhookurl=https://hooks.slack.com/services/YOUR/SLACK/URL\"\n\nkubectl create secret -n kube-system generic webhooksecret --from-literal=$WEBHOOKURL_LITERAL\n```\n```\nhelm upgrade --install aws-node-termination-handler \\\n  --namespace kube-system \\\n  --set enableSqsTerminationDraining=true \\\n  --set queueURL=https://sqs.us-east-1.amazonaws.com/0123456789/my-term-queue \\\n  --set webhookURLSecretName=webhooksecret \\\n  oci://public.ecr.aws/aws-ec2/helm/aws-node-termination-handler --version $CHART_VERSION\n```\n\nFor a full list of configuration options see our [Helm readme](https://github.com/aws/aws-node-termination-handler/blob/v1.25.5/config/helm/aws-node-termination-handler#readme).\n\n#### Single Instance vs Multiple Replicas\n\nThe Helm chart, by default, will deploy a single instance of Amazon Node Termination Handler. With the minimizing of resource usage, a single instance still provides good responsiveness in processing SQS messages.\n\n**When should multiple instances of Amazon Node Termination Handler be used?**\n\n* Responsiveness: Amazon Node Termination Handler may be taking longer than desired to process certain events, potentially in processing numerous concurrent events or taking too long to drain Pods. The deployment of multiple Amazon Node Termination Handler instances may help.\n\n* Availability: The deployment of multiple Amazon Node Termination Handler instances provides mitigation in the case that Amazon Node Termination Handler itself is drained. Replica Amazon Node Termination Handlers will process SQS messages, avoiding a delay until the Deployment can start another instance. \n\n**Notes**\n\n* Running multiple instances of Amazon Node Termination Handler will not load balance responding to events. Each instance will greedily consume and respond to events.\n* Logs from multiple instances of Amazon Node Termination Handler are not aggregated.\n* Multiple instances of Amazon Node Termination Handler may respond to the same event, if it takes longer than 20s to process. This is not an error case, only the first response will have an affect.\n\n#### Kubectl Apply\n\nQueue Processor needs an **SQS queue URL** to function; therefore, manifest changes are **REQUIRED** before using kubectl to directly add all of the above resources into your cluster.\n\nMinimal Config:\n\n```\ncurl -L https://github.com/aws/aws-node-termination-handler/releases/download/v1.25.5/all-resources-queue-processor.yaml -o all-resources-queue-processor.yaml\n\u003copen all-resources-queue-processor.yaml and update QUEUE_URL value\u003e\nkubectl apply -f ./all-resources-queue-processor.yaml\n```\n\nFor a full list of releases and associated artifacts see our [releases page](https://github.com/aws/aws-node-termination-handler/releases).\n\n\u003c/details\u003e\n\n\n\u003cdetails close\u003e\n\u003csummary\u003eUse with Kiam\u003c/summary\u003e\n\u003cbr\u003e\n\n## Use with Kiam\n\nIf you are using IMDS mode which defaults to `hostNetworking: true`, or if you are using queue-processor mode, then this section does not apply. The configuration below only needs to be used if you are explicitly changing NTH IMDS mode to `hostNetworking: false` .\n\nTo use the termination handler alongside [Kiam](https://github.com/uswitch/kiam) requires some extra configuration on Kiam's end.\nBy default Kiam will block all access to the metadata address, so you need to make sure it passes through the requests the termination handler relies on.\n\nTo add a whitelist configuration, use the following fields in the Kiam Helm chart values:\n\n```\nagent.whiteListRouteRegexp: '^\\/latest\\/meta-data\\/(spot\\/instance-action|events\\/maintenance\\/scheduled|instance-(id|type)|public-(hostname|ipv4)|local-(hostname|ipv4)|placement\\/availability-zone)|\\/latest\\/dynamic\\/instance-identity\\/document$'\n```\nOr just pass it as an argument to the kiam agents:\n\n```\nkiam agent --whitelist-route-regexp='^\\/latest\\/meta-data\\/(spot\\/instance-action|events\\/maintenance\\/scheduled|instance-(id|type)|public-(hostname|ipv4)|local-(hostname|ipv4)|placement\\/availability-zone)|\\/latest\\/dynamic\\/instance-identity\\/document$'\n```\n\n## Metadata endpoints\nThe termination handler relies on the following metadata endpoints to function properly:\n\n```\n/latest/dynamic/instance-identity/document\n/latest/meta-data/spot/instance-action\n/latest/meta-data/events/recommendations/rebalance\n/latest/meta-data/events/maintenance/scheduled\n/latest/meta-data/instance-id\n/latest/meta-data/instance-life-cycle\n/latest/meta-data/instance-type\n/latest/meta-data/public-hostname\n/latest/meta-data/public-ipv4\n/latest/meta-data/local-hostname\n/latest/meta-data/local-ipv4\n/latest/meta-data/placement/availability-zone\n```\n\n\u003c/details\u003e\n\n## Building\nFor build instructions please consult [BUILD.md](./BUILD.md).\n\n## Metrics\nAvailable Prometheus metrics:\n\n| Metric name    | Description                                                        |                              \n| -------------- | -------------------------------------------------------------------|\n| `actions`      | Number of actions                                                  |\n| `actions_node` | Number of actions per node (Deprecated: Use actions metric instead)|\n| `events_error` | Number of errors in events processing                              |\n\nThe method of collecting Prometheus metrics changes depending on whether NTH is running in IMDS mode or Queue mode.\n\n\u003e [!WARNING]\n\u003e Both `serviceMonitor` and `podMonitor` are custom resources provided by the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) for seamless integration with Kubernetes services and pods. For more details, please refer to [the API reference docs](https://prometheus-operator.dev/docs/api-reference/api/) for the Prometheus Operator.\n\nIn Queue mode, metrics can be collected in two ways:\n- Use a `serviceMonitor` custom resource with the Prometheus Operator to collect metrics.\n- Alternatively, add aws-node-termination-handler service address statically in Prometheus `scrape_configs`.\n\nExample `scrape_configs` in prometheus helm chart:\n```yaml\n# charts/prometheus/values.yaml\n# See: https://github.com/prometheus-community/helm-charts/blob/main/charts/prometheus/values.yaml\nextraScrapeConfigs: |\n  - job_name: 'aws-node-termination-handler'\n    static_configs:\n      - targets:\n          - 'aws-node-termination-handler.kube-system.svc.cluster.local:9092'\n```\n\nIn IMDS mode, metrics can be collected as follows:\n- Use a `podMonitor` custom resource with the Prometheus Operator to collect metrics.\n\n## Communication\n* If you've run into a bug or have a new feature request, please open an [issue](https://github.com/aws/aws-node-termination-handler/issues/new).\n* You can also chat with us in the [Kubernetes Slack](https://kubernetes.slack.com) in the `#provider-aws` channel\n* Check out the open source [Amazon EC2 Spot Instances Integrations Roadmap](https://github.com/aws/ec2-spot-instances-integrations-roadmap) to see what we're working on and give us feedback!\n\n##  Contributing\nContributions are welcome! Please read our [guidelines](https://github.com/aws/aws-node-termination-handler/blob/main/CONTRIBUTING.md) and our [Code of Conduct](https://github.com/aws/aws-node-termination-handler/blob/main/CODE_OF_CONDUCT.md)\n\n## License\nThis project is licensed under the Apache-2.0 License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws%2Faws-node-termination-handler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faws%2Faws-node-termination-handler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faws%2Faws-node-termination-handler/lists"}