{"id":296,"date":"2026-09-11T11:29:57","date_gmt":"2026-09-11T11:29:57","guid":{"rendered":"https:\/\/www.codelogicx.com\/blog\/?p=296"},"modified":"2026-09-11T11:55:30","modified_gmt":"2026-09-11T11:55:30","slug":"aws-alb-debugging","status":"publish","type":"post","link":"https:\/\/www.codelogicx.com\/blog\/aws-alb-debugging\/","title":{"rendered":"Two-Line Fix Took Three Days: How We Debugged AWS ALB Issues"},"content":{"rendered":"<p><span data-contrast=\"auto\">This blog aims to share the lessons learned from a deceptively simple security remediation task that turned into a three-day investigation across multiple layers of cloud infrastructure. Through the journey of disabling port 80 on a shared Application Load Balancer (ALB), uncovering a silent IAM role fallback, and identifying an overlooked health check dependency, readers will gain practical insights into troubleshooting complex AWS environments. <\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This content\u00a0emphasizes the importance of understanding shared architecture, validating assumptions against actual deployments, and recognizing how small configuration changes can create unexpected downstream impacts. <\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Ultimately, it serves as a reminder that effective debugging is often less about fixing code and more about uncovering hidden relationships within modern cloud systems.\u00a0<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Let&#8217;s dive deep into\u00a0the steps\u00a0how two low-severity security issues exposed:\u00a0\u00a0\u00a0<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">The Issue flagged during Penetration Testing:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"none\">It arrived as one of the least threatening items on the board. A penetration test had flagged two findings:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><b><span data-contrast=\"none\">Insecure Ports in Use.<\/span><\/b><span data-contrast=\"none\"> Endpoints are reachable over plain HTTP on port 80.Requests are 301-redirected to HTTPS, but the initial connection is unencrypted.<\/span>\r\n\r\n<b><span data-contrast=\"none\">Server Version Disclosure.<\/span><\/b><span data-contrast=\"none\"> HTTP responses expose <\/span><span data-contrast=\"none\">Server:awselb\/2.0<\/span><span data-contrast=\"none\">,disclosing the load balancer technology.<\/span><\/pre>\n<p><span data-contrast=\"none\">Two fixes. One removes a listener. One sets a boolean. Both are documented by AWS in a single paragraph each. I estimated an afternoon.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">This is what happened.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">At first glance, this looked like routine security housekeeping.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">The remediation plan was straightforward. One finding could be addressed by removing a listener. The other required flipping a boolean configuration value. AWS documentation covered both changes in a few short paragraphs. Nothing about the work suggested risk, complexity, or even much effort.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">I estimated an afternoon, but\u00a0the\u00a0entire task consumed three days.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">What began as two minor hardening changes led to the discovery of a production IAM misconfiguration that had been quietly active for 93 days. Along the way, a seemingly unrelated CloudWatch alarm started firing and triggered another investigation. That alarm, as it turned out, was tied to a health check that nobody had ever actually validated.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">By the end of it, the penetration test findings were the easiest part of the entire exercise.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">This is the story of how two low-severity security issues exposed a chain of assumptions hiding in plain sight, and why some of the simplest infrastructure changes can reveal the most interesting problems.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">In this blog, we have segregated the blog in\u00a0<\/span><b><i><span data-contrast=\"auto\">Different Acts\u00a0for better understanding.\u00a0<\/span><\/i><\/b><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;134245417&quot;:true,&quot;201341983&quot;:0,&quot;335551550&quot;:0,&quot;335551620&quot;:0,&quot;335559738&quot;:210,&quot;335559739&quot;:210,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Act One: The Shared Load Balancer<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><strong>The first fix looked trivial. In the Kubernetes Ingress manifest:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\"># Before<\/span>\r\n<span data-contrast=\"none\">alb.ingress.kubernetes.io\/listen-ports: '[{\"HTTP\": 80}, {\"HTTPS\":443}]'<\/span><span data-contrast=\"none\">\r\nalb.ingress.kubernetes.io\/ssl-redirect: '443'<\/span>\r\n<span data-contrast=\"none\"># After<\/span> \r\n<span data-contrast=\"none\">alb.ingress.kubernetes.io\/listen-ports: '[{\"HTTPS\":443}]'<\/span><\/pre>\n<p><span data-contrast=\"none\">Delete the redirect, drop the listener. Deploy. Done.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">Except port 80 stayed open.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The reason was a single annotation I&#8217;d skimmed past:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">alb.ingress.kubernetes.io\/group.name: ingress-backend-group<\/span><\/pre>\n<p><span data-contrast=\"none\">The AWS Load Balancer Controller supports <\/span><b><span data-contrast=\"none\">ingress groups. <\/span><\/b><span data-contrast=\"none\">These<\/span><span data-contrast=\"none\"> multiple Ingress resources\u00a0that are potentially across different namespaces and different Git repositories, merge into a single physical ALB. It&#8217;s an excellent cost optimization. It&#8217;s also a footgun if you don&#8217;t know it&#8217;s there.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The controller computes the union of every group member&#8217;s requirement. If <\/span><i><span data-contrast=\"none\">any<\/span><\/i><span data-contrast=\"none\"> ingress in the group asks for port 80, the listener exists\u00a0for everyone.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-347 size-full\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/01-shared-alb-ingress-group.png\" alt=\"\" width=\"2663\" height=\"925\" \/><\/p>\n<p><span data-contrast=\"none\">I had fixed one repository. There were four more and\u00a0one ingress that existed in no repository at all, applied years earlier with <\/span><span data-contrast=\"none\">kubectl apply<\/span><span data-contrast=\"none\"> and never captured in Git.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The lesson here is not &#8220;read your annotations.&#8221; It&#8217;s that <\/span><b><span data-contrast=\"none\">infrastructure boundaries and repository boundaries are different things<\/span><\/b><span data-contrast=\"none\">, and nothing in a code review will tell you that the file you&#8217;re editing shares state with four repos you&#8217;ve never opened.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">Finding them required stepping outside Git entirely and asking the cluster:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">kubectl get ingress -A -o json | jq -r '<\/span>\r\n<span data-contrast=\"none\">\u00a0 .items[] |<\/span>\r\n<span data-contrast=\"none\">\u00a0 select(.metadata.annotations[\"alb.ingress.kubernetes.io\/group.name\"] == \"ingress-backend-group\") |<\/span>\r\n<span data-contrast=\"none\">\u00a0 \"\\(.metadata.name)\\t\\(.metadata.annotations[\"alb.ingress.kubernetes.io\/listen-ports\"])\"<\/span><\/pre>\n<p><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:100}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">One query, complete answer. I should have run it on\u00a0the first day.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p aria-level=\"1\"><span data-contrast=\"none\">Act Two: The Silent Fallback<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">With every manifest corrected and deployed, <\/span><b><span data-contrast=\"none\">port 80<\/span><\/b><span data-contrast=\"none\"> still would not close.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The controller logs explained why, and the explanation was more interesting than the problem:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">UnauthorizedOperation: You are not authorized to perform this operation.<\/span>\r\n<span data-contrast=\"none\">User: arn:aws:sts::REDACTED:assumed-role\/eksctl-...-NodeInstanceRole-...\/i-...<\/span>\r\n<span data-contrast=\"none\">is not authorized to perform: ec2:RevokeSecurityGroupIngress<\/span><\/pre>\n<p><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:100}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">Removing a listener also means revoking the corresponding security group rule. The controller tried, but AWS refused.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The interesting part is the principal. The controller was making that call as the <\/span><b><span data-contrast=\"none\">EC2 node instance role<\/span><\/b><span data-contrast=\"none\">\u00a0the generic identity attached to the worker node\u00a0not as its own dedicated IAM role.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">This is the failure mode of IRSA (IAM Roles for Service Accounts). When IRSA is wired correctly, a webhook injects credentials into the pod at creation time:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-341 aligncenter\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/Screenshot-2026-09-11-140121.png\" alt=\"\" width=\"1538\" height=\"216\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-349 size-full\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/03-irsa-not-applied.png\" alt=\"\" width=\"2624\" height=\"443\" \/><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">The Critical Detailing: <\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:true,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<p><b><span data-contrast=\"none\">There is no error when this fails.<\/span><\/b><span data-contrast=\"none\"> The AWS SDK credential chain is designed to fall through gracefully. IRSA credentials absent? Try environment variables. Absent? Try instance metadata. Something always answers. The pod starts, reports healthy, and runs indefinitely with the wrong identity\u00a0until it attempts an operation the fallback role can&#8217;t perform.\u00a0<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">In this case, that\u00a0took 93 days.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><strong>The diagnosis includes three checks:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\"># 1. Is the annotation on the ServiceAccount?\u00a0 (It was.)<\/span>\r\n<span data-contrast=\"none\">kubectl get sa aws-load-balancer-controller -n kube-system \\<\/span>\r\n<span data-contrast=\"none\">\u00a0 -o jsonpath='{.metadata.annotations.eks\\.amazonaws\\.com\/role-arn}'<\/span>\r\n<span data-contrast=\"none\"># 2. Does the IAM role have the permission?\u00a0 (It did.)<\/span>\r\n<span data-contrast=\"none\">aws iam get-policy-version --policy-arn &lt;policy&gt; --version-id &lt;v&gt;<\/span>\r\n<span data-contrast=\"none\"># 3. Does the running pod actually have IRSA credentials?\u00a0 (It did not.)<\/span>\r\n<span data-contrast=\"none\">kubectl get pod &lt;controller-pod&gt; -n kube-system \\<\/span>\r\n<span data-contrast=\"none\">\u00a0 -o jsonpath='{.spec.containers[0].env[*].name}' | tr ' ' '\\n' | grep AWS<\/span>\r\n<span data-contrast=\"none\"># \u2192 empty<\/span><\/pre>\n<p><span data-contrast=\"none\">Configurations\u00a0are correct. Permissions correct. Running process wrong. The annotation had been added <\/span><i><span data-contrast=\"none\">after<\/span><\/i><span data-contrast=\"none\"> the pod was created, and nothing had restarted it since.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Fixing it without a gap<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"none\">The controller was running a single replica. A naive <\/span><span data-contrast=\"none\">kubectl rollout restart<\/span><span data-contrast=\"none\"> would leave a window with no controller at all. Instead:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-350 aligncenter\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/04-identity-gated-restart-flow.png\" alt=\"\" width=\"1285\" height=\"2265\" \/><\/p>\n<p><span data-contrast=\"none\">The explicit stop-gate matters. If the new pod comes up <\/span><i><span data-contrast=\"none\">also<\/span><\/i><span data-contrast=\"none\"> lacking the token volume, the webhook isn&#8217;t firing and restarting again will not help. All\u00a0you\u00a0would\u00a0just be cycling pods while the real problem sits elsewhere. Encoding &#8220;if this check fails, stop&#8221; into the runbook prevents the instinct to try again harder.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The restart worked. The controller assumed its correct role, reconciled, removed the listener, revoked the security group rule. It also silently fixed a second permission error nobody had reported\u00a0the same fallback had been blocking AWS Shield subscription checks for the entire 93 days.\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Act Three: Two Documentation Pages, One Truth<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><strong>The second finding is- suppressing Server: awselb\/2.0 \u2014 had a documented one-line fix:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\">routing.http.response.server.enabled = false<\/span><\/pre>\n<p><span data-contrast=\"none\">The question was where to put it. And this is where things got genuinely confusing, because <\/span><b><span data-contrast=\"none\">AWS documents this attribute in two different places with two different APIs.<\/span><\/b><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">One page shows it set via <\/span><span data-contrast=\"none\">modify-load-balancer-attributes<\/span><span data-contrast=\"none\">. Another shows it under listener attributes, set via <\/span><span data-contrast=\"none\">modify-listener-attributes<\/span><span data-contrast=\"none\">. Both are official AWS documentation.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><strong>The first attempt placed it as a load-balancer attribute. AWS rejected it:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\">ValidationError: Load balancer attribute key<\/span>\r\n<span data-contrast=\"none\">'routing.http.response.server.enabled' is not recognized<\/span><\/pre>\n<p><span data-contrast=\"none\">Worse, because the value was embedded in an Ingress annotation, the controller retried the rejected call on <\/span><b><span data-contrast=\"none\">every reconciliation loop<\/span><\/b><span data-contrast=\"none\"> \u2014 and a failing reconcile blocks <\/span><i><span data-contrast=\"none\">all<\/span><\/i><span data-contrast=\"none\"> other pending changes for that ingress group. The invalid attribute for finding \u00a73.6 was actively preventing the fix for \u00a73.5 from applying.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">Two findings, tangled together by a shared reconciliation loop.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The resolution was to stop reading documentation and ask the environment directly:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">aws elbv2 describe-listener-attributes --listener-arn &lt;443-listener&gt;<\/span><\/pre>\n<pre><span data-contrast=\"none\">{<\/span>\r\n<span data-contrast=\"none\">\u00a0 \"Key\": \"routing.http.response.server.enabled\",<\/span>\r\n<span data-contrast=\"none\">\u00a0 \"Value\": \"true\"<\/span>\r\n<span data-contrast=\"none\">}<\/span><\/pre>\n<p><span data-contrast=\"none\">There it was. A <\/span><b><span data-contrast=\"none\">listener<\/span><\/b><span data-contrast=\"none\"> attribute, on this ALB, in this region, right now. No ambiguity, no interpretation.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><b><span data-contrast=\"none\">When documentation conflicts, the environment is the source of truth.<\/span><\/b><span data-contrast=\"none\"> A <\/span><span data-contrast=\"none\">describe-*<\/span><span data-contrast=\"none\"> call takes two seconds and settles arguments that documentation, blog posts, and automated code review cannot.<\/span><\/pre>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">The controller version constraint<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"none\">Knowing the correct placement didn&#8217;t mean it could be managed declaratively. The installed controller version predated support for the <\/span><span data-contrast=\"none\">listener-attributes<\/span><span data-contrast=\"none\"> annotation \u2014 the correct annotation would simply be ignored. <\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><em>So, three options existed:\u00a0<\/em><\/p>\n\n<table id=\"tablepress-4\" class=\"tablepress tablepress-id-4\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Approach <\/th><th class=\"column-2\">Works today<\/th><th class=\"column-3\">GitOps-managed<\/th><th class=\"column-4\">Self-healing<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\">Load-balancer attribute annotation<\/td><td class=\"column-2\">No \u2014 API rejects it<\/td><td class=\"column-3\"><\/td><td class=\"column-4\"><\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\">Listener attribute annotation<\/td><td class=\"column-2\">No \u2014 controller too old<\/td><td class=\"column-3\">Yes<\/td><td class=\"column-4\">Yes<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\">Direct CLI \/ console on listener<\/td><td class=\"column-2\">Yes<\/td><td class=\"column-3\">No<\/td><td class=\"column-4\">No<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-4 from cache -->\n<p><span data-contrast=\"none\">The pragmatic choice was the third, with an explicit follow-up to upgrade the controller and migrate to the declarative path.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">But applying configuration outside GitOps to a controller-managed resource raises an obvious question: <\/span><b><span data-contrast=\"none\">will the controller revert it?<\/span><\/b><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><strong>Rather than assume, I tested it. A throwaway annotation forces a full reconcile:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\">kubectl annotate ingress &lt;name&gt; reconcile-test=\"$(date +%s)\" --overwrite<\/span>\r\n<span data-contrast=\"none\">sleep 90<\/span>\r\n<span data-contrast=\"none\"># re-check the attribute<\/span>\r\n<span data-contrast=\"none\">kubectl annotate ingress &lt;name&gt; reconcile-test-<\/span><\/pre>\n<p><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:100}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The value survived. Because the controller version doesn&#8217;t manage listener attributes at all, it leaves them untouched\u00a0the same limitation that prevented the declarative fix also guaranteed the manual one would persist.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">That&#8217;s a satisfying symmetry, but the important part is that it was <\/span><b><span data-contrast=\"none\">verified rather than assumed<\/span><\/b><span data-contrast=\"none\">. &#8220;It&#8217;ll probably be fine&#8221; is not a deployment strategy.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Act Four: The Alarm That Wasn&#8217;t Our Fault (But Looked Like It)<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><strong>Days later, a CloudWatch alarm fired:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\">Production-API-NoHealthyTargets<\/span>\r\n<span data-contrast=\"none\">HealthyHostCount &lt; 1 for 2 datapoints<\/span><\/pre>\n<p><span data-contrast=\"none\">Zero healthy targets on a production API target group \u2014 and it belonged to one of the exact services I&#8217;d modified.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The obvious conclusion was that my change had broken it. The obvious conclusion was wrong, and the process of establishing that is worth more than the fix.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\">What the evidence showed:<\/h2>\n<p><span data-contrast=\"none\">Pods were <\/span><span data-contrast=\"none\">1\/1 Running<\/span><span data-contrast=\"none\">, 43 hours old, no restarts. The Kubernetes liveness probe was passing. But the ALB reported every target as:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">Target.ResponseCodeMismatch: Health checks failed with these codes: [302]<\/span><\/pre>\n<p><strong>Curling the application directly from inside the pod:\u00a0<\/strong><\/p>\n<pre><span data-contrast=\"none\">$ curl -sI http:\/\/localhost:3005\/<\/span>\r\n<span data-contrast=\"none\">HTTP\/1.1 302 Found<\/span>\r\n<span data-contrast=\"none\">Location: http:\/\/localhost:3005\/public-api\/docs<\/span>\r\n<span data-contrast=\"none\">$ curl -sI http:\/\/localhost:3005\/public-api\/docs<\/span>\r\n<span data-contrast=\"none\">HTTP\/1.1 200 OK<\/span><\/pre>\n<p><span data-contrast=\"none\">The application redirects <\/span><span data-contrast=\"none\">\/<\/span><span data-contrast=\"none\"> to its doc&#8217;s page. It always has. The ALB health check targeted <\/span><span data-contrast=\"none\">\/<\/span><span data-contrast=\"none\"> and accepted only <\/span><span data-contrast=\"none\">200<\/span><span data-contrast=\"none\">. That mismatch had existed since the service was deployed.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-351 aligncenter\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/05-health-check-mismatch.png\" alt=\"\" width=\"1358\" height=\"983\" \/><\/p>\n<p><span data-contrast=\"none\">Two health checks, same application, opposite conclusions \u2014 because they probed different paths.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h3 aria-level=\"2\"><span data-contrast=\"none\">Now the question arises why it fired that day?\u00a0<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:true,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<p><span data-contrast=\"none\">The alarm history showed <\/span><span data-contrast=\"none\">INSUFFICIENT_DATA \u2192 ALARM<\/span><span data-contrast=\"none\"> with the reason <\/span><i><span data-contrast=\"none\">&#8220;Unchecked: Initial alarm creation.&#8221;<\/span><\/i><span data-contrast=\"none\"> The alarm had been created that morning as part of a compliance monitoring rollout. The misconfiguration was old; the observation was new.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The fix was to align the ALB health check with the path the liveness probe already used and had already validated:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><span data-contrast=\"none\">alb.ingress.kubernetes.io\/healthcheck-path: '\/public-api\/docs'<\/span><\/pre>\n<p><span data-contrast=\"none\">Targets went healthy in under a minute.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">There was a tempting shortcut here: set <\/span><span data-contrast=\"none\">success-codes: &#8220;200,302&#8221;<\/span><span data-contrast=\"none\"> and move on. It would have cleared the alarm just as fast. But it would also mean the ALB considers a target healthy whenever <\/span><i><span data-contrast=\"none\">anything<\/span><\/i><span data-contrast=\"none\"> responds with a redirect \u2014 including a broken application whose redirect middleware still works. The alarm would go quiet while the signal quality got worse.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<pre><b><span data-contrast=\"none\">Clearing an alert and fixing a problem are different objectives.<\/span><\/b><span data-contrast=\"none\"> They frequently have different solutions, and the faster one is usually the wrong one.<\/span><\/pre>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Let&#8217;s have a look at the Comprehensive Diagram:<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-352 aligncenter\" src=\"https:\/\/www.codelogicx.com\/blog\/wp-content\/uploads\/2026\/09\/06-full-journey-map.png\" alt=\"Flowchart of troubleshooting network issues\" width=\"843\" height=\"2656\" \/><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Few Important Anecdotes Which I Discussed with Myself Before Starting? <\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:2,&quot;335551620&quot;:2,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><b><span data-contrast=\"none\">Map the blast radius before editing anything.<\/span><\/b><span data-contrast=\"none\"> A shared <\/span><span data-contrast=\"none\">group.name<\/span><span data-contrast=\"none\"> means your one-file change has dependencies in repositories you haven&#8217;t opened. Query the live cluster for everything sharing that group before touching the first manifest.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">A correct annotation is not a working configuration.<\/span><\/b><span data-contrast=\"none\"> IRSA annotations, node labels, and similar settings only take effect at pod creation. A configuration added after the pod started is invisible until something restarts. Verify the <\/span><i><span data-contrast=\"none\">running process<\/span><\/i><span data-contrast=\"none\">, not just the desired state \u2014 check for the token volume and the environment variables, not the annotation.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Silent fallbacks are the expensive kind of failure.<\/span><\/b><span data-contrast=\"none\"> The AWS credential chain is designed never to fail loudly. That&#8217;s convenient until it means a workload has been running with the wrong identity for three months. Anywhere a system has a graceful fallback, ask what happens when the primary path silently doesn&#8217;t work.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Query the environment before trusting the documentation.<\/span><\/b><span data-contrast=\"none\"> Vendor docs can be internally inconsistent. Automated reviewers can confidently state opposite things on consecutive passes. A single <\/span><span data-contrast=\"none\">describe-*<\/span><span data-contrast=\"none\"> call is definitive for your account, your region, your resource, right now.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Test persistence for anything applied outside GitOps.<\/span><\/b><span data-contrast=\"none\"> If you must configure something imperatively on a controller-managed resource, force a reconcile and confirm it survives. Then document it with a re-apply procedure, because the next person will not know it exists.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Investigate before accepting blame.<\/span><\/b><span data-contrast=\"none\"> When an alarm fires shortly after your change, the correlation is suggestive but not conclusive. In this case a five-minute investigation showed a longstanding misconfiguration surfaced by a brand-new alarm. Had I assumed causation, I might have reverted a correct security fix to &#8220;resolve&#8221; an unrelated problem.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><b><span data-contrast=\"none\">Every genuinely hard bug is at least two bugs.<\/span><\/b><span data-contrast=\"none\"> The port-80 change was blocked by an IAM issue, which was compounded by an invalid attribute from the <\/span><i><span data-contrast=\"none\">other<\/span><\/i><span data-contrast=\"none\"> ticket poisoning the same reconciliation loop. Neither would have been especially difficult alone. Interleaved, each one obscured the other&#8217;s symptoms.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"1\"><span data-contrast=\"none\">Conclusion:\u00a0<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;134245418&quot;:false,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:240,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"none\">The final diff across all of it is about a dozen lines. Two annotations changed, one deleted, one health check path corrected.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">What produced those dozen lines was: enumerating an infrastructure boundary that didn&#8217;t match the repository boundary, diagnosing an identity fallback that had been silently active for three months, resolving contradictory vendor documentation empirically, and correctly declining to take the blame for an unrelated alarm.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">The infrastructure was not broken. It was working exactly as configured. The configuration just encoded several assumptions that had quietly stopped being true\u00a0and nothing in the system was designed to tell anyone.<\/span><span data-ccp-props=\"{&quot;134245417&quot;:true,&quot;201341983&quot;:1,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559738&quot;:0,&quot;335559739&quot;:150,&quot;335559740&quot;:300}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"none\">That&#8217;s most of what infrastructure work is. The fix is rarely the hard part.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog aims to share the lessons learned from a deceptively simple security remediation task that turned into a three-day investigation across multiple layers of cloud infrastructure. Through the journey of disabling port 80 on a shared Application Load Balancer (ALB), uncovering a silent IAM role fallback, and identifying an overlooked health check dependency, readers &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.codelogicx.com\/blog\/aws-alb-debugging\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Two-Line Fix Took Three Days: How We Debugged AWS ALB Issues&#8221;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":355,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-296","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":18,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":361,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions\/361"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/media\/355"}],"wp:attachment":[{"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codelogicx.com\/blog\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}