Fedora Linux 45 released

Post Syndicated from jzb original https://lwn.net/Articles/1105121/

Fedora Linux
45
has been released. This includes all editions: Fedora Workstation, Fedora KDE Plasma Desktop, Fedora Server, Fedora Cloud, Fedora CoreOS, and Fedora IoT, as well as the Atomic Desktops and Spins.

This release adds support for installation
on Stratis storage
using Anaconda or Kickstart installs, retires
unmaintained VPN plugins
for NetworkManager, and updates Fedora’s desktop
environments, developer toolchains, and system packages. See the Fedora wiki
ChangeSet page
for a list of major changes.

Security updates for Tuesday

Post Syndicated from jzb original https://lwn.net/Articles/1105111/

Security updates have been issued by AlmaLinux (bind, bind9.16, firefox, freerdp, ghostscript, kernel, kernel-rt, libXi, perl-YAML:1.24, perl:5.32, pipewire, qt5-qtbase, redis:6, tomcat, and wireshark), Debian (chromium, git-annex, incus, kernel, and strongswan), Fedora (barman, erlang-hex_core, glib-networking, kernel, knot, liblerc, libsoup3, mingw-cfitsio, openjpeg, perl-libnet, pipx, python-pillow, python-uv-build, radicale, ruff, rust-archive-trait, rust-astral-ini, rust-astral-mail-headers, rust-astral-pubgrub, rust-astral-version-ranges, rust-astral_async_zip, rust-quick-junit, rust-tar-codec, rust-tar-framing, tpm2-tss, ty, uv, and zvbi), Mageia (unbound), Red Hat (buildah, compat-openssl10, compat-openssl11, container-tools:rhel8, delve, golang-github-openprinting-ipp-usb, grafana, grafana-pcp, kernel, oci-seccomp-bpf-hook, openssl, opentelemetry-collector, osbuild-composer, podman, rhc, and skopeo), Slackware (expat), SUSE (ansible-core, apache-arrow, apache-commons-codec, apache-commons-io, apache-commons- logging, avalon-framework, avalon-logkit, glassfish-jsp, jsch, maven-file- management, opentest4j, aws-nitro-enclaves-cli, bouncycastle, chromedriver, chromium, cifs-utils, expat, firefox, gcc48, ghostscript, GraphicsMagick, guava, j2objc-annotations, gvfs, ImageMagick, in-toto, libsoup, nodejs22, nodejs24, praat, python-Pillow, python-PyJWT, python-soupsieve, python-sqlparse, python313-OpenEXR, python313-vllm, rootlesskit, and rqlite), and Ubuntu (kernel, linux, linux-aws, linux-aws-5.15, linux-aws-fips, linux-azure, linux-azure-5.15, linux-azure-fde-5.15, linux-azure-fips, linux-fips, linux-gcp, linux-gcp-5.15, linux-gcp-fips, linux-gke, linux-gkeop, linux-hwe-5.15, linux-ibm, linux-ibm-5.15, linux-intel-iot-realtime, linux-intel-iotg, linux-intel-iotg-5.15, linux-kvm, linux-lowlatency, linux-lowlatency-hwe-5.15, linux-nvidia, linux-oracle, linux-oracle-5.15, linux-realtime, linux, linux-aws, linux-aws-fips, linux-azure, linux-azure-5.4, linux-azure-fips, linux-fips, linux-gcp, linux-gcp-5.4, linux-gcp-fips, linux-hwe-5.4, linux-ibm, linux-ibm-5.4, linux-iot, linux-kvm, linux-oracle, linux-oracle-5.4, linux-xilinx-zynqmp, linux, linux-aws, linux-fips, linux-kvm, linux-lts-xenial, linux, linux-aws, linux-gcp, linux-hwe-7.0, linux-ibm, linux-oracle, linux-aws, linux-azure-fde, linux-bluefield, linux-nvidia-tegra, linux-nvidia-tegra-5.15, linux-nvidia-tegra-igx, and linux-oem-7.0).

Introducing Zero Wire, a hub for investigating critical Internet vulnerabilities

Post Syndicated from Daniele Molteni original https://blog.cloudflare.com/zero-wire/

You run security at your organization. It’s 7:00 am, and you’re having breakfast. You receive a ping: a new critical vulnerability has been disclosed. Your team scrambles to compare vendor advisories, read technical research, check which systems run the affected software, and answer familiar questions from the business: are we affected, and what are we doing about it? Another disclosure arrives before that work is finished.

AI is changing both the volume and speed of critical vulnerability discovery. It can analyze large codebases at scale and surface deeply nested flaws that may have existed for years without being found through human review. That discovery momentum will put more pressure on security teams to understand the impact of each disclosure on their infrastructure.

To help security teams prepare, today we’re introducing Zero Wire: a public vulnerability intelligence feed on Cloudflare Radar, bringing the clarity of a news wire service to critical security developments. It helps security leaders and practitioners understand significant vulnerabilities and decide what to do next.

How it works

Zero Wire lives inside Cloudflare Radar under the security section.

Each briefing brings together a plain-language explanation of the vulnerability, who should investigate it, recommended actions, and links to the evidence and vendor guidance. The format is deliberately simple: an index card with what you need to know, without the drama. A CISO should be able to understand the issue quickly and ask the right questions. An engineer should be able to follow the same briefing to the technical guidance needed to investigate and remediate it.

We also offer a pre-compiled prompt you can use with your agent to assess the impact on your infrastructure. Cloudflare contributes security research, observations from our network, and practical knowledge of the controls that can help reduce exposure. The information is useful whether or not you are a Cloudflare customer. 

Zero Wire brings that context together with authoritative external sources, giving readers a starting point for assessment and a place to return as an issue develops.

Our focus

Rather than a catalog of every CVE, Zero Wire complements vendor advisories and vulnerability databases, linking readers to the evidence and technical guidance needed to act. Zero Wire focuses on critical CVEs in Internet-facing software, such as vulnerabilities in web applications, the runtimes and libraries they depend on, and services exposed to the Internet, where a proxy can help mitigate exploitation.

We select significant issues that security teams need to understand and assess. Each briefing explains the potential impact, which deployments should be investigated, what is known about exploitation, and the available mitigation and patching guidance. A vulnerability’s severity and evidence of active exploitation are distinct: readers need both to make informed decisions.

A dedicated Cloudflare protection, such as Web Application Firewall (WAF) rules, is not a prerequisite for inclusion. Some issues require vendor updates or changes beyond the traffic Cloudflare can inspect. Where Cloudflare controls can help, we explain their scope and configuration requirements.

A walk through Zero Wire

Start on the Zero Wire homepage. Each card introduces an issue, identifies associated CVEs where applicable, and summarizes why it matters and what to do. You can search for a published briefing using a CVE or issue name, and follow technology tags to related entries. One briefing can cover several related CVEs when understanding them together makes the response clearer.

Find what needs attention

The homepage separates briefings into two categories. “Needs attention” brings together issues requiring active assessment or action, including those with known exploitation or developing guidance. “Reference” keeps briefings available when guidance has stabilized. Moving to “Reference” does not mean every affected system has been patched: an older vulnerability can still matter to an organization that has not completed remediation.

The status and last-checked date help you interpret each card. Known exploitation, an ongoing investigation, and an available vendor fix describe different things. Read them alongside the briefing’s evidence rather than treating them as a verdict on your own environment.

Understand what happened and who should investigate

When you open a briefing, the overview tells you what happened, why it deserves attention, and which teams should investigate. The explanation connects the technical issue to its practical consequences, such as service disruption or risk of data exposure.

For example, the recent php2shell vulnerability concerns flaws in the PHP runtime. That distinction matters for teams running applications such as WordPress or Magento: updating application code or a plugin alone does not repair the underlying runtime. The briefing helps readers identify the right system owners and directs them to the PHP security guidance for affected versions and remediation.

Turn the briefing into an action plan

What to do now gives your team a short set of next steps. Depending on the issue, that can mean identifying affected deployments, checking versions with a hosting provider, applying vendor updates, reviewing suspicious activity, or keeping compensating controls in place while patching.

The purpose is to make the next conversation concrete. For a PHP deployment, ask which runtime is actually running, whether the vendor’s fix has been applied, and who owns the update. Follow the linked vendor advisory for detailed applicability and remediation instructions, which can change as the investigation develops.

Assess your exposure with an AI agent

In this section, we share a prompt that can be used with your AI agent to quickly assess the impact on your infrastructure. The prompt asks for a read-only assessment of deployed software, relevant vendor fixes, exposure, and compensating controls, with per-asset evidence, unknowns, and next actions. It helps your team investigate its own environment; copying the prompt does not itself scan or change systems.

Check the evidence and follow what changed

To help you learn more about the vulnerability, each briefing links to external documents such as CVE records, research, and relevant exploitation evidence, including CISA’s Known Exploited Vulnerabilities Catalog. These sources answer different questions. A vendor advisory establishes affected versions and remediation guidance. An exploitation report provides evidence of attacker activity. 

If applicable to a briefing, Cloudflare can add context about traffic seen on our network, for example by showing traffic matching WAF rules that indicates exploitation attempts. Those distinctions matter. Observing an attack attempt does not establish that a particular organization was compromised. Equally, a lack of observed attempts on Cloudflare’s network does not establish that exploitation is absent elsewhere. Briefings distinguish what the sources establish from what remains unknown.

Where available, charts add context to that evidence. The php2shell briefing shows the volume of HTTP requests matching Cloudflare WAF managed rules over time. Note that requests matching these rules are not a count of compromised systems or successful exploits; the chart aims at providing practitioners a sense of what the focus level is by threat actors on a particular vulnerability.

Finally, update chronology records important developments, such as new advisories or changes to the evidence and response guidance. Together with the last-checked date, it helps returning readers understand what has changed since their previous visit.

Understand Cloudflare’s role

The Cloudflare section provides links to whether we offer compensating controls or provide a way to mitigate the vulnerability impact on your infrastructure. 

If a particular CVE can be addressed with a WAF rule, the briefing reports its availability and essential configuration requirements. When applicable, paid Plans and free Plans links take customers to the relevant dashboard configuration. The next step is explicit: “Review your WAF configuration to determine whether you are protected”. A link allows you to review your security posture, it does not automatically enable a rule or verify a deployment.

Note that a WAF mitigation is a compensating control for the traffic it covers, it is not a replacement for fixing vulnerable software. Blocking the requests can prevent exposed data from reaching an attacker, but it cannot undo actions already performed at the origin. The security teams should always follow the vendor remediation guidance.

Stay informed with Zero Wire

A useful vulnerability briefing should leave you with a clearer understanding of the issue and a concrete next step. Day Zero brings those essentials together: what happened, who should investigate, what to do now, and where to find the evidence.

Visit Zero Wire vulnerability intelligence, share the relevant briefings with the teams responsible for your systems, and return for new entries and updates. When the next disclosure arrives, we want you to spend less time assembling the basic facts and more time acting on them.

Follow Cloudflare Radar on X @CloudflareRadar and Bluesky @radar.cloudflare.com for updates.

AIs Hacking the Law

Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2026/11/ais-hacking-the-law.html

In both a 2021 essay and my 2022 book, A Hacker’s Mind, I talk about AIs finding vulnerabilities and exploits—hacking—the legal system.

Here’s some demonstrations of this from Germany:

Legal systems encode the foundations of social order in natural language. Similar to computer systems, the written law can contain vulnerabilities that invite exploitation.1 Courts absorb most exploits through interpretation, and such vulnerabilities rarely surface in the first place. With highly capable AI systems enabling the discovery of vulnerabilities at unprecedented scale, we believe the latter could change.

In testing this hypothesis, we have identified a substantial number of vulnerabilities in the German legal system using LLMs. To our knowledge, none of these have been previously recorded. We share a selection of vulnerabilities below, and present potential exploits for each. We share only those vulnerabilities whose exploitation we believe would not cause serious harm.

We believe that with cheap legal reasoning proliferating, AI systems could jeopardize the functioning of today’s legal systems. In such a world, lawmakers would need to significantly harden the process of legislation, for example by leveraging advanced AI themselves.

Still in its early stages, but definitely something that’s coming.

Бомбоубежища за 1%

Post Syndicated from Александър Малинов original https://www.toest.bg/bomboubezhishta-za-1-procent/

Бомбоубежища за 1%

България не е във война, поне официално. Липсата на формално обявена война обаче не пречи на Русия вече почти пет години да убива цивилни и да разрушава градове и села в Украйна. От години насам България като важна част от обединена Европа и НАТО също е жертва на руска агресия под формата на информационна война, саботажи и политическа намеса. През октомври 2026 г. това се промени, след като Русия засили военния си натиск върху България. 

На 6, 13 и 28 октомври близо до българския бряг няколко търговски кораба бяха ударени от руски дронове, а над 20 души от екипажите им загинаха. България ще се сблъсква с все повече преки военни заплахи и инциденти, а междувременно инфраструктурата ни за гражданска защита остава критично неподготвена. В това отношение се вижда рязък контраст с други европейски държави, които активно подготвят населението си за действие по време на криза, включително и война.

Как е в Европа?

В отговор на ескалиращата руска агресия срещу Европа много държави предприеха спешни мерки – от обновяване на укритията до масово разпространение на ръководства за оцеляване за всяко домакинство.

В Полша подготовката на гражданското общество премина от формални административни прегледи към мащабна трансформация. Страната прие фундаментални законодателни промени, задължаващи строителния сектор и частните инвеститори да интегрират защитни съоръжения и подземни бункери в нови обществени и многофамилни сгради. Чрез националната програма за защита на населението и гражданска отбрана Варшава задели милиарди злоти за реновиране на съществуващи укрития и изграждане на нови пространства за сигурност, а финансовите параметри на тези проекти достигат мащаби от десетки милиарди евро за следващия петгодишен цикъл. 

Полските власти не просто инспектират мазета и подземни паркинги, а създават национална мрежа от самостоятелни убежища със системи за филтровентилация, водоснабдяване и електрозахранване и развиват система за ранно предупреждение при ракетен и дронов удар.

