<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BrainTally</title>
    <description>The latest articles on DEV Community by BrainTally (@cloudlative).</description>
    <link>https://dev.to/cloudlative</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4190308%2F80ce4836-396e-4d09-bc3d-8827b8556154.png</url>
      <title>DEV Community: BrainTally</title>
      <link>https://dev.to/cloudlative</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cloudlative"/>
    <language>en</language>
    <item>
      <title>A practical Kubernetes troubleshooting checklist</title>
      <dc:creator>BrainTally</dc:creator>
      <pubDate>Sat, 17 Oct 2026 11:59:47 +0000</pubDate>
      <link>https://dev.to/cloudlative/a-practical-kubernetes-troubleshooting-checklist-fl8</link>
      <guid>https://dev.to/cloudlative/a-practical-kubernetes-troubleshooting-checklist-fl8</guid>
      <description>&lt;p&gt;A pod is not running, or is running but serving errors, and you have a terminal and a few minutes. Trying things at random wastes them. Kubernetes already records most of what you need; the skill is reading it in the right order. This checklist moves from the cheapest, most informative checks to the more expensive ones. Commands assume &lt;code&gt;kubectl&lt;/code&gt; is pointed at the right cluster and namespace, so confirm that first with &lt;code&gt;kubectl config current-context&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: look at the state
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl get deploy,rs,svc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;STATUS&lt;/code&gt;, &lt;code&gt;READY&lt;/code&gt; and &lt;code&gt;RESTARTS&lt;/code&gt; columns tell you which branch of this checklist to follow. The &lt;code&gt;-o wide&lt;/code&gt; output also shows which node each pod landed on, which matters later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: read the status like a diagnosis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;What it usually means&lt;/th&gt;
&lt;th&gt;Next check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pending&lt;/td&gt;
&lt;td&gt;The scheduler has not placed the pod&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;describe pod&lt;/code&gt;, events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ContainerCreating&lt;/td&gt;
&lt;td&gt;Image pull, volume mount or network setup in progress or stuck&lt;/td&gt;
&lt;td&gt;events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ImagePullBackOff / ErrImagePull&lt;/td&gt;
&lt;td&gt;Wrong image name or tag, missing registry credentials, registry unreachable&lt;/td&gt;
&lt;td&gt;events, image reference, pull secret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CrashLoopBackOff&lt;/td&gt;
&lt;td&gt;The container starts, exits, and is restarted with growing delays&lt;/td&gt;
&lt;td&gt;previous logs, exit code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CreateContainerConfigError&lt;/td&gt;
&lt;td&gt;A referenced ConfigMap or Secret (or key) is missing&lt;/td&gt;
&lt;td&gt;events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running but not Ready&lt;/td&gt;
&lt;td&gt;Readiness probe failing&lt;/td&gt;
&lt;td&gt;probe config, logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evicted&lt;/td&gt;
&lt;td&gt;The node removed the pod, often under resource pressure&lt;/td&gt;
&lt;td&gt;node conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note that "CrashLoopBackOff" is not itself a cause. It is the kubelet backing off between restarts of a container that keeps exiting. By default the delay starts at 10 seconds, doubles each time, and is capped at 5 minutes; it resets after the container runs for 10 minutes without problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: read the events
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe pod NAME
kubectl get events &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.lastTimestamp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Events&lt;/code&gt; section at the bottom of &lt;code&gt;describe&lt;/code&gt; is usually where the answer is. For a Pending pod, look for scheduler messages such as insufficient CPU or memory, unmatched node selectors or affinity, untolerated taints, or unbound PersistentVolumeClaims. Events are kept for one hour by default (&lt;code&gt;--event-ttl&lt;/code&gt;), so check them early.&lt;/p&gt;