Подобни действия се наблюдават и в балтийските страни – Естония, Латвия и Литва, чиито правителства третират гражданската отбрана като пряко продължение на военната си доктрина. Латвия започна мащабни инициативи, подкрепени с милионни европейски и общински инвестиции, за трансформиране на хиляди сгради в защитни убежища (само в столицата Рига се разработват проекти за сигурност на десетки хиляди граждани). 

Литва и Естония от своя страна залагат на тотална децентрализация на информацията: стотици хиляди домакинства преди време получиха директно в домовете си специализирани ръководства за оцеляване в условия на криза, обсада или окупация, съдържащи детайлни инструкции за поведение при военен конфликт и съпротива. 

Брошурата, раздадена на населението на Литва, информира, че граждани, попаднали под чужда окупация, имат право да извършват саботажи срещу окупационните сили и че 

при настъпила окупация всяка информация за капитулиране на литовските сили би била фалшива. 

Швеция, Норвегия и Дания разпространиха обновени брошури за гражданите с ясни инструкции при военен конфликт. В шведското ръководство за оцеляване категорично се заявява: 

Ако Швеция бъде нападната, никога няма да се предадем.

По подобие на страните от Северна Европа, през миналата година Чехия раздаде над 5 млн. брошури, които стигнаха до всяко домакинство, и пусна специален уебсайт с инструкции за оцеляване през първите 72 часа на криза, включваща прекъсване на електричеството, интернет и останалите комуникации.

Породената от руската агресия срещу Украйна активна подготовка на населението за оцеляване в криза е приоритет не само за Източна Европа. В западната част на континента държавните власти също обновиха готовността си – както що се отнася до скривалища и бомбоубежища, така и по отношение на комуникацията с населението. 

Германия предприе спешна реформа в своята политика за сигурност, започвайки изпълнението на дългосрочен план на стойност милиарди евро за преоборудване и адаптация на съществуващата подземна инфраструктура. Берлин съсредоточава усилията си върху спешни ремонти на бункери от Студената война и трансформирането на метростанции, подземни тунели и паркинги, мазета в надеждни защитни пространства, които могат да служат за скривалища. В допълнение федералните власти активно модернизират националната мрежа за ранно предупреждение на гражданите.

Нидерландия, Франция и Белгия залагат на превантивната информираност и масовото ангажиране на самите граждани. В Нидерландия например правителството започна мащабна национална кампания чрез изпращане на специални ръководства на милиони домакинства, даващи ясни указания как всяко семейство да състави собствен план за действие и да подготви тридневни запаси от вода, консерви, медикаменти и алтернативни източници на светлина и топлина. Подобни инициативи бяха реализирани и от френските и белгийските власти през националните кризисни центрове с цел повишаване на устойчивостта срещу хибридни атаки, киберзаплахи и мащабни прекъсвания на комуникациите.


/* ———- ОБЩО за всички инфографики (.tst-ig) ———- */
.tst-ig,
.tst-ig * {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
text-transform: none;
letter-spacing: 0;
text-decoration: none;
text-indent: 0;
}
.tst-ig {
–tst-ink: #000;
–tst-white: #fff;
–tst-shape: #e8e8e8; /* сивото на картите и на „празните” кръгчета */
–tst-radius: 20px;
–tst-accent: #D92B36; /* акцентът на Тоест (цветът на точките и на запълнените кръгчета) */
display: block;
width: 100%;
margin: 24px 0;
padding: 8px 0;
color: var(–tst-ink);
font-weight: 700;
font-style: normal;
font-size: 15px;
line-height: 1.3;
text-align: left;
overflow: visible;
}
.tst-ig-title { display: block; text-align: center; margin-bottom: 24px; }

/* =====================================================================================
КАРТА НА ЕВРОПА (.tst-map) — кликаш държава → излиза балонче с текст
===================================================================================== */
.tst-map {
–tst-map-idle: #ee9aa0; /* кликаемите държави — по-бледо червено */
–tst-map-hover: #e56a73;
}
.tst-map-hint { margin: -12px 0 14px; text-align: center; font-weight: 500; font-size: 13px; }
.tst-map-texts { display: none; } /* текстовете се четат от скрипта и излизат в балончето */
.tst-map-stage { position: relative; max-width: 760px; margin: 0 auto; }
.tst-map-svg { display: block; width: 100%; height: auto; }
.tst-map-bg { fill: var(–tst-shape); stroke: #fff; stroke-width: 1; stroke-linejoin: round; fill-rule: evenodd; }
.tst-map-c path {
fill: var(–tst-map-idle);
stroke: #fff;
stroke-width: 1;
stroke-linejoin: round;
cursor: pointer;
transition: fill 0.2s;
}
@media (hover: hover) { .tst-map-c:hover path { fill: var(–tst-map-hover); } }
.tst-map-c.is-active path { fill: var(–tst-accent); }
.tst-map-c:focus { outline: none; }
.tst-map-c:focus-visible path { stroke: var(–tst-ink); stroke-width: 2; }

.tst-map-bubble {
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 290px;
max-width: calc(100% – 16px);
padding: 16px 18px 18px;
background: var(–tst-white);
border-radius: 18px;
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.15);
pointer-events: none;
}
.tst-map-bubble[hidden] { display: none; }
.tst-map-name { font-size: 17px; line-height: 1.2; }
.tst-map-body { margin-top: 8px; font-weight: 500; font-size: 15px; line-height: 1.4; }
.tst-map-tail {
position: absolute;
bottom: -7px;
left: 20px;
width: 16px;
height: 16px;
background: var(–tst-white);
transform: rotate(45deg);
border-radius: 0 0 3px 0;
}
.tst-map-bubble.is-below .tst-map-tail { bottom: auto; top: -7px; border-radius: 3px 0 0 0; }

.tst-map.is-armed:not(.is-done) .tst-map-bg,
.tst-map.is-armed:not(.is-done) .tst-map-c { opacity: 0; }

/* =====================================================================================
ФИНЛАНДИЯ СРЕЩУ БЪЛГАРИЯ (.tst-fin) — по 100 кръгчета (1 кръгче = 1% от населението)
===================================================================================== */
.tst-fin { –tst-fin-d: 20px; –tst-fin-gap: 6px; }
.tst-fin-parts { display: flex; flex-wrap: wrap; justify-content: center; gap: 40px 64px; }
.tst-fin-part { width: calc(var(–tst-fin-d) * 10 + var(–tst-fin-gap) * 9); max-width: 100%; }
.tst-fin-top { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 16px; }
.tst-fin-country { font-size: 18px; }
.tst-fin-num { font-size: 42px; line-height: 1; }
.tst-fin-grid {
display: grid;
grid-template-columns: repeat(10, var(–tst-fin-d));
gap: var(–tst-fin-gap);
}
.tst-fin-dot {
position: relative;
width: var(–tst-fin-d);
height: var(–tst-fin-d);
border-radius: 50%;
background: var(–tst-shape);
overflow: hidden;
}
.tst-fin-glow { /* цветната част; JS я добавя във всяко „пълно” кръгче */
position: absolute;
left: 0; top: 0; bottom: 0;
width: var(–tst-fin-p, 100%); /* при частично кръгче (напр. 0,5) е по-тясна */
background: var(–tst-accent);
}
.tst-fin-note { margin-top: 16px; font-weight: 500; font-size: 15px; line-height: 1.4; }
.tst-fin-legend { margin-top: 28px; text-align: center; font-weight: 500; font-size: 13px; }

.tst-fin-part.is-armed:not(.is-done) .tst-fin-dot { opacity: 0; }
.tst-fin-part.is-armed:not(.is-done) .tst-fin-glow { clip-path: inset(0 100% 0 0); }
.tst-fin-part.is-armed:not(.is-done) .tst-fin-country,
.tst-fin-part.is-armed:not(.is-done) .tst-fin-num { clip-path: inset(0 100% 0 0); }
.tst-fin-part.is-armed:not(.is-done) .tst-fin-note { opacity: 0; }


<!– =====================================================================================
[B] КАРТА НА ЕВРОПА — как се подготвя Европа
Копирай от тук до „КРАЙ КАРТА".
РЕДАКТИРАШ САМО текстовете в блока „ТЕКСТОВЕ" (име и текст на всяка държава/група).
Блокът с картата () НЕ СЕ ПИПА. data-group в двата блока трябва да съвпада.
Групите се оцветяват заедно: Естония+Латвия+Литва, Швеция+Норвегия+Дания, Нидерландия+Франция+Белгия.
===================================================================================== –>

Как се подготвя Европа
Натисни върху държава

Полша
Нови обществени и многофамилни сгради задължително се строят с убежища. Милиарди злоти за обновяване и нови укрития.

Естония, Латвия, Литва
Ръководства за оцеляване в стотици хиляди домакинства. В Латвия хиляди сгради стават убежища.

Швеция, Норвегия, Дания
Обновени брошури за гражданите с ясни инструкции при военен конфликт

Чехия
Над 5 млн. брошури за всяко домакинство и сайт с инструкции за първите 72 часа на криза

Германия
План за милиарди евро: ремонт на бункери от Студената война, метростанции, тунели и паркинги като скривалища

Нидерландия, Франция, Белгия
Национални кампании: всяко семейство съставя план за действие и си осигурява тридневни запаси

Финландия
Над 50 000 убежища с капацитет 4,8 млн. души

България
247 напълно годни убежища с капацитет около 60 000 души


Що се отнася до покритие и достъп до бункери, абсолютният лидер е Финландия. 

Страната разполага с над 50 000 убежища за гражданска защита с капацитет от 4,8 млн. души – значителна част от населението ѝ, което наброява близо 5,7 милиона. Повечето от тях са частни стоманобетонни скривалища, разположени в отделни сгради. В съчетание със задължителните бомбоубежища в мазетата на жилищните кооперации капацитетът в столицата Хелзинки надхвърля 700 000 души, каквото е населението на града.

Как е в България?

В цялата страна официално регистрираните и напълно годни да изпълнят своето предназначение защитни скривалища са едва 247. Това става ясно от данни на отдел „Превантивна дейност“ в Главна дирекция „Пожарна безопасност и защита на населението“, представени пред БНР. Общият капацитет на тези съоръжения позволява едновременно да бъдат укрити максимум около 60 000 души, или по-малко от 1% от постоянно живеещите в страната.

Според същите данни при евентуална извънредна ситуация най-мащабно укриване на населението в градски условия би могло да се осъществи в станциите на метрото в София. 


Каква част от населението може да се скрие в убежище
Финландия
84%

Убежища за 4,8 млн. души при около 5,7 млн. население

България
<1%

247 годни убежища с капацитет около 60 000 души

1 кръгче = 1% от населението



(function () {
‘use strict’;

/* ===== ОБЩО ===== */
var reduceMotion = window.matchMedia && window.matchMedia(‘(prefers-reduced-motion: reduce)’).matches;
var canAnimate = typeof Element !== ‘undefined’ && typeof Element.prototype.animate === ‘function’;
function qs(root, sel) { return root.querySelector(sel); }
function qsa(root, sel) { return Array.prototype.slice.call(root.querySelectorAll(sel)); }
function noop() {}
var WIPE_FROM = ‘inset(0 100% 0 0)’;
var WIPE_TO = ‘inset(0 0 0 0)’;

function onceInView(el, threshold, cb) {
if (!(‘IntersectionObserver’ in window)) { cb(el); return; }
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { io.unobserve(e.target); cb(e.target); }
});
}, { threshold: threshold });
io.observe(el);
}

/* пуска елементите един след друг: всеки чака да е в екрана И предишният да е стигнал до „реда” си.
play(el) връща след колко ms да тръгне следващият. */
function sequence(items, threshold, play) {
var prev = Promise.resolve();
items.forEach(function (it) {
var seen = new Promise(function (res) { onceInView(it, threshold, res); });
prev = Promise.all([prev, seen]).then(function () {
var wait = play(it) || 0;
return new Promise(function (res) { setTimeout(res, wait); });
});
});
}

/* събира анимациите и при край маха началното състояние (is-armed) */
function makeRunner(root, defaultEase) {
var anims = [];
function run(el, keyframes, delay, duration, easing) {
var a = el.animate(keyframes, { delay: delay, duration: duration, easing: easing || defaultEase, fill: ‘both’ });
anims.push(a);
return a;
}
function finish() {
Promise.all(anims.map(function (a) { return a.finished; })).then(function () {
root.classList.add(‘is-done’);
anims.forEach(function (a) { try { a.cancel(); } catch (e) { noop(); } });
}).catch(noop);
}
return { run: run, finish: finish };
}

var EASE_OUT = ‘cubic-bezier(0.22, 0.8, 0.26, 1)’;
var EASE_POP = ‘cubic-bezier(0.34, 1.56, 0.64, 1)’;

/* =====================================================================================
КАРТА НА ЕВРОПА (.tst-map) — влизане на картата + клик върху държава → балонче
===================================================================================== */
var MAP = {
threshold: 0.3,
bgMs: 600,
groupDelay: 300, // кога тръгват държавите
groupStep: 110, // пауза между групите
groupMs: 500,
bubbleMs: 260
};

function mapSetup(root) {
var stage = qs(root, ‘.tst-map-stage’);
var svg = qs(root, ‘.tst-map-svg’);
var bubble = qs(root, ‘.tst-map-bubble’);
var bName = qs(bubble, ‘.tst-map-name’);
var bBody = qs(bubble, ‘.tst-map-body’);
var groups = qsa(root, ‘.tst-map-c’);
var texts = {};
qsa(root, ‘.tst-map-text’).forEach(function (t) {
texts[t.getAttribute(‘data-group’)] = {
name: (qs(t, ‘.tst-map-name’) || {}).textContent || ”,
body: (qs(t, ‘.tst-map-body’) || {}).textContent || ”
};
});
var active = null;
var FULL_VIEW = svg.getAttribute(‘viewBox’);
/* компютър с мишка: балончето излиза при посочване; телефон/таблет: при докосване */
var canHover = !!(window.matchMedia && window.matchMedia(‘(hover: hover) and (pointer: fine)’).matches);

/* на тесен екран (телефон/приложение) приближаваме към Европа, за да са държавите по-големи */
function applyView() {
var narrow = stage.clientWidth < 560;
svg.setAttribute('viewBox', narrow ? '130 90 520 540' : FULL_VIEW);
}
applyView();

/* намира държавата под пръста; ако докосването е „до" държава (малките са тесни), взема най-близката */
function groupAt(x, y) {
var offs = [[0, 0], [10, 0], [-10, 0], [0, 10], [0, -10], [14, 14], [-14, 14], [14, -14], [-14, -14], [20, 0], [-20, 0], [0, 20], [0, -20]];
for (var i = 0; i < offs.length; i++) {
var el = document.elementFromPoint(x + offs[i][0], y + offs[i][1]);
var g = el && el.closest ? el.closest('.tst-map-c') : null;
if (g && root.contains(g)) { return g; }
}
return null;
}

function place() {
if (!active) { return; }
var vb = svg.viewBox.baseVal;
var sw = stage.clientWidth, sh = stage.clientHeight;
var kx = sw / vb.width, ky = svg.getBoundingClientRect().height / vb.height;
var bb = active.getBBox();
var cx = (bb.x – vb.x + bb.width / 2) * kx;
var top = (bb.y – vb.y) * ky, bottom = (bb.y – vb.y + bb.height) * ky;
var w = bubble.offsetWidth, h = bubble.offsetHeight;
var left = Math.max(8, Math.min(cx – w / 2, sw – w – 8));
var below = top – h – 14 < 0;
var y = below ? bottom + 14 : top – h – 14;
y = Math.max(0, Math.min(y, sh – h));
bubble.style.left = left + 'px';
bubble.style.top = y + 'px';
bubble.classList.toggle('is-below', below);
var tx = Math.max(24, Math.min(cx – left, w – 24));
bubble.querySelector('.tst-map-tail').style.left = (tx – 8) + 'px';
bubble.style.transformOrigin = tx + 'px ' + (below ? '0' : '100%');
}

function close() {
if (active) { active.classList.remove('is-active'); }
active = null;
bubble.hidden = true;
}

function select(g) {
var t = texts[g.getAttribute('data-group')];
if (!t) { return; }
if (active) { active.classList.remove('is-active'); }
active = g;
g.classList.add('is-active');
bName.textContent = t.name;
bBody.textContent = t.body;
bubble.style.visibility = 'hidden';
bubble.hidden = false;
place();
bubble.style.visibility = '';
if (canAnimate && !reduceMotion) {
bubble.animate([{ opacity: 0, transform: 'scale(0.92)' }, { opacity: 1, transform: 'scale(1)' }],
{ duration: MAP.bubbleMs, easing: EASE_POP });
}
}

groups.forEach(function (g) {
g.setAttribute('tabindex', '0');
g.setAttribute('role', 'button');
var t = texts[g.getAttribute('data-group')];
if (t) { g.setAttribute('aria-label', t.name); }
g.addEventListener('click', function (e) { e.stopPropagation(); if (active !== g) { select(g); } });
if (canHover) {
g.addEventListener('mouseenter', function () { if (active !== g) { select(g); } });
g.addEventListener('mouseleave', function () { if (active === g) { close(); } });
}
g.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); select(g); }
if (e.key === 'Escape') { close(); }
});
});
stage.addEventListener('click', function (e) { // клик до държава → избира я; клик другаде → балончето се скрива
var g = groupAt(e.clientX, e.clientY);
if (g) { select(g); } else { close(); }
});
window.addEventListener('resize', function () { applyView(); place(); });

if (reduceMotion || !canAnimate) { return; }
root.classList.add('is-armed');
onceInView(root, MAP.threshold, function () {
var R = makeRunner(root, EASE_OUT);
R.run(qs(root, '.tst-map-bg'), [{ opacity: 0 }, { opacity: 1 }], 0, MAP.bgMs);
groups.forEach(function (g, i) {
R.run(g, [{ opacity: 0 }, { opacity: 1 }], MAP.groupDelay + i * MAP.groupStep, MAP.groupMs);
});
R.finish();
});
}

/* =====================================================================================
ФИНЛАНДИЯ СРЕЩУ БЪЛГАРИЯ (.tst-fin) — първо кръгчетата едно след друго (сиви),
после цветът се „пали" в цветните, докато излиза числото. После втората част.
===================================================================================== */
var FIN = {
threshold: 0.5,
dotStep: 9, // пауза между кръгчетата
dotMs: 350,
glowLead: 200, // цветът тръгва толкова след последното кръгче
glowStep: 10, // пауза между цветните кръгчета
glowMs: 450,
wordMs: 500,
noteDelay: 350,
next: 500 // след колко ms от старта на цвета тръгва следващата част
};

/* създава кръгчетата от data-total / data-on (работи и без анимация) */
function finBuild(grid) {
if (grid.getAttribute('data-built') === '1') { return; }
var total = parseInt(grid.getAttribute('data-total'), 10);
var on = parseFloat(grid.getAttribute('data-on'));
if (!isFinite(total) || total < 1) { total = 100; }
if (!isFinite(on)) { on = 0; }
for (var i = 0; i < total; i++) {
var dot = document.createElement('div');
dot.className = 'tst-fin-dot';
if (i < on) {
var g = document.createElement('span');
g.className = 'tst-fin-glow';
var p = Math.min(1, on – i);
if (p < 1) { g.style.setProperty('–tst-fin-p', (p * 100) + '%'); }
dot.appendChild(g);
}
grid.appendChild(dot);
}
grid.setAttribute('data-built', '1');
}

function finPlay(part) {
part.classList.remove('is-done');
part.classList.add('is-armed');
var R = makeRunner(part, EASE_OUT), run = R.run;
var dots = qsa(part, '.tst-fin-dot');
var glows = qsa(part, '.tst-fin-glow');
var country = qs(part, '.tst-fin-country'), num = qs(part, '.tst-fin-num'), note = qs(part, '.tst-fin-note');

if (country) { run(country, [{ clipPath: WIPE_FROM }, { clipPath: WIPE_TO }], 0, FIN.wordMs); }
dots.forEach(function (d, i) {
run(d, [{ opacity: 0, transform: 'scale(0.3)' }, { opacity: 1, transform: 'scale(1)' }], i * FIN.dotStep, FIN.dotMs, EASE_POP);
});
var tG = Math.max(0, (dots.length – 1) * FIN.dotStep) + FIN.glowLead;
glows.forEach(function (g, k) {
run(g, [{ clipPath: WIPE_FROM }, { clipPath: WIPE_TO }], tG + k * FIN.glowStep, FIN.glowMs);
});
if (num) { run(num, [{ clipPath: WIPE_FROM }, { clipPath: WIPE_TO }], tG, FIN.wordMs); }
if (note) { run(note, [{ opacity: 0, transform: 'translateY(6px)' }, { opacity: 1, transform: 'translateY(0)' }], tG + FIN.noteDelay, 600); }
R.finish();
return tG + FIN.next;
}

function finSetup(root) {
qsa(root, '.tst-fin-grid').forEach(finBuild);
if (reduceMotion || !canAnimate) { return; }
var parts = qsa(root, '.tst-fin-part');
parts.forEach(function (p) { p.classList.add('is-armed'); });
sequence(parts, FIN.threshold, finPlay);
}

/* ===== старт ===== */
function init() {
qsa(document, '.tst-map').forEach(mapSetup);
qsa(document, '.tst-fin').forEach(finSetup);
}
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); }
})();

МВР обаче не потвърждава дали метростанциите отговарят на нужните изисквания. 

На този фон капацитетът на отделните специализирани подземни скривалища остава ограничен, като най-големият обект може да побере само около 300 души. Въпреки поредицата от атаки с дронове край българското крайбрежие и продължаващата война на Русия в Украйна темата за сигурността на цивилното население шокиращо остава извън дневния ред на българските политици – както в проруските среди на Радев и Костадинов, така и сред проевропейските сили. Следва незабавно да се поставят на фокус въпросите около състоянието, поддръжката и капацитета на защитната инфраструктура в страната и готовността на държавата и населението за реакция при кризисни ситуации. 

Три са насоките, които изискват спешно внимание:

Увеличаване на капацитета – спешна проверка на всички бомбоубежища от времето на Студената война в цялата страна и превръщането им в годни скривалища по примера на Германия и Полша. Одит на гражданска инфраструктура, която би могла да се ползва по време на кризи – това са метростанции, тунели и подземни гаражи. 

Институционална, политическа и обществена ангажираност – обществото не получава ясни насоки от управляващите, актуални карти на укритията или практични обучения за реакция при криза. Липсва мащабна национална кампания за подготовка на домакинствата, подобна на тези в Европа.

Разминаване с реалността – заради дребни политически интереси и нежелание на политическите сили да всяват „паника“ защитата на населението е хвърлена в кофата; не само че липсва инфраструктура и кампания за подготовка, липсват дори идеи и насоки такива да бъдат създадени.

Според премиера Радев няма място за „истерия“, когато Русия убива моряци в близост до българския бряг. Вероятно по същата причина къпещото се в похвали от Москва правителство пази гробно мълчание по темата с липсата на бомбоубежища в България и не предприема кампания за кризисна готовност на населението. Но да се подготвиш за бедствие, когато е очевидно, че то се насочва към теб, не е истерия, а елементарно чувство за самосъхранение. Ако съседската къща гори, да знаеш къде има пожарогасител или да се измъкнеш навреме е начин да останеш жив. 

Докато Европа готви своите граждани за природни бедствия, кибератаки и военен конфликт, в България институциите са безмълвни по темата, а за политическите лидери явно безопасността на хората в страната не е на дневен ред. Кой обаче ще поеме отговорност, когато ни връхлети кризата?

Marvell Proposes Acquiring Lumentum to Combine Optical Circuit Switching with AI Connectivity Silicon

Post Syndicated from Cliff Robinson original https://www.servethehome.com/marvell-to-acquire-lumentum-115-billion-optical-ai-connectivity/

Marvell announced its intention to acquire Lumentum in a $115B acquisition to further optical connectivity in the AI era

The post Marvell Proposes Acquiring Lumentum to Combine Optical Circuit Switching with AI Connectivity Silicon appeared first on ServeTheHome.

Introducing queue consumption mode for Apache Kafka in AWS Lambda

Post Syndicated from Vaibhav Jain original https://aws.amazon.com/blogs/compute/introducing-queue-consumption-mode-for-apache-kafka-in-aws-lambda/

Queue consumption mode for AWS Lambda event source mappings (ESMs) that subscribe to Apache Kafka is now available. Queue consumption mode is available on the self-managed Apache Kafka ESM. It covers both Kafka clusters you operate yourself and managed Kafka offerings such as Confluent Cloud and other providers that offer Kafka 4.2 or later with Kafka Queue support.

With this launch, you can build queue-style event-driven workloads on Kafka that process records with high parallelism that scales concurrency to match your backlog instead of your topic layout. Queue mode achieves this using Kafka Share Groups (KIP-932), introduced in Kafka 4.0. With share groups, multiple consumers read concurrently from the same partitions, so Lambda can process records from a single partition across many parallel invocations. The result is parallelism that is decoupled from partition count, without head-of-line blocking and without introducing a second messaging system into your architecture.

Many Kafka workloads treat each event as an independent unit of work rather than a step in an ordered sequence: generating image and video renditions after upload, offloading slow work from a user-facing API, scoring transactions for fraud, delivering notifications, enriching records for inference, processing bulk files, buffering ahead of a rate-limited dependency, and ingesting telemetry. Correctness for these workloads depends on processing records quickly, not in order. The Kafka consumer group protocol, however, assigns each partition to exactly one consumer, so a topic with 10 partitions supports up to 10 concurrent consumers. Over-partitioning raises that ceiling but increases broker resource usage, slows rebalances, and still leaves head-of-line blocking, where one slow record stalls every record behind it. Previously, teams moved this traffic to a separate queuing system, adding a platform to operate and new producer code.

In this post, you learn how queue consumption mode works compared to the existing stream mode, what broker and cluster requirements your Kafka 4.2 cluster must meet, and how to scale from on-demand defaults to provisioned mode for high-throughput workloads.

What’s new

This launch adds a ConsumptionMode parameter to the Kafka event source mappings in Lambda. It accepts two values: Stream (the default, matching today’s behavior) and Queue, which uses Kafka Share Groups for parallel consumption. The core primitive in both modes is the event poller, a compute resource that fetches records from Kafka and invokes your Lambda function. Queue mode changes the protocol an event poller uses to obtain those records. Because pollers are no longer bound to individual partitions, queue mode supports higher concurrency. A single poller reaches up to 10 concurrent invocations compared to 5 in stream mode, and queue mode scales independently of partition count. We cover the scaling model in detail later in this post.

Stream mode: One consumer per partition, ordered processing

ConsumptionMode defaults to Stream, so existing ESMs are unaffected by this launch. In Stream mode, event pollers join a Kafka consumer group, and the broker assigns each partition exclusively to one consumer. This guarantees ordered processing within each partition.

Queue mode: Multiple consumers per partition, unordered parallel processing

Setting ConsumptionMode to Queue directs Lambda to use the Kafka Share Consumer. Event pollers join a share group, where partitions can be assigned to multiple event pollers for parallel processing without guarantees about order. The broker manages a record lifecycle of Available, Acquired, Acknowledged, and Archived. Fetched records are marked Acquired under a visibility timeout called the record lock duration. A successful invocation acknowledges them. A failed invocation releases them back to Available for any poller to acquire. While an invocation is still running, the poller renews the lock without incrementing the delivery attempt count.

Choosing between the modes

Use Stream mode when per-partition ordering matters: change data capture, event sourcing, or per-entity state machines. Use Queue mode when records are independent, and you want parallelism that is not bounded by partition count. You can run a Queue mode ESM and a Stream mode ESM against the same topic. Each operates independently through its own protocol.

Minimum requirements

Before you configure an ESM with ConsumptionMode: Queue, confirm that your Kafka cluster and Lambda function meet the following requirements.

Cluster requirements

  • Apache Kafka 4.2 or later, with share groups enabled.