&lt;p&gt;Also in &lt;code&gt;describe&lt;/code&gt;, under &lt;code&gt;Containers&lt;/code&gt;, read &lt;code&gt;State&lt;/code&gt;, &lt;code&gt;Last State&lt;/code&gt;, &lt;code&gt;Reason&lt;/code&gt; and &lt;code&gt;Exit Code&lt;/code&gt;. &lt;code&gt;OOMKilled&lt;/code&gt; means the container exceeded its memory limit. Exit codes above 128 are 128 plus the signal number: 137 is SIGKILL (9), 143 is SIGTERM (15).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: read the logs, including the previous container
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs POD
kubectl logs POD &lt;span class="nt"&gt;--previous&lt;/span&gt;
kubectl logs POD &lt;span class="nt"&gt;-c&lt;/span&gt; CONTAINER
kubectl logs &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="nv"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;myapp &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a crash loop, the current container may have just started and have nothing to show, so &lt;code&gt;--previous&lt;/code&gt; is what you want. For pods with several containers, name the container with &lt;code&gt;-c&lt;/code&gt;, and remember init containers: a failing init container keeps the pod from starting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: check configuration and wiring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Environment and config:&lt;/strong&gt; &lt;code&gt;kubectl exec POD -- env&lt;/code&gt; and confirm values from ConfigMaps and Secrets arrived.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service selectors:&lt;/strong&gt; &lt;code&gt;kubectl get endpointslices -l kubernetes.io/service-name=SVC&lt;/code&gt;. An empty result means no ready pod matches the Service selector. Compare &lt;code&gt;kubectl get pods --show-labels&lt;/code&gt; with the selector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ports:&lt;/strong&gt; check &lt;code&gt;targetPort&lt;/code&gt; on the Service against the port your container listens on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probes:&lt;/strong&gt; an aggressive liveness probe restarts a healthy but slow-starting app. A startup probe is the documented fix.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; &lt;code&gt;kubectl auth can-i list pods --as=system:serviceaccount:NAMESPACE:NAME -n TARGET_NAMESPACE&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an image has no shell, &lt;code&gt;kubectl debug -it POD --image=busybox --target=CONTAINER&lt;/code&gt; adds an ephemeral debug container alongside the target.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: check resources and node pressure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl describe node NODE
kubectl top nodes
kubectl top pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;describe node&lt;/code&gt;, read &lt;code&gt;Conditions&lt;/code&gt;: &lt;code&gt;MemoryPressure&lt;/code&gt;, &lt;code&gt;DiskPressure&lt;/code&gt; or &lt;code&gt;PIDPressure&lt;/code&gt; set to &lt;code&gt;True&lt;/code&gt; mean the kubelet may evict pods. Also read &lt;code&gt;Allocated resources&lt;/code&gt;: requests add up even when usage is low, so a cluster can be "full" for the scheduler while the CPUs are idle. Requests drive scheduling; limits are enforced at runtime (CPU is throttled, memory can be OOM-killed).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: check the rollout
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl rollout status deploy/NAME
kubectl rollout &lt;span class="nb"&gt;history &lt;/span&gt;deploy/NAME
kubectl rollout undo deploy/NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the problem began with a deploy, consider rolling back first, then investigating. Restoring service and diagnosing are separate jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Running &lt;code&gt;kubectl logs&lt;/code&gt; on a crash-looping pod and stopping when it is empty. Use &lt;code&gt;--previous&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Debugging in the wrong namespace or context.&lt;/li&gt;
&lt;li&gt;Treating CrashLoopBackOff as the cause rather than the symptom.&lt;/li&gt;
&lt;li&gt;Raising a memory limit without checking whether the app leaks.&lt;/li&gt;
&lt;li&gt;Changing several things at once.&lt;/li&gt;
&lt;li&gt;Reading events too late; they are gone after an hour by default.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to tell it is fixed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;kubectl get pods&lt;/code&gt; shows all containers &lt;code&gt;READY&lt;/code&gt; and a restart count that has stopped climbing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;kubectl rollout status&lt;/code&gt; reports success.&lt;/li&gt;
&lt;li&gt;The Service's EndpointSlice lists the pod addresses, and a request from inside the cluster succeeds.&lt;/li&gt;
&lt;li&gt;No new warning events for several minutes.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Want to check how well this sticks? Free 10-question Kubernetes skills check - scenario questions with an explanation for every answer, no sign-up: &lt;a href="https://braintally.com/technical-assessments/kubernetes/check" rel="noopener noreferrer"&gt;braintally.com/technical-assessments/kubernetes/check&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://braintally.com/blog/kubernetes-troubleshooting-checklist" rel="noopener noreferrer"&gt;BrainTally&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>sre</category>
      <category>beginners</category>
    </item>
    <item>
      <title>AWS IAM mistakes teams keep making</title>
      <dc:creator>BrainTally</dc:creator>
      <pubDate>Sat, 17 Oct 2026 11:05:16 +0000</pubDate>
      <link>https://dev.to/cloudlative/aws-iam-mistakes-teams-keep-making-2nap</link>
      <guid>https://dev.to/cloudlative/aws-iam-mistakes-teams-keep-making-2nap</guid>
      <description>&lt;p&gt;Most AWS security incidents do not start with an exotic exploit. They start with an over-broad policy, a key that was never rotated or a role that trusts more than it should, each created because it was the fastest way to make something work. Here are the IAM mistakes that recur most often, what to do instead, and how to check that the fix held.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Wildcards in actions and resources
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is administrator access. Less obvious variants are &lt;code&gt;s3:*&lt;/code&gt; on every bucket, or &lt;code&gt;ec2:*&lt;/code&gt; for a pipeline that only starts and stops instances. Name the actions and narrow the resource:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::example-bucket/uploads/*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Object-level actions such as &lt;code&gt;s3:GetObject&lt;/code&gt; apply to the object ARN (&lt;code&gt;bucket/prefix/*&lt;/code&gt;), while &lt;code&gt;s3:ListBucket&lt;/code&gt; applies to the bucket ARN - mixing these up is a common reason a "tight" policy fails and someone swaps in a wildcard. IAM Access Analyzer can generate a policy from CloudTrail activity; test it, and don't treat the first working policy as the final one.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Long-lived access keys
&lt;/h2&gt;

&lt;p&gt;A leaked key keeps working until someone notices. Prefer temporary credentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workloads on AWS:&lt;/strong&gt; instance profiles, ECS task roles, or a Kubernetes service account mapped to a role.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD:&lt;/strong&gt; OpenID Connect federation (&lt;code&gt;sts:AssumeRoleWithWebIdentity&lt;/code&gt;) - no stored key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People:&lt;/strong&gt; federated sign-in through IAM Identity Center.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Audit what's left with &lt;code&gt;aws iam generate-credential-report&lt;/code&gt; and &lt;code&gt;aws iam get-credential-report&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Loose trust policies
&lt;/h2&gt;

&lt;p&gt;Trusting &lt;code&gt;arn:aws:iam::123456789012:root&lt;/code&gt; trusts the whole account. Name the specific role instead, use &lt;code&gt;sts:ExternalId&lt;/code&gt; for third parties, and for GitHub Actions OIDC roles always restrict the &lt;code&gt;sub&lt;/code&gt; claim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token.actions.githubusercontent.com:aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sts.amazonaws.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token.actions.githubusercontent.com:sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"repo:my-org/my-repo:ref:refs/heads/main"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Unrestricted iam:PassRole
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;iam:PassRole&lt;/code&gt; on &lt;code&gt;"Resource": "*"&lt;/code&gt; lets a user hand compute a more powerful role than their own. Restrict it to specific role ARNs and add the &lt;code&gt;iam:PassedToService&lt;/code&gt; condition. Treat &lt;code&gt;iam:CreatePolicyVersion&lt;/code&gt;, &lt;code&gt;iam:AttachUserPolicy&lt;/code&gt; and &lt;code&gt;iam:PutRolePolicy&lt;/code&gt; the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. No guardrails above individual policies
&lt;/h2&gt;

&lt;p&gt;Permissions boundaries cap what a role's policies can grant; SCPs cap whole accounts; an explicit deny anywhere wins. Effective permissions are the intersection.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Shared users and unused identities
&lt;/h2&gt;

&lt;p&gt;Shared logins destroy auditability. Use last-accessed data or Access Analyzer's unused-access findings to remove old users, roles and keys. The root user: MFA, no access keys, rarely used.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Skipping MFA and visibility
&lt;/h2&gt;

&lt;p&gt;Require MFA (passkeys or security keys where you can), keep CloudTrail logs somewhere workload roles can't delete, and review Access Analyzer findings.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick audit for this week
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Find policies with &lt;code&gt;"Action": "*"&lt;/code&gt; or &lt;code&gt;"Resource": "*"&lt;/code&gt; and justify each.&lt;/li&gt;
&lt;li&gt;Generate a credential report; delete or rotate old keys.&lt;/li&gt;
&lt;li&gt;Read the trust policy of every role assumable from outside the account.&lt;/li&gt;
&lt;li&gt;List who holds &lt;code&gt;iam:PassRole&lt;/code&gt; and IAM-write permissions.&lt;/li&gt;
&lt;li&gt;Move one CI pipeline from a stored key to OIDC.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Want to see how well this sticks? I put together a free 10-question AWS skills check - scenario questions with an explanation for every answer, no sign-up: &lt;a href="https://braintally.com/technical-assessments/aws/check" rel="noopener noreferrer"&gt;braintally.com/technical-assessments/aws/check&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://braintally.com/blog/aws-iam-mistakes-teams-keep-making" rel="noopener noreferrer"&gt;BrainTally&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