Four broker settings interact with your ESM configuration:

  • group.share.partition.max.record.locks – The maximum in-flight records per partition. In Queue mode, multiple pollers might acquire records from the same partition concurrently, so the total in-flight count can exceed a single poller’s batch size. Set this value high enough to accommodate your expected concurrency. When the limit is reached, pollers can’t acquire new records from that partition until existing records are acknowledged, or their locks expire.
  • group.share.record.lock.duration.ms – The visibility timeout for acquired records. In most cases, the default of 30 seconds is sufficient. The poller renews the lock during processing. A long-running function does not typically require a duration longer than 30 seconds.
  • group.share.delivery.count.limit – The maximum number of times the broker attempts to deliver a record before archiving it. This works alongside MaximumRetryAttempts to govern retry behavior.
  • group.share.max.size – The maximum consumers allowed in the share group. When provisioned mode is active, keep MinimumPollers ≤ MaximumPollers ≤ group.share.max.size so that Lambda scaling isn’t capped by the broker. In on-demand mode, Lambda internally manages poller counts within broker-safe defaults.

Getting started

In the Lambda console, choose your function, choose Add trigger, and select Self-managed Apache Kafka. Enter your bootstrap servers and topic name, set Consumption mode to Queue, and configure your virtual private cloud (VPC) subnets and security groups. Optionally set Minimum event pollers and Maximum event pollers to use provisioned mode. For on-demand scaling leave those empty.

The following AWS CLI command creates the equivalent Queue mode ESM in on-demand mode:

aws lambda create-event-source-mapping
--function-name my-function
--self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["broker1.example.com:9092","broker2.example.com:9092"]}}'
--topics my-queue-topic
--batch-size 100
--self-managed-kafka-event-source-config '{"ConsumptionMode": "Queue"}'

ConsumptionMode is the only parameter required to enable Queue mode. BatchSize sets the maximum records per batch sent to your function, accepts values from 1–10,000, and defaults to 100.

With AWS CloudFormation, the equivalent resource looks as follows:

MyKafkaQueueESM:
  Type: AWS::Lambda::EventSourceMapping
  Properties:
    FunctionName: !Ref MyFunction
    SelfManagedEventSource:
      Endpoints:
        KafkaBootstrapServers:
          - broker1.example.com:9092
          - broker2.example.com:9092
    Topics:
      - my-queue-topic
    BatchSize: 100
    SelfManagedKafkaEventSourceConfig:
      ConsumptionMode: Queue

Queue mode is also configurable through the AWS SDKs, AWS Serverless Application Model (AWS SAM), and AWS Cloud Development Kit (AWS CDK). For the complete setup walkthrough, see the AWS Lambda Developer Guide.

Scaling with on-demand mode

Queue mode ESMs use on-demand mode for scaling by default. Lambda evaluates share group consumer lag at one-minute intervals and adds or removes event pollers as needed, completing scaling actions within three minutes. On-demand mode scales to five event pollers per ESM, each supporting up to 1 MB/s. It reaches its ceiling at either 5 MB/s aggregate throughput or 50 concurrent invocations, whichever comes first. This suits lower-concurrency workloads and development environments.

Scaling with provisioned mode

For workloads with strict latency requirements or spiky traffic, provisioned mode for scaling gives you direct control over the event pollers dedicated to your ESM. Set MinimumPollers from 1 –200 and MaximumPollers from 1 to 2,000. However, the broker’s group.share.max.size setting caps how many members can join a share group, and Kafka 4.2 limits this value to 1,000. Set MaximumPollers to 1,000 or below unless your broker supports a higher limit. Each provisioned event poller supports up to 5 MB/s.

aws lambda create-event-source-mapping
--function-name my-function
--self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["broker1.example.com:9092","broker2.example.com:9092"]}}'
--topics my-queue-topic
--batch-size 100
--self-managed-kafka-event-source-config '{"ConsumptionMode": "Queue"}'
--provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'
--source-access-configurations '[{"Type":"VPC_SUBNET","URI":"subnet-0123456789abcdef0"},{"Type":"VPC_SUBNET","URI":"subnet-0123456789abcdef1"},{"Type":"VPC_SECURITY_GROUP","URI":"sg-0123456789abcdef0"}]'

To size MinimumPollers, divide your baseline ingestion rate by 5 MB/s. If your workload is concurrency-bound, divide your target concurrent invocations by 10 instead. A workload needing 300 concurrent invocations requires at least 30 pollers. Setting MinimumPollers equal to MaximumPollers pins capacity and disables autoscaling. For detailed sizing guidance, see Introducing provisioned mode for Kafka event source mappings with AWS Lambda on the AWS Compute Blog.

Low-latency processing, schema registry filtering for Avro and Protobuf, and ESM grouping are available only in provisioned mode. Provisioned mode also removes the requirement to configure AWS PrivateLink VPC endpoints, so you are not charged for those endpoints. To switch an ESM to on-demand scaling, pass an empty configuration:

aws lambda update-event-source-mapping \
--uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
--provisioned-poller-config '{}'

Cost optimization with provisioned mode

In provisioned mode, ESMs in the same VPC can share Event Poller Unit (EPU) capacity through a common PollerGroupName, letting low-throughput ESMs pack onto shared EPUs instead of each holding dedicated capacity. For details, see Cost optimization for provisioned mode. A poller group supports up to 100 ESMs and 2,000 aggregate maximum pollers.

Queue mode ESMs share EPUs only with other Queue mode ESMs. The two modes autoscale on different signals, and isolation keeps a new Queue mode ESM from destabilizing existing ordered consumers. Use a unique PollerGroupName for your Queue mode ESMs. If you reuse a PollerGroupName across modes, CreateEventSourceMapping returns a validation error.

Handling failures

MaximumRetryAttempts accepts values from 0 to 10,000 and defaults to -1, which retries indefinitely. BisectBatchOnFunctionError splits a batch in half when the function returns an error, isolating a poison-pill record from an otherwise healthy batch. To capture records that exhaust their retries, configure an on-failure destination: a Kafka topic, Amazon Simple Queue Service (Amazon SQS), or Amazon Simple Notification Service (Amazon SNS). ESM logging to Amazon CloudWatch Logs is available for diagnostics.

Key considerations for Queue mode

Keep the following in mind when configuring your event source mapping for Queue mode.

  • Make your function idempoten – Lambda event source mappings process each record at least once, and duplicate processing can occur. See How do I make my Lambda function idempotent in the AWS Knowledge Center.
  • No ordering guarantees – Records can arrive out of order, including records from the same partition.
  • Batching window is not supported – MaximumBatchingWindowInSeconds returns a validation error. The Kafka Share Consumer requires every record in a batch to be acknowledged before fetching new records, which is incompatible with a time-based window.
  • Starting position is not supported – StartingPosition and StartingPositionTimestamp can’t be used. Queue mode reads from the share group’s committed position. To control where a new share group begins reading, configure share.auto.offset.reset on the broker.
  • Event filtering supports up to five filter patterns per event source mapping.

Pricing and availability

Queue consumption mode is available in all AWS Regions where Lambda event source mappings for self-managed Apache Kafka is supported. On-demand mode carries no charge beyond standard Lambda invocation charges. Provisioned mode is billed on EPU usage. For details, see AWS Lambda pricing.

Conclusion

Queue consumption mode brings queue-style processing to Apache Kafka topics without additional infrastructure and without changes to your producers, topic configuration, or function code. By replacing exclusive partition assignment with share groups, it removes the partition count as a ceiling on parallelism and eliminates head-of-line blocking for workloads built on independent records.

To get started, create an event source mapping with ConsumptionMode set to Queue on a self-managed Apache Kafka 4.2 or later cluster. For configuration details, see Polling Kafka queue topics in the AWS Lambda Developer Guide.

For more serverless learning resources, visit Serverless Land.

 


About the authors

Vaibhav Jain

Vaibhav Jain

Vaibhav is a Senior Delivery Consultant at Amazon Web Services, where he leads technical delivery for complex data platform and application modernization engagements. He has over 20 years of experience in application development, including 15 years building large-scale distributed systems before joining AWS.

Hardith Murari

Hardith Murari

Hardith is a Delivery Consultant at Amazon Web Services, focused on application development, modernization, and event-driven architectures. He is driven by a deep interest in cloud infrastructure, distributed systems, and developer tooling, always seeking to improve reliability, scalability, and the overall developer experience on AWS.

Nihar Sheth

Nihar Sheth

Nihar is a Principal Product Manager for AWS Lambda at Amazon Web Services, where he leads product strategy for serverless compute and event-driven integrations. He is passionate about building capabilities that make it easier to create event-driven, highly scalable applications with a focus on developer experience, performance, and operational simplicity.

Beyond DKIM key rotation: understanding email replay attacks

Post Syndicated from Michael Araba original https://aws.amazon.com/blogs/security/beyond-dkim-key-rotation-understanding-email-replay-attacks/

As the email administrator for your organization’s domain, you receive a Domain-based Message Authentication, Reporting, and Conformance (DMARC) aggregate report showing email passing DomainKeys Identified Mail (DKIM) verification as though it came from your domain, sent from IP addresses you don’t recognize to recipients you didn’t contact. To clear the issue, you rotate your DKIM key, confirm the new selector is live, and verify that your DMARC policy is already set to p=reject. Days later, you see that the same unfamiliar traffic is still authenticating as you.

In this post, you learn why rotation alone can’t stop a DKIM replay attack, how to confirm that you’re looking at a replay rather than a legitimate relay or ordinary spoofing, and the DNS cleanup step that most rotation guidance leaves out. You also learn how you can use Amazon Simple Email Service (Amazon SES) to detect and respond to this activity faster.

How DKIM replay works

DKIM verifies one thing: that specific parts of a message didn’t change between the signer and the receiver. The signer signs the message with a private key, and receivers fetch the matching public key from your domain’s DNS to check the signature. A valid signature continues to validate wherever the message travels afterward. Mailing lists, .forward rules, and third-party relays all preserve it, which is the protocol working as designed.

A replay attack takes advantage of that durability. The attack works as follows:

  1. Your ecommerce platform sends a customer a legitimate response email, signed with your DKIM key.
  2. An attacker obtains one copy of that message. They might subscribe to your mailing list, compromise a mailbox, retrieve it from a list archive, or capture it through a forwarding rule.
  3. The attacker resends that message, unchanged, from their own servers to thousands of new recipients.
  4. Each receiving server fetches your public key from DNS and checks the signature. The signature passes, because the body wasn’t modified. Sender Policy Framework (SPF) fails, because the sending IP isn’t yours, but DMARC requires only one of SPF or DKIM to pass with alignment. Because DKIM passes, DMARC passes, and the message is delivered as authenticated email from your domain.

Understanding what an attacker can and can’t do matters, because the limits define the problem. An attacker can’t modify your message, add new content, or read your email. The signature is only valid while the message remains byte-for-byte identical.

What an attacker gains is your domain’s reputation, which they use to deliver your genuine message to an audience you didn’t intend. A receipt or invoice becomes a lure, and email that would normally be filtered is delivered because receivers trust your domain. This is abuse of reputation and reach, not content forgery, and the distinction matters when you explain the incident to your security team.

This also explains why an enforcing DMARC policy doesn’t stop an attack. DMARC passes when SPF or DKIM passes with alignment. During a replay, DKIM passes, so DMARC passes, and p=reject does not apply. A p=reject policy is designed to stop spoofing, where a forger has no valid signature and DKIM fails. It does nothing against a message that you signed. Determining which of the two was used is what tells you how to respond.

Is it replay, spoofing, or a legitimate relay?

Email from an unfamiliar IP address that passes DKIM has three common explanations, and each requires a different response. Confirm which you’re dealing with before you make any changes.

DMARC aggregate (rua) reports provide the source IP address, message volume, and SPF and DKIM results. This is enough to identify an anomaly, but not to prove a replay. A report row might read as follows:

source IP: 203.0.113.45 | count: 4,200 | SPF: fail | DKIM: pass (d=yourdomain.com)

You need to evaluate that row against the three possibilities:

  • The first possibility is a legitimate relay that you haven’t inventoried, such as a mailing list, a forwarder, or an email security gateway such as an inline cloud access security broker (CASB) that you route through. The signature validly survives the relay, and this is normal email flow. In the report, the source IP address usually resolves to a known provider, and the volume tracks your actual sending.
  • The second possibility is replay abuse, in which an attacker redistributes a message that you legitimately signed. In this case, the DKIM-passing volume comes from an IP address that has no business relationship with you, often well above the usual number of recipients that you send to, and frequently to recipient domains that you haven’t worked with.
  • The third possibility is ordinary spoofing, which is a forgery with no valid signature. That row shows DKIM: fail. DKIM that passes from an unknown IP address is therefore usually not ordinary spoofing.

Aggregate counts can’t prove a replay on their own. To confirm a replay, you need message-level evidence: a specific message that you sent matched to one that reached recipients you didn’t address. If you can’t make that match, treat the activity as an unconfirmed anomaly, and begin with the enforcement and monitoring steps that follow rather than removing keys.

Set up an enforcing DMARC policy first

Before you take any other action, confirm that you’re enforcing DMARC. Many domains that encounter this problem are still at p=none, which is monitoring only. This situation is common. Every DMARC deployment begins at p=none, and many organizations do not advance beyond it because nothing appears to be broken. At p=none, receivers take no action on failures, so no change you make affects delivery, and you can’t determine what enforcement would have caught.

The first step is therefore not key removal; it’s completing your sender inventory and reaching enforcement:

  1. Inventory every legitimate sender and relay for your domain, including your email service providers, mailing lists, and any security gateways that send on your behalf.
  2. Bring each sender into SPF and DKIM alignment so that legitimate email authenticates.
  3. Advance the policy one stage at a time, from p=none to p=quarantine to p=reject. Review your rua reports at each stage before you advance, typically for a week or two per stage, and longer if you have many senders to work through. The pct tag lets you ramp up gradually, for example by quarantining 25% of failing email before you increase the percentage.

After you’re enforcing DMARC, receivers that honor DMARC drop unauthenticated spoofing on your behalf. Only after this baseline is in place, and only after you have confirmed a replay of genuinely signed email, does the next step apply.

Remove the old key from DNS: routine hygiene after rotation

Most rotation guidance omits this step. Rotating a key and removing the old key are two separate actions.

Rotation means that your provider begins signing new email with a new key and selector. Removal means deleting the old public key from DNS, so that previously signed messages, including the copies that an attacker captured, can no longer be verified. If you rotate but leave the old public key published, every message ever signed with that key remains replayable for as long as the record exists. Removing the old key is what closes that window and is the step that’s commonly overlooked.

Removal affects only messages that are still in transit and were signed with the old key. After email is delivered, the receiver no longer needs your key, so we recommend that you leave the old key published long enough for in-flight email to arrive and then remove it. How much of this process you manage yourself depends on your DKIM method, which the following section describes. During a confirmed active replay, closing this window is essential.

How you manage keys depends on the DKIM method that you use with Amazon SES. With Bring Your Own DKIM (BYODKIM), you generate the key pair and publish the public key as a TXT record that you control. You can rotate and remove keys whenever you want, including removing an old key on demand during an incident. As the BYODKIM documentation states, “you can rotate the DKIM keys for your domains as often as you want.”

With Easy DKIM, a feature where Amazon SES generates and manages the keys for you, you publish CNAME records that point to AWS-hosted keys. Because your DNS points to AWS-hosted keys through those CNAME records, Amazon SES manages the underlying key material for you, so you don’t publish or remove individual keys yourself. Unlike BYODKIM, Easy DKIM doesn’t provide an on-demand option to delete a specific key immediately.

If you’re an Easy DKIM sender during a confirmed replay, your defenses are early detection (described in the following section), the duplicate-message throttling that receivers already apply, and, over the longer term, the emerging DKIM2 effort, an IETF initiative to update the DKIM specification with built-in replay resistance, which is being designed to give receivers better signals to identify and act on replayed messages at the protocol level.

How Amazon SES helps you detect and respond

Your first response is detection, not DNS changes. The goal is to identify anomalous DKIM-passing volume early, while you build the message-level evidence that distinguishes a replay from a legitimate relay.

Begin by enabling logging. Create an Amazon SES configuration set with an event destination (see Monitor email sending using Amazon SES event publishing) that streams per-message events (Send, Delivery, Bounce, and Complaint) to Amazon Data Firehose or Amazon EventBridge (see Add an event destination), tagged with the From domain.

Separately, confirm that you’re receiving rua reports for your domain. You enable these reports by adding a rua= address to your domain’s DMARC TXT record, for example rua=mailto:[email protected]. For the record syntax and a phased p=none to p=quarantine to p=reject rollout, see Complying with DMARC authentication protocol in Amazon SES. Reports arrive as daily XML digests, and most teams process them with a DMARC analyzer rather than reading the raw XML.

With both sources in place, you can correlate them. Compare the email that your account emitted—based on your Amazon SES delivery events—against what DMARC reports show that receivers accepted as your domain. When DMARC shows DKIM-passing volume from IP addresses outside your SPF record that exceeds the delivery events that Amazon SES recorded for that From domain in the same window, that gap is your signal. It’s also how you build the message-level case that distinguishes a replay from a legitimate relay.

We recommend three additional controls. Amazon SES sending authorization restricts which AWS principals can send using your verified identity. It doesn’t stop an external replay, but it addresses the insider and third-party vector that SPF, DKIM, and DMARC don’t cover on their own, so use identity-level policies to limit sending to specific AWS Identity and Access Management (IAM) principals.

Use Amazon Route 53 to set short DNS time-to-live values (TTLs) (for example, 300 seconds) on your DKIM records so that changes propagate quickly; and enable DNS query logging with an Amazon CloudWatch Logs metric filter that watches for queries to a selector that you’ve rotated away from.

A spike in lookups for an old selector is a useful early indicator of a replay attempt using a retired selector. For a BYODKIM domain during a confirmed replay, Route 53 is also where you remove the old selector’s TXT record. You can automate that removal by using an Amazon CloudWatch alarm that starts an AWS Lambda function to call the Route 53 API and retire an old selector’s record.

Scope the function’s IAM role to only the specific Route 53 hosted zone and record that it needs to change, so that it follows least privilege. Because an incorrect DNS change can have a wide effect, gate any automation behind confirmed-replay criteria and test it against a non-production domain first. For most teams, alarm-to-human is safer than alarm-to-automatic-removal.

When your domain is the one being abused

Most guidance assumes that you’re either the provider preventing abuse or the receiver detecting it. In a replay, your domain is the one whose reputation is being consumed, and you aren’t on the recipient list. As a result, you don’t have the message that everyone asks for when you report the issue.

When you file an abuse report with the provider that hosts the source IP address, they ask for full message headers. The email went to people you didn’t contact, so you don’t have the message headers. You then provide DMARC aggregate reports that show the source IP address and volume, and the provider asks for headers again. At this point, you’re unable to proceed.

To break this cycle, go to the recipients. Review your rua reports for the top recipient domains—which are often .gov and .edu domains—contact those recipients directly and request a sample message with full headers. In addition to providing the headers, that sample lets you confirm a replay rather than a legitimate relay. Build your abuse report around the IP address and the DMARC evidence rather than the message content. If the source IP address belongs to Amazon Web Services (AWS), report it through the AWS abuse process and include your DMARC reports and SPF record as evidence.

Incident response: ordered actions

If your reports show suspicious DKIM-passing email from unfamiliar IP addresses, complete the following procedure.

To respond to a suspected DKIM replay

  1. Confirm that it’s a replay. Match a message that you sent to one that reached recipients you didn’t address and rule out legitimate relays and gateways. Aggregate data alone isn’t proof.
  2. Reach an enforcing DMARC policy. Inventory your legitimate senders, align them, and advance from p=none to p=quarantine to p=reject. This stops spoofing.
  3. Harden SPF to -all rather than ~all, but only after your sender inventory is complete, since -all hard-fails any legitimate source you haven’t listed.
  4. Check the DKIM-Signature header of a fresh message to confirm that your provider signs only with the current selector.
  5. Report the source IP address to the hosting provider and include your DMARC evidence.
  6. Investigate the capture point, such as a compromised mailbox, a mailing list, a forwarding rule, or a newsletter subscription.
  7. Remove the old DKIM public key after in-flight email has cleared. For BYODKIM, delete the old selector’s TXT record. For Easy DKIM, rely on the managed Amazon SES rotation together with the monitoring and receiver-side defenses described earlier.

The following table summarizes what each action does and doesn’t do.

Action What it does What it doesn’t do
Confirm replay (message-level) Separates a replay from a legitimate relay or spoofing Can’t be done from aggregate DMARC data alone
DMARC enforcement (p=none to p=reject) Drops unauthenticated spoofing Does nothing against a replay because DKIM still passes
Key rotation Signs new email with a new key Doesn’t invalidate already signed messages
Remove old key (routine, post-rotation) Invalidates old-key signatures, including captured ones Doesn’t protect in-flight old-key email; on-demand removal available only with BYODKIM
Amazon SES sending authorization Restricts which principals send as your identity Doesn’t stop external replay of captured messages

Conclusion

DKIM replay succeeds because a valid signature keeps validating, and an enforcing DMARC policy doesn’t change that. To respond effectively, confirm that the activity is a replay with message-level evidence, reach an enforcing DMARC policy, and then remove the old key from DNS as routine post-rotation hygiene. Keep your primary defense on monitoring and DMARC enforcement rather than on emergency DNS changes. The durable fix for replay is receiver-side: duplicate-message counting today, and stronger protocol-level signals through DKIM2 in the future.

To get started, review your current DMARC policy and confirm that you’re receiving rua reports, enable Amazon SES event publishing, and document how you rotate and remove DKIM keys for each of your domains.

Learn more

If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, contact AWS Support.


Michael Araba

Michael Araba

Michael is a Technical Account Manager at AWS Enterprise Support, where he works with customers on email security, DNS architecture, and incident response.

[$] The second part of the 7.4 merge window

Post Syndicated from daroc original https://lwn.net/Articles/1102739/

The 7.4 merge window, which
closed on November 1,
included a record-breaking 18,591 non-merge changesets.
That is almost as many as the entire 7.3 development cycle, which had 18,765, itself a record breaker. Of
those, 11,838 landed after the article covering the
first part of the merge window
. Most of those were bug fixes of
various forms; it seems as though bug fixes may be crowding out feature
additions across the open-source ecosystem to
some extent. Still, a good number of new features were included, and a handful
removed, in the tail end of the merge window.

How to run a DR readiness engagement

Post Syndicated from Peter Garnepudi original https://aws.amazon.com/blogs/architecture/how-to-run-a-dr-readiness-engagement/

Part 3 of 3

The framework from Part 1 (three business decisions) and Part 2 (progressive validation) works at any pace. You can apply it over months as part of normal operations, or compress it into a structured engagement that moves from undefined targets to a validated recovery commitment in weeks. This post walks through how to run that engagement yourself, with concrete steps, outputs, and a before-and-after example from a real enterprise engagement.

Step 1: Kickoff (define the scope)

Bring three groups into one room: the application owner who knows the technical architecture, the business owner who understands the consequence of downtime, and the platform team that owns the shared services your application depends on. If a dependency is owned by a team not represented in the room, that’s your first action item before proceeding.

Ask these questions in order:

  • What does the user need to be able to do for this function to count as “recovered”?
  • Which applications, shared services, and accounts are in the path of that user journey?
  • Who owns each piece, and have they confirmed their recovery timeline?

The output artifact is a boundary map: a document listing every service and account in the recovery path, with an owner assigned to each and their stated recovery timeline recorded. This single artifact becomes the foundation for every subsequent step.

Step 2: Assessment (surface the gaps)

Run a structured review of each component in the boundary map. For each dependency, ask: does it recover in the target AWS Region, does it recover within the stated recovery time objective (RTO), and does an upstream service’s recovery target cap the RTO you can actually commit to?

  • A Well-Architected Framework Review against the Reliability pillar gives you a systematic way to surface single points of failure, missing health checks, and unverified quotas.
  • An Operational Readiness Review checks whether the runbook’s assumptions hold: are the resources pre-provisioned, do upstream dependencies recover within the target, and are there any manual steps that depend on a specific person being available?

The output is a prioritized list of dependency gaps with owners assigned and a target fix date for each. “Done” at this step means every gap has an owner, a planned fix, and a committed date. Gaps without owners don’t get fixed.

Step 3: Validation plan (structure the tests)

Build a test calendar that progresses through the levels from Part 2. A practical sequence for a first engagement:

  • Week 2: Tabletop exercise on the highest-consequence function. Confirm ownership, escalation path, and expected duration per step.
  • Week 4-6: Planned failover after gap remediation. Measure actual recovery time against the committed RTO. Verify data consistency against the recovery point objective (RPO).
  • Week 8-10: Surprise drill (if the planned failover passed). Test coordination without advance notice.

Don’t schedule a game day with fault injection until you’ve passed a planned failover cleanly. Each level builds confidence for the next. Attempting a higher level before the lower one passes cleanly wastes effort and produces noisy findings that obscure the real gaps.

Step 4: Execute and learn (close the loop)

Each test produces findings. Document them in a format that maps each finding back to the decision it informs:

  • Boundary findings (a shared service discovered mid-test that wasn’t in the recovery scope) → feed back into Decision 1.
  • Consequence findings (recovery took longer than the business can tolerate) → feed back into Decision 2, where the business owner either accepts the longer timeline or invests in a faster architecture.
  • Dependency findings (an upstream service whose recovery target capped the application’s own, a resource that wasn’t pre-provisioned) → feed back into Decision 3.

The output is an updated recovery commitment that reflects what you actually measured, not what you assumed. This document replaces the prior version and becomes the baseline for the next cycle.

Step 5: Ongoing cadence (prevent drift)

Recovery posture drifts as applications change. A new microservice adds a dependency nobody mapped. A team deploys a configuration change that shifts traffic routing. A quota that covered peak load 6 months ago no longer does. Schedule a quarterly review that checks: has the boundary changed (new shared services, new accounts)? Has the business owner confirmed they still accept the RTO/RPO targets? Have any dependencies changed their recovery behavior?

A trigger for re-engagement outside the quarterly cycle: any architecture change that adds a cross-account dependency or changes the failover path.

What this looks like in practice

In the enterprise engagement referenced throughout this series, the team applied this pattern across its portfolio of applications and accounts. The first exercise missed a contractual recovery commitment of 5 hours, taking more than twice that long. Root causes mapped to all three decisions: the boundary excluded a shared authentication platform (most downstream applications couldn’t authenticate users), the dependency chain included an upstream service whose recovery target capped what the applications calling it could achieve, disaster recovery (DR) resources weren’t pre-provisioned, and DNS failover depended on a manual step that took over 3 hours under coordination pressure.

Over 4 months, the team redefined the boundary to include shared platforms, documented the full dependency chain per application, reconciled each application’s target against its slowest dependency, pre-provisioned the recovery environment, and replaced manual DNS failover with automated routing built on Amazon Application Recovery Controller (ARC) routing controls. ARC routing controls are on/off switches on a data plane that shifts traffic without depending on the Amazon Route 53 control plane, so a cutover doesn’t rely on modifying DNS records mid-event. This follows the Well-Architected guidance to rely on the data plane, not the control plane, during recovery (REL11-BP04), the same static-stability principle behind pre-provisioning. The second exercise passed. The organization operated a live customer-facing system from the recovery Region for the first time. Senior leadership cited the structured engagement as the factor that connected the two different outcomes.

Accelerating the timeline

You can run every step in this post with your own teams. If you want to compress the timeline, AWS Enterprise Support provides specific mechanisms that map to each step: a Technical Account Manager to facilitate the kickoff and maintain engagement momentum between sessions, Well-Architected and Operational Readiness Reviews for the assessment, specialist Solutions Architects for deep dependency analysis, and AWS Countdown for coordinated operational-readiness and engineering support during critical events, including planned failovers and DR game days. These are acceleration options, not prerequisites. The steps and outputs are the same either way.

The AWS Resilience Lifecycle Framework and AWS Resilience Analysis Framework provide the detailed practices behind each decision, and AWS Resilience Hub helps you assess applications against your defined RTO and RPO targets.


About the authors

Peter Garnepudi

Peter Garnepudi

Peter Garnepudi is a Senior Technical Account Manager and Enterprise Support Lead at Amazon Web Services. With 20 years in the IT industry and 9 years at AWS, Peter is a database specialist who works with Strategic, ISV, and Financial Services customers to optimize their cloud operations. His expertise includes database architecture, workload resilience, chaos engineering, and GenAI risk governance. He is based in Ottawa, Canada.

Jay Desai

Jay Desai

Jay Desai is a Technical Account Manager at Amazon Web Services in Toronto. He works with Financial Services customers to help them run secure, resilient, and well-architected workloads on AWS.

Validating your DR commitment: From controlled test to real-world readiness

Post Syndicated from Peter Garnepudi original https://aws.amazon.com/blogs/architecture/validating-your-dr-commitment-from-controlled-test-to-real-world-readiness/

Part 2 of 3

In Part 1 of this series, you defined three business decisions that shape your disaster recovery (DR) commitment: the recovery boundary, the business-anchored target, and the dependency-reconciled commitment. Those decisions give you a target on paper. Testing tells you whether it holds under real conditions.

This post covers a progressive approach to DR validation. Each level of testing surfaces a different class of gap, and each gap feeds back into the three decisions from Part 1 so your commitment gets stronger with every cycle.

Why a single test isn’t enough

A scheduled DR exercise with advance notice proves that the failover mechanism works. That’s a necessary starting point. You can confirm that traffic shifts correctly, data remains consistent in the recovery Region, and the application functions as expected after the transition.

A scheduled exercise doesn’t test the assumptions that only surface under pressure. It doesn’t show whether teams who haven’t rehearsed together can coordinate, or whether everyone agrees on who declares the failover and under what conditions. It also can’t confirm that you provisioned and validated your recovery environment before you triggered the failover. These are the conditions where real recoveries stall, and they’re invisible to a test where every team knows it’s coming and watches closely.

In the same engagement from Part 1, several applications had DR instances in a stopped state. The failover automation assumed it could launch instances, create database replicas, and scale container fleets on demand during the exercise. That approach worked only if the team confirmed two things in advance: that the recovery AWS Region had capacity for the requested instance types, and that the account quotas could absorb the full production load. The team didn’t verify these assumptions in advance.

The architecture was correct. The team didn’t verify those assumptions in advance, and it didn’t pre-provision the recovery environment. To close this gap, the team needs to pre-provision the recovery environment and configure auto scaling groups, confirm that its account quotas match production capacity requirements, and remove any runbook step that assumes your team needs to create resources during the event.

Four levels of progressive validation

The AWS Resilience Lifecycle Framework treats testing as a practice you deepen over time. The four levels below are a maturity model you can apply yourself, ordered from lowest-cost awareness to highest-fidelity validation. We’ve drawn it from patterns across the DR exercises we’ve seen. Each surfaces a different class of gap.

Level 1: Tabletop exercise. A facilitated walkthrough of the recovery plan without touching production. The goal is shared awareness and ownership clarity.

Questions to ask during the tabletop:

  • Who declares the failover, and under what conditions?
  • For each step in the runbook, who owns it and what’s their backup?
  • What’s the expected duration of each step, and what’s the total end-to-end timeline?
  • Which steps depend on a specific person being available?

In the same case study from Part 1, the first tabletop surfaced three boundary gaps: the shared authentication platform wasn’t in the recovery scope, a networking account owned by a different team had no failover runbook, and the DNS update step listed a generic team alias with no named owner.

Level 2: Planned failover. A scheduled failover with advance notice. The goal is confirming the mechanism works under known conditions.

What to measure:

  • Actual recovery time per application compared to the stated recovery time objective (RTO).
  • Data consistency validation in the recovery Region to confirm the recovery point objective (RPO).
  • Any step that requires manual intervention (potential automation candidate).
  • Any dependency that recovered later than expected.

In the same case study, the planned failover revealed the DNS misconfiguration: the shared platform’s Amazon Route 53 records still resolved to the primary Region 45 minutes into the test. Most downstream applications appeared healthy but couldn’t serve users. Actual recovery took more than twice the 5-hour target.

A successful planned failover produces a measured gap (or confirmation) between the RTO target you defined and your actual recovery time. That number is the starting point for every subsequent conversation with the business owner about whether the target is realistic.

Level 3: Surprise drill. A failover triggered without advance notice to the responding team. The goal is testing execution readiness, not capability.

This level finds the gaps that preparation hides: the runbook that only its original author can interpret, the step that depends on a specific person’s tribal knowledge, and the escalation path that nobody has practiced. In the case study, a later surprise drill revealed that only one engineer understood how to validate database consistency in the recovery Region. With that person unavailable, the team lost 90 minutes locating and interpreting the procedure.

Level 4: Game day with fault injection. An exercise where you inject specific dependency failures using AWS Fault Injection Service, which ships purpose-built scenarios such as “AZ Availability: Power Interruption” and “Cross-Region: Connectivity”. The goal is testing resilience under conditions you didn’t fully script.

You discover the dependency you assumed would be healthy, the monitoring gap that delays detection, and the cascade that your tabletop didn’t model. This is the closest approximation to a real event without waiting for one to happen.

What each level reveals

The tabletop finds the step no team owns. The planned failover finds the misconfiguration. The surprise drill finds the coordination failure. The game day finds the unmodeled dependency. Each level surfaces a different class of gap.

Run only the calm, scheduled test and you validate the mechanism while leaving the conditions that cause real recovery failures untested. The point isn’t to skip levels. You build confidence at each level before increasing realism. But stopping at the planned failover, a pattern we often see once the mechanism works, leaves team, process, and dependency gaps invisible until an event exposes them.

Closing the loop

Each test produces specific findings that map directly to the three decisions from Part 1.

  • A boundary gap (a shared service discovered mid-test that wasn’t in the recovery scope) feeds back into Decision 1.
  • A recovery that exceeds the time the business can tolerate feeds back into Decision 2, where the business owner either accepts the longer timeline or invests in a faster architecture.
  • A dependency that recovered slower than the target assumed feeds back into Decision 3 for a revised commitment that reflects what was actually measured.

In the same engagement, the first exercise surfaced all four patterns described across this series: a boundary gap (shared platform not in scope), a dependency gap (an upstream service whose recovery target capped the application’s own), a stability gap (resources not pre-provisioned), and a coordination gap (manual DNS failover). The team mapped each finding to a specific decision and a specific fix. Four months later, the second exercise passed. The organization operated a live customer-facing system from the recovery Region for the first time.

The value of progressive testing is not passing a single exercise. It’s building a practice where each cycle tightens the recovery commitment, and each finding has a clear path back to the decision it informs.

Where to start

If you haven’t run a tabletop yet, start there. Gather the owners of one critical business function and walk the recovery plan together. Ask: who declares the failover, what’s the first action, who owns each step, and what’s the expected duration of each. If the room disagrees with any answer, this indicates an opportunity to clarify and strengthen your recovery plan before touching production.

If you’ve passed a planned failover, consider whether a surprise drill would surface coordination gaps that preparation masks. In this engagement, the surprise drill cost the team 90 minutes that the planned failover never surfaced. Whatever level you’re at, document what each test reveals and feed it back into the three decisions. A posture that improves every test cycle is worth more than one that passes a single exercise and never evolves. In Part 3, we walk through how to structure a full DR readiness engagement: who to involve, what to produce at each step, and how to compress the timeline from months to weeks.


About the authors

Peter Garnepudi

Peter Garnepudi

Peter Garnepudi is a Senior Technical Account Manager and Enterprise Support Lead at Amazon Web Services. With 20 years in the IT industry and 9 years at AWS, Peter is a database specialist who works with Strategic, ISV, and Financial Services customers to optimize their cloud operations. His expertise includes database architecture, workload resilience, chaos engineering, and GenAI risk governance. He is based in Ottawa, Canada.

Jay Desai

Jay Desai

Jay Desai is a Technical Account Manager at Amazon Web Services in Toronto. He works with Financial Services customers to help them run secure, resilient, and well-architected workloads on AWS.

Three business decisions that define your DR success

Post Syndicated from Peter Garnepudi original https://aws.amazon.com/blogs/architecture/three-business-decisions-that-define-your-dr-success/

Part 1 of 3

A disaster recovery (DR) strategy is only as strong as the business decisions behind it. The architecture and failover mechanisms matter, but they execute against targets that you define. In our experience facilitating enterprise DR exercises, the difference between teams that meet their recovery targets and teams that don’t often comes down to three decisions made (or deferred) before the first architecture diagram: what you’re actually recovering, what the business needs from that recovery, and what your dependencies allow you to commit to.

This post helps you validate whether your current approach accounts for each one. It draws on a pattern from a real engagement where revisiting these decisions turned a missed recovery target into a successful test four months later.

This is Part 1 of a three-part series. It walks through those three decisions and shows how to make them before you choose an architecture pattern. Part 2 covers progressive validation testing. Part 3 covers how to run a DR readiness engagement. The approach builds on the AWS Resilience Lifecycle Framework and the AWS Resilience Analysis Framework.

Define the recovery boundary

The first decision is drawing the line around what “recovered” means. You cannot meaningfully define a recovery time objective (RTO) until you specify precisely what you need working for you to consider that objective met.

The Resilience Lifecycle Framework defines a business function as the end-to-end capability a user depends on (completing a transaction, filing a report, accessing an account). A single business function often spans multiple applications, accounts, and teams. When you set a recovery target at the application level without accounting for the shared services that the application calls, you might define the boundary too narrowly to deliver the capabilities your users require.

Here’s a pattern we observed in a DR exercise for a large enterprise customer. The customer tested dozens of applications across many AWS accounts. Each application had its own failover automation, and each one failed over correctly. But a shared authentication platform (running in a separate account, managed by a different team) used Amazon Route 53 simple routing pointed at the primary AWS Region. It had no health checks and no failover configuration. Because the team didn’t include it in the recovery scope, the platform remained in the primary Region while everything else moved. The result: Most of the downstream applications that depended on it couldn’t authenticate users. Although the team had successfully failed over the applications themselves, the business function (user login, transaction, confirmation) did not work. This single boundary gap, not the individual application architectures, was the primary driver of the missed recovery target.

The solution involved redefining the recovery scope rather than changing the architecture. The organization redefined recovery boundaries around business functions (what capabilities must you deliver to your users?) rather than individual applications (is this service running?). That single change pulled the shared authentication platform inside the scope and helped the team discover the dependency. A business impact analysis is the structured starting point for this work.

Anchor the target to business consequence

The second decision is settling what recovery means in terms the business owns. Business stakeholders strengthen RTO and recovery point objective (RPO) when they help set them. In organizations where these targets are defined by engineering alone, they can become disconnected from what the business actually tolerates. A 4-hour RTO means something different for a payments platform that clears interbank settlement than it does for an internal reporting dashboard, even when both share the same database engine and replication setup.

In the same engagement, the business carried a contractual recovery commitment of 5 hours. The business treated it as a firm commitment to their regulator. The engineering team treated it as a stretch goal based on the architecture’s theoretical capability. Neither side had validated whether 5 hours was achievable given the dependency chain. That disconnect only became visible when the first exercise took 9–11 hours. The target had never been tested against the actual recovery path, and the business stakeholder who owned the penalty had never been asked whether the engineering team’s assumptions matched theirs.

RPO is a statement about data loss. For a payments platform clearing interbank settlement, an RPO of 5 minutes might still be too wide if those minutes contain transactions that can’t be reconstructed. The question for the business owner is: Which records must survive a Regional impairment, and can you prove they will? The business owner uses that framing to decide whether asynchronous replication (with its window of in-flight data loss) is acceptable. The alternative is synchronous writes, with the latency cost that comes with them.

RTO is a statement about downtime tolerance. A 4-hour recovery time is a technical figure until someone attaches a consequence to each hour. For regulatory filings, the fourth hour might mean a missed deadline with financial penalties. For a storefront, every minute carries lost orders.

The AWS Resilience Lifecycle Framework recommends defining objectives around business outcomes directly (for example, the percentage of successful orders maintained when a component degrades). A service-level agreement (SLA) is a contract with a financial penalty. A service-level objective is a target you manage toward. Raising an SLA doesn’t make an application more resilient.

The output of this decision is a recovery requirement stated in language the business recognizes and engineering can build against: the function, the consequence of losing it, the data that must survive, and the tolerable downtime before the consequence lands.

Account for the dependency chain

The third decision is confirming that your recovery target accounts for everything in the critical path, not just the components you own. Your application recovers only as fast as its slowest dependency. If a service you call takes 4 hours to recover in the recovery Region, your achievable RTO is 4 hours regardless of your own architecture.

In the same engagement, one customer-facing application had committed to a 1-hour recovery target and had the architecture to meet it on its own. But it called a shared identity service, owned by a different team, to validate every user session. That identity service carried a 4-hour recovery target. No matter how fast the customer-facing application recovered, users couldn’t do anything until the identity service came back. The application’s real, achievable RTO was 4 hours, set entirely by a dependency its own team didn’t own and hadn’t accounted for when they committed to 1 hour.

This is why the dependency chain, not the application in isolation, defines the commitment you can make. Identify and document every service your business function calls, note the recovery target each one holds, and set your own target against the slowest link you depend on. Where another team owns a dependency, its recovery target becomes a commitment you need from them, in writing, not an assumption. The AWS Fault Isolation Boundaries whitepaper helps you reason about which dependencies hold during a Regional impairment, and which introduce risk. The distinction that matters is what your runbook asks a service to do. Reading existing data keeps working during an impairment: existing credentials still authenticate, and existing DNS records still resolve. Changing things is what carries risk, because creating or modifying AWS Identity and Access Management (IAM) roles and Route 53 records runs through control planes that live in a single Region. A recovery path that only reads existing state holds up. One that must create or change resources mid-event might not. That’s the case for settling those changes ahead of time.

Where you can, reduce the chain itself. When you pre-provision and run a dependency in the recovery Region before the event, you reduce how many services need to recover before you can restore your application. The shorter the chain of things that must recover in sequence, the closer your achievable target gets to the one you want to commit to.

Where to start

Start your validation by examining one business function. Assess whether: Is the recovery boundary drawn around the full user journey, including shared services in other accounts? Has a business stakeholder confirmed the consequence-per-hour attached to the current RTO and RPO? Does the target account for every dependency in the path, including global endpoints and any runbook step that assumes resource creation during failover?

If you can answer yes to all three with evidence, your targets are well-founded. If any answer is uncertain, you’ve identified where to focus next. In Part 2, we cover how to validate your answers through progressive testing that closes the distance between a controlled exercise and real-world readiness.


About the authors

Peter Garnepudi

Peter Garnepudi

Peter Garnepudi is a Senior Technical Account Manager and Enterprise Support Lead at Amazon Web Services. With 20 years in the IT industry and 9 years at AWS, Peter is a database specialist who works with Strategic, ISV, and Financial Services customers to optimize their cloud operations. His expertise includes database architecture, workload resilience, chaos engineering, and GenAI risk governance. He is based in Ottawa, Canada.

Jay Desai

Jay Desai

Jay Desai is a Technical Account Manager at Amazon Web Services in Toronto. He works with Financial Services customers to help them run secure, resilient, and well-architected workloads on AWS.

Automating the full AWS DRS agent lifecycle: Install, heal, and offboard

Post Syndicated from Manisha Yadav original https://aws.amazon.com/blogs/architecture/automating-the-full-aws-drs-agent-lifecycle-install-heal-and-offboard/

If you protect a large Amazon Elastic Compute Cloud (Amazon EC2) fleet with AWS Elastic Disaster Recovery (AWS DRS), you manage the AWS Replication Agent across its whole lifecycle. You install it, keep it healthy and registered, and remove it cleanly when a server leaves disaster recovery (DR) scope. An enterprise IT customer with more than 300 Linux and Windows instances in DR scope ran into two of these problems while planning and validating a scheduled DR drill. Some agents had stalled after a network change, and some descoped servers were still replicating and adding to the bill. A server with a stalled agent can’t meet your recovery point objective (RPO), the maximum data loss you can accept after a disruption. The customer’s team checked replication status in the AWS DRS console before each drill, so a problem that started between drills could go unnoticed until the next one.

Working with that customer, we automated the install, heal, and offboard phases of the lifecycle. Most of the design choices in this post came from fixing those two problems. Each phase runs as an AWS Systems Manager (SSM) Automation document, started by Amazon EventBridge or on a schedule. A single EC2 tag decides which phase applies to an instance. Because the logic lives in the Automation documents, there are no AWS Lambda functions to maintain. When you take an instance out of scope, the automation records whether replication billing actually stopped.

You can find the SSM Automation documents, AWS Identity and Access Management (IAM) policies, and deployment scripts in the aws-samples/sample-drs-agent-lifecycle-automation GitHub repository.

Solution overview

You apply a DR tag to each EC2 instance, and its value (yes, pause, or no) tells the automation what to do. Three SSM Automation documents divide the work. Onboarding installs and repairs the agent and keeps registration healthy. Healing responds when replication stalls, and offboarding runs teardown when you descope an instance.

AWS Systems Manager State Manager runs onboarding on a 30-minute schedule against tagged instances. Amazon EventBridge triggers healing when AWS DRS reports a stalled server, and offboarding when the DR tag changes. The automation runs primarily in your source AWS Region and calls the DR Region only where AWS DRS requires it.

Prerequisites

To deploy this solution, you need:

  • An AWS account with administrative access.
  • Two AWS Regions configured: a source Region (where your EC2 instances run) and a DR Region (where AWS DRS replicates to).
  • AWS Elastic Disaster Recovery initialized in both the source Region (for failback) and the DR Region (for replication).
  • Network connectivity between Regions with TCP 443 (AWS DRS API and Amazon Simple Storage Service (Amazon S3)) and TCP 1500 (replication data) open. For private connectivity, use AWS Transit Gateway or VPC peering. Public endpoints are also supported.
  • (Optional) Amazon Virtual Private Cloud (Amazon VPC) endpoints for AWS DRS and Amazon S3 in the DR Region, if using private connectivity.
  • IAM permissions to deploy AWS CloudFormation stacks that create named IAM roles (CAPABILITY_NAMED_IAM), Amazon EventBridge rules, and a State Manager association, and to register SSM Automation documents. You also need iam:PassRole on DRS-Automation-Role, because the Amazon EventBridge rules and the State Manager association use that role.
  • AWS Command Line Interface (AWS CLI) installed and configured.
  • An instance profile on each source EC2 instance with the AWSElasticDisasterRecoveryAgentInstallationPolicy and AmazonSSMManagedInstanceCore managed policies, so that each instance is managed by Systems Manager. If your instances already have an instance profile, attach both policies to its role.
  • An existing Amazon Simple Notification Service (Amazon SNS) topic for notifications.
  • (Optional) An existing Amazon S3 bucket for audit reports.
  • Git, Bash 4 or later, and yq. The deployment scripts use yq to read config.yaml. macOS includes Bash 3.2, so install a newer version, for example with Homebrew.

You don’t need to create the automation’s IAM roles yourself. The CloudFormation templates create DRS-Automation-Role (which runs every lifecycle action) and DRS-EventBridge-Forward-Role (deployed with the DR Region stack), along with the Amazon EventBridge rules in both Regions and the State Manager association. Amazon CloudWatch metrics are published automatically.

One tag controls the entire lifecycle

After you deploy the solution, the value of the DR tag on each EC2 instance determines what the automation does:

DR value State What happens
yes Protected Agent is installed, failback tag applied, health maintained every 30 minutes
pause Quiesced Agent stays installed, stalled alerts suppressed, offboarding blocked
no or deleted Descoped Replication stopped, source server deleted, agent uninstalled
Anything else (for example, DR=maybe, DR=true) Misconfigured Fail-safe: automation skips the instance and logs a SKIPPED_MISCONFIGURED status. No install, no heal, no teardown, preventing an unrecognized value from triggering the wrong action

The tag value is normalized (trimmed and lowercased) before evaluation. A value like DR=Yes normalizes to DR=yes and matches correctly.

Three SSM Automation documents divide the lifecycle:

  • DRS-Agent-Onboard runs every 30 minutes through State Manager against tag:DR=yes instances. It installs or repairs the agent, applies the AWSDRS:AllowLaunchingIntoThisInstance tag, and validates AWS DRS registration. The tag tells AWS DRS to launch recovery onto the original instance during failback and acts as the drift-correction backstop. State Manager re-evaluates tagged instances every 30 minutes. Each run catches instances that lost the Replication Agent, newly tagged instances that aren’t onboarded yet, and earlier runs that failed silently.
  • DRS-Agent-Heal fires when Amazon EventBridge receives a replication-stalled event (cross-Region forwarded from the DR Region). The rule filters on the STALLED state, so recovery transitions don’t trigger unnecessary runs. It inspects the replication error to distinguish agent-side failures from infrastructure issues. For agent problems, it restarts the service first, then reinstalls in place only if the restart doesn’t fix it. For infrastructure-caused stalls, it escalates to operators through Amazon SNS.
  • DRS-Agent-Offboard fires when Amazon EventBridge detects a DR tag change or deletion. The offboarding document first verifies safeguards: a tag re-check, a terminated-instance guard, and an optional approval gate. After those pass, it records replication state and stops replication. It then disconnects the source server, deletes it, uninstalls the Replication Agent, and removes the tags.

How the components connect

The solution operates primarily in the source Region. Cross-Region calls happen only where AWS DRS requires them (registration checks and teardown API calls target the DR Region).

The following diagram shows how the automation components connect across the source and DR Regions. State Manager and Amazon EventBridge operate in the source Region; AWS DRS replication and the stall-forwarding rule run in the DR Region.

State Manager and EventBridge in the source Region connecting to AWS DRS replication in the DR Region

Figure 1: AWS DRS agent lifecycle automation architecture across the source and DR Regions

In the source Region, State Manager runs the onboarding document every 30 minutes, and Amazon EventBridge rules start the heal and offboarding documents when their events arrive. AWS Systems Manager Parameter Store holds the DR-event stand-down flag (/drs/control/event-in-progress). The DRS-Automation-Role IAM role runs every automation step. Amazon SNS delivers alerts, Amazon S3 stores per-event audit reports, and Amazon CloudWatch captures outcome metrics.

In the DR Region, AWS DRS manages source server registration and ongoing replication. AWS DRS emits replication events only in the DR Region, where the source servers are registered. An Amazon EventBridge forwarding rule filters replication-stalled events by the STALLED state. It then sends them to the source Region for healing. Staging subnets and Amazon Elastic Block Store (Amazon EBS) volumes, managed by AWS DRS, support the replication infrastructure.

For networking, AWS Transit Gateway (which connects VPCs across Regions) carries TCP 443 (AWS DRS API and S3) and TCP 1500 (replication data) between Regions. Amazon VPC endpoints for AWS DRS and S3 keep traffic on the AWS backbone without internet exposure. An Amazon Route 53 Private Hosted Zone (for DNS resolution within your VPC) resolves endpoint names to private IPs. This removes the need for --endpoint installer flags and protects failback compatibility.

Tag and rule examples

Run these commands after you deploy the solution. Tag an instance for protection:

aws ec2 create-tags --resources i-0abc123def456 --tags Key=DR,Value=yes

Descope an instance (triggers offboarding):

aws ec2 create-tags --resources i-0abc123def456 --tags Key=DR,Value=no

Or remove the tag entirely (also triggers offboarding):

aws ec2 delete-tags --resources i-0abc123def456 --tags Key=DR

The Amazon EventBridge rule that triggers offboarding matches this pattern:

{
  "source": ["aws.tag"],
  "detail-type": ["Tag Change on Resource"],
  "detail": {
    "changed-tag-keys": ["DR"],
    "service": ["ec2"],
    "resource-type": ["instance"]
  }
}

The Amazon EventBridge rule that triggers healing filters on the STALLED state so recovery transitions are ignored:

{
  "source": ["aws.drs"],
  "detail-type": ["DRS Source Server Data Replication Stalled Change"],
  "detail": {
    "state": ["STALLED"]
  }
}

Three layers protecting the RPO

The 15-minute RPO referenced throughout this post is a customer-configured target, not an AWS service guarantee. The architecture helps protect it with three complementary layers, each covering a different failure mode.

Layer 1: OS service auto-restart (seconds). The agent service uses systemd Restart=always on Linux and Windows Service Recovery. When the process stops, the OS brings it back automatically. On Linux, systemd restarts the service almost instantly. On Windows, the first recovery action fires after a configurable delay (30 seconds by default). This layer handles agent process crashes without any automation running.

Layer 2: Amazon EventBridge heal (minutes, not seconds). If the agent disappears or can’t maintain registration, AWS DRS detects the stall and emits a replication-stalled event in the DR Region. A forwarding rule filters on the STALLED state and sends it cross-Region to the source Region’s event bus. A matching receive rule triggers the heal document.

The heal document restarts the agent first (most stalls are transient). If restart fails, it re-runs the installer in place, preserving driver state to avoid a full-disk rescan. The restart path is the faster of the two, and total time depends on your environment and on AWS DRS stall-detection latency. The reinstall path takes longer because the agent must re-establish block-level tracking. Stall-detection latency also counts against the window, because lag must accumulate before the service marks a server as stalled.

Layer 3: State Manager backstop (up to 30 minutes). The onboarding document re-evaluates DR=yes instances every 30 minutes, catching drift and edge cases that faster layers miss. This exceeds the 15-minute RPO target, so it functions as a safety net rather than the primary defense.

Layer 2 requires the Amazon EventBridge data plane in both Regions to be operational, while Layers 1 and 3 run entirely in the source Region.

Onboarding: How ongoing convergence works

State Manager targets tag:DR=yes. Instances that already have the tag and instances you tag later are included automatically, without manual registration.

The onboarding document is idempotent. It skips healthy, registered instances. For instances that need work, it checks the stand-down flag and instance state, validates the operating system (Linux or Windows), and flags unsupported architectures as TAGGED_UNSUPPORTED. If AutoInstallEnabled is false, the run is audit-only.

For actual installs, a concurrency lock (flock on Linux, a named mutex on Windows) prevents races when multiple automation runs overlap on the same instance. This lock is built into the documents and needs no configuration. The State Manager association sets MaxConcurrency to 10 and MaxErrors to 100% in templates/state-manager-association.yaml. MaxConcurrency limits how many instances are processed at once. With MaxErrors at 100%, a failure on one instance doesn’t stop the run for the rest of the fleet. For larger fleets, raise MaxConcurrency gradually and watch for AWS DRS API throttling.

The failback tag (AWSDRS:AllowLaunchingIntoThisInstance) is applied only when the agent is confirmed present. Registration is assessed cross-Region, and if an instance stays in PENDING_REGISTRATION beyond a configurable threshold (default: 3 runs), the document escalates through Amazon SNS. Each execution writes an S3 audit record and emits a CloudWatch metric.

Healing agent issues within RPO

The heal document reads the source server ARN from the event and looks up the matching EC2 instance ID with drs:DescribeSourceServers in the DR Region. It then checks the stand-down flag and the tag state. Values other than yes suppress the heal with no action and no alert.

If restart doesn’t resolve the issue, the automation re-runs the installer in place as a fallback. It doesn’t uninstall first, so the existing replication driver stays intact where possible. Reinstallation can trigger a block-level rescan whose duration scales with total disk size. On large volumes, this might temporarily exceed the RPO window while the rescan completes.

Not every stall is an agent problem. Bandwidth throttling, undersized replication servers, or staging-area disk issues can also cause stalls. The automation escalates these non-agent stalls to your operators through Amazon SNS rather than attempting agent remediation. If the Replication Agent is still not functioning after reinstall, you receive a HEAL_FAILED notification with diagnostic details.

Only the AWS DRS agent service is restarted, not the EC2 instance itself. Your workloads keep running without interruption.

Offboarding with honest billing status

When you set DR=no or delete the tag, Amazon EventBridge fires a Tag Change on Resource event. The offboarding document applies several safeguards before teardown.

Terminated-instance guard: EC2 termination strips tags, generating the same event as a deliberate descope. The document sends an alert and stops. It doesn’t delete the source server, which contains the recovery point.

Tag re-check: If the tag has been restored, the document exits.

Approval gate: If AutoOffboardEnabled is false, the document sends a notification and stops.

State recording: Before modifying resources, it captures replication state, lag duration, and last snapshot time.

Recovery-instance check: Before completing teardown, the offboarding document checks for active recovery instances. If found, it flags them in the audit report and sends an SNS alert. Recovery instances incur separate EC2 billing that persists after source server deletion.

Adaptive retry: A maximum of 10 attempts with exponential backoff handles API throttling during bulk descope.

After teardown, the document checks what actually succeeded:

Outcome Meaning
COMPLETED Source server deleted, billing halted
BILLING_STOPPED_ORPHAN Replication stopped but delete didn’t succeed. Operator must manually delete.
FAILED stop_replication didn’t succeed. Billing might still be active. Operator review recommended.
NO_SERVER Instance was not registered as an AWS DRS source server. Clean no-op.

Because each outcome reflects what actually succeeded, you know whether replication billing has stopped or whether a source server needs manual follow-up.

Security: Least-privilege IAM roles

The solution creates two IAM roles and relies on one that you provide. SSM Automation and Amazon EventBridge assume the DRS-Automation-Role to run all lifecycle actions. Its permissions cover SSM, EC2 tags, cross-Region AWS DRS calls, SNS, S3, Parameter Store, and iam:PassRole on itself. The iam:PassRole permission only allows passing this role to Systems Manager. Run Command is limited to instances tagged DR=yes. In the DR Region, the DRS-EventBridge-Forward-Role can only put events on the source Region’s default event bus.

On each EC2 instance, the instance profile from the prerequisites lets the Replication Agent and SSM Agent reach their services. The automation stores no long-lived credentials. Each role receives temporary credentials when it’s assumed. When you use private connectivity, cross-Region traffic stays on Transit Gateway and VPC endpoints.

Deploy the solution

Start in audit mode, where the onboarding document reports what it would install without changing any instance and offboarding sends a notification instead of running teardown. Review the audit reports, then turn on installation for a small set of instances before you scale to the full fleet.

To configure config.yaml

Clone the repository and change to its directory:

git clone https://github.com/aws-samples/sample-drs-agent-lifecycle-automation.git
cd sample-drs-agent-lifecycle-automation

The deployment scripts read your settings from config.yaml in the root of the repository. Set the values in the following sample before you deploy. The file in the repository also sets document names and stack names. Keep those at their defaults, because the commands in this post use the default names.

# Region configuration
source_region: us-west-1        # Region where your EC2 instances run
dr_region: us-east-2            # Region where AWS DRS replicates to
account_id: "111122223333"      # Your AWS account ID

# Observability
sns_topic_name: drs-alerts      # Existing SNS topic for notifications
amzn-s3-demo-audit_bucket: ""           # Existing S3 bucket for audit reports; empty turns off audit reports
cloudwatch_namespace: DRSAutomation

# Automation toggles (start in audit mode)
auto_install_enabled: "false"   # false = report only; true = install and repair agents
auto_offboard_enabled: "false"  # false = notify only; true = tear down on descope

# Tag configuration
dr_tag_key: DR
dr_protected_value: "yes"
dr_descope_value: "no"

# Stand-down control and schedule
stand_down_parameter: /drs/control/event-in-progress
schedule_rate: "rate(30 minutes)"

The following table describes the values you’re most likely to change.

Parameter Required Description
source_region Yes Region that hosts your EC2 instances and the automation
dr_region Yes Region where AWS DRS replicates to
account_id Yes AWS account that hosts the automation
sns_topic_name Yes Name of an existing SNS topic in the source Region
amzn-s3-demo-audit_bucket No Existing S3 bucket for JSON audit reports. Leave empty to skip them
auto_install_enabled No Set to false to report only, or true to install and repair agents
auto_offboard_enabled No Set to false to notify only, or true to run teardown when you descope an instance
dr_tag_key No EC2 tag key that controls the lifecycle (default DR)

To deploy the solution

The following steps deploy each component separately so you can see what each one creates. Run the commands from the root of the cloned repository. Replace the example account ID (111122223333) and Regions (us-west-1 and us-east-2) with your own values.

To deploy everything in one command instead, run ./scripts/deploy.sh after you edit config.yaml, and then go to the confirmation commands after step 6. The script prints the status of every stack when it finishes. Without yq, it falls back to built-in defaults, including a placeholder account ID. Use either the script or the individual steps, not both.

  1. Deploy the IAM role stack. The template creates a role with an explicit name (DRS-Automation-Role), so CAPABILITY_NAMED_IAM is required.
    aws cloudformation deploy \
      --template-file templates/iam-roles.yaml \
      --stack-name drs-automation-iam \
      --capabilities CAPABILITY_NAMED_IAM \
      --region us-west-1 \
      --parameter-overrides \
        AccountId=111122223333 \
        SourceRegion=us-west-1 \
        DRRegion=us-east-2 \
        SNSTopicName=drs-alerts

  2. Register the three SSM Automation documents. The script reads source_region from config.yaml and creates the documents from the documents/ folder on the first run. On later runs, it publishes a new default version of any document that changed.
    ./scripts/register-documents.sh

  3. Deploy the Amazon EventBridge rules in the source Region. This stack creates the tag-change rule that starts offboarding and the rule that starts healing. It uses the existing DRS-Automation-Role, so it doesn’t need CAPABILITY_NAMED_IAM.
    aws cloudformation deploy \
      --template-file templates/eventbridge-source.yaml \
      --stack-name drs-eventbridge-source \
      --region us-west-1 \
      --parameter-overrides \
        AutomationRoleArn=arn:aws:iam::111122223333:role/DRS-Automation-Role \
        TargetRegion=us-east-2 \
        SNSTopicArn=arn:aws:sns:us-west-1:111122223333:drs-alerts \
        AutoOffboardEnabled=false

  4. Deploy the forwarding rule in the DR Region. This stack creates DRS-EventBridge-Forward-Role, which lets the rule send stalled events to the source Region’s event bus, so CAPABILITY_NAMED_IAM is required.
    aws cloudformation deploy \
      --template-file templates/eventbridge-dr.yaml \
      --stack-name drs-eventbridge-dr \
      --capabilities CAPABILITY_NAMED_IAM \
      --region us-east-2 \
      --parameter-overrides \
        SourceRegion=us-west-1 \
        AccountId=111122223333

  5. Create the stand-down flag in Parameter Store with a value of false. The script reads the parameter name and Region from config.yaml and doesn’t overwrite an existing value.
    ./scripts/init-parameters.sh

    If you prefer not to use the script, run the following command instead:

    aws ssm put-parameter --name /drs/control/event-in-progress \
      --value false --type String --region us-west-1

  6. Deploy the State Manager association in audit mode. The association runs once as soon as it’s created and then every 30 minutes.
    aws cloudformation deploy \
      --template-file templates/state-manager-association.yaml \
      --stack-name drs-state-manager \
      --region us-west-1 \
      --parameter-overrides \
        AutomationRoleArn=arn:aws:iam::111122223333:role/DRS-Automation-Role \
        TargetRegion=us-east-2 \
        AutoInstallEnabled=false \
        SNSTopicArn=arn:aws:sns:us-west-1:111122223333:drs-alerts

To confirm the deployment, run the following commands:

aws cloudformation describe-stacks --region us-west-1 \
  --query "Stacks[?starts_with(StackName, 'drs-')].[StackName,StackStatus]" --output table

aws cloudformation describe-stacks --stack-name drs-eventbridge-dr --region us-east-2 \
  --query "Stacks[0].StackStatus" --output text

aws events list-rules --name-prefix DRS- --region us-west-1 --query "Rules[].Name"

aws events list-rules --name-prefix DRS- --region us-east-2 --query "Rules[].Name"

aws ssm list-documents --filters Key=Owner,Values=Self --region us-west-1 \
  --query "DocumentIdentifiers[?starts_with(Name, 'DRS-Agent-')].Name"

aws ssm get-parameter --name /drs/control/event-in-progress --region us-west-1 \
  --query "Parameter.Value" --output text

A successful deployment shows the following results:

  • All four stacks show CREATE_COMPLETE, or UPDATE_COMPLETE after a re-run.
  • The source Region lists the DRS-Tag-Change-Offboard and DRS-Stalled-Heal-Receive rules.
  • The DR Region lists the DRS-Stalled-Forward rule.
  • The source Region lists the DRS-Agent-Onboard, DRS-Agent-Heal, and DRS-Agent-Offboard documents.
  • The stand-down flag returns false.
  • In the AWS Systems Manager console, State Manager lists DRS-Agent-Onboard-Association.

When you’re ready to turn on installation, set auto_install_enabled: "true" in config.yaml and deploy the State Manager stack again with AutoInstallEnabled=true:

aws cloudformation deploy \
  --template-file templates/state-manager-association.yaml \
  --stack-name drs-state-manager \
  --region us-west-1 \
  --parameter-overrides \
    AutomationRoleArn=arn:aws:iam::111122223333:role/DRS-Automation-Role \
    TargetRegion=us-east-2 \
    AutoInstallEnabled=true \
    SNSTopicArn=arn:aws:sns:us-west-1:111122223333:drs-alerts

To turn on teardown, set auto_offboard_enabled: "true" and deploy the source Region Amazon EventBridge stack again with AutoOffboardEnabled=true:

aws cloudformation deploy \
  --template-file templates/eventbridge-source.yaml \
  --stack-name drs-eventbridge-source \
  --region us-west-1 \
  --parameter-overrides \
    AutomationRoleArn=arn:aws:iam::111122223333:role/DRS-Automation-Role \
    TargetRegion=us-east-2 \
    SNSTopicArn=arn:aws:sns:us-west-1:111122223333:drs-alerts \
    AutoOffboardEnabled=true

Safety guards prevent unintended actions

The following table lists the safety guards across the three automation documents. The stand-down flag and the tag value allow-list apply to every document. The terminated-instance guard and honest billing status protect offboarding, and the remaining guards protect onboarding and healing.

Guard Prevents
DR-event stand-down Acting during failover/failback
Terminated-instance guard Deleting a recovery point on instance termination
Reverse-direction detect Overwriting an AWS DRS-managed failback agent
Concurrency lock Race conditions from overlapping runs
AutoInstallEnabled gate Unintended installs in audit-first deployments
OS pre-check Running installer on incompatible operating system
Honest billing status Reporting “billing stopped” when teardown partially completed
Tag value allow-list A typo triggering the wrong lifecycle action
Agent-presence-gated tagging Applying failback tag to an agent-less instance

To pause the automation during a declared DR event:

aws ssm put-parameter --name /drs/control/event-in-progress \
  --value true --type String --overwrite --region us-west-1

To resume after the event:

aws ssm put-parameter --name /drs/control/event-in-progress \
  --value false --type String --overwrite --region us-west-1

Monitoring and observability

The three SSM Automation documents produce telemetry across three channels, each tuned for a different audience.

Amazon SNS notifications go to the on-call team. Onboarding stays quiet unless an instance needs intervention. Heal notifies on both success and intervention-needed, because a successful auto-heal still tells you a real issue occurred and was resolved. Offboarding sends a notification at each stage: start, complete, orphan, incomplete, and approval-needed.

Amazon S3 audit reports serve compliance and troubleshooting. One JSON object per lifecycle event at s3://<amzn-s3-demo-audit_bucket>/drs/<account>/<instance>/<event>-<timestamp>.json captures instance ID, host name, platform, source server ID, status, and pre-teardown replication state. To control storage costs, add a lifecycle rule to the bucket (for example, expire objects under drs/ after 90 days).

Amazon CloudWatch metrics power fleet dashboards. An Outcome metric (1=handled, 0=needs attention) dimensioned by event type provides at-a-glance fleet health.

Clean up

Removing the automation doesn’t stop replication. Instances tagged DR=yes keep replicating until you stop replication through the AWS DRS console or API. To remove the automation infrastructure, run the following commands:

  1. Delete the State Manager association and the source Region Amazon EventBridge stacks.
    aws cloudformation delete-stack --stack-name drs-state-manager --region us-west-1
    aws cloudformation delete-stack --stack-name drs-eventbridge-source --region us-west-1

  2. Delete the Amazon EventBridge forwarding stack in the DR Region.
    aws cloudformation delete-stack --stack-name drs-eventbridge-dr --region us-east-2

  3. Delete the SSM Automation documents and the stand-down parameter.
    aws ssm delete-document --name DRS-Agent-Onboard --region us-west-1
    aws ssm delete-document --name DRS-Agent-Heal --region us-west-1
    aws ssm delete-document --name DRS-Agent-Offboard --region us-west-1
    aws ssm delete-parameter --name /drs/control/event-in-progress --region us-west-1

  4. After the other stacks are deleted, delete the IAM role stack.
    aws cloudformation delete-stack --stack-name drs-automation-iam --region us-west-1

  5. (Optional) If you created the SNS topic and S3 bucket only for this solution, delete them.

Conclusion

With a DR=yes tag in place, onboarding keeps the agent installed and registered, and healing restarts or reinstalls it when replication stalls. When you descope an instance, offboarding stops replication, removes the source server, and writes a JSON audit record to Amazon S3. That record tells you whether billing stopped or whether a partial teardown needs an operator’s follow-up. The whole lifecycle runs from one tag, without function code for your team to maintain.

The June 2023 post Deploying AWS Elastic Disaster Recovery at scale with AWS Systems Manager covered the initial install. This solution builds on it with ongoing health checks and offboarding.

Next steps

Start by cloning the repository and deploying it in audit mode in a test account. Tag a few instances with DR=yes and let onboarding run for a day. The audit reports in Amazon S3 show what the automation would install or repair on each instance, without changing anything. When the reports match what you expect, turn on installation for those instances. Then set DR=no on one of them to check the offboarding notification before you turn on teardown. If you have questions or improvements, open an issue in the GitHub repository.

Additional resources


About the authors

Manisha Yadav

Manisha Yadav

Manisha is a Delivery Consultant with AWS Professional Services in Gurugram, India. She helps enterprise customers move workloads to AWS and then keep them recoverable, mostly with AWS Elastic Disaster Recovery and AWS Systems Manager. The automation in this post started as her answer to managing Replication Agents one instance at a time.

Danish Shamim

Danish Shamim

Danish is a Senior Delivery Consultant at AWS Professional Services, where he focuses on disaster recovery and large migrations. He helps enterprise customers protect and move their workloads, and he builds the automation and runbooks that keep those solutions running in production.

Vimal Bhati

Vimal Bhati

Vimal helps AWS customers move workloads to AWS as a Delivery Consultant at AWS Professional Services. He works mostly on Infrastructure as Code with AWS CloudFormation, and he contributed the deployment tooling for this solution.

The collective thoughts of the interwebz