DOP Lab 01 - Auto-remediate an unrestricted-SSH security group
Scaffold: 3/5. AWS Config is turned on for you (recorder, delivery channel,
an S3 bucket for Config, and the role Config assumes), the managed rule
INCOMING_SSH_DISABLED (“restricted-ssh”) is in place, and a demo VPC holds a
security group left open to the world on SSH, standing by for the rule to flag
it. You write the remediation: the RemediationConfiguration that fixes the
flagged group, and the role its automation assumes.
The scenario
A security group left open to the world on SSH should be closed by the platform automatically, not filed in a queue for someone to action next week. AWS Config can detect the drift, but detection on its own just produces a list of things that are wrong. The interesting part of a DevOps Professional answer is what happens next: the rule fires, and a remediation runs without a human in the loop, so the estate self-heals.
Here the drift is a security group whose inbound rules allow tcp port 22 from
0.0.0.0/0. The managed rule INCOMING_SSH_DISABLED flags it. The fix is the
AWS-owned SSM Automation document
AWSConfigRemediation-RemoveUnrestrictedSourceIngressRules, which revokes the
ingress rules open to the world. You wire the two together with an
AWS::Config::RemediationConfiguration set to run automatically.
The requirement
When the demo security group is flagged by the rule, AWS Config must run
AWSConfigRemediation-RemoveUnrestrictedSourceIngressRules against it
automatically, passing the flagged group’s id and a role for the automation to
assume. After remediation runs, the group no longer allows SSH from 0.0.0.0/0.
What’s provided
src/template.yaml- the Config recorder (scoped to security groups), the delivery channel and its S3 bucket, the Config role, the managed rule, and the demo VPC and non-compliant security group, plus the stack Outputs. There is a clearly-markedTODOblock where the remediation goes.scripts/- deploy, test, and teardown.solution/template.yaml- the complete, correct template.
Deploying src/template.yaml as shipped succeeds and the rule evaluates the group
as non-compliant, but a flagged group stays flagged: there is no remediation, so
nothing closes it.
Note: the templates turn Config on assuming this account does not already run it in this region (Config allows one recorder and one delivery channel per region). If Config is already on, see the comment at the top of the template - keep the rule, the demo VPC and group, and the remediation, and drop the recorder, delivery channel, Config role, and Config bucket.
Your task
Open src/template.yaml and fill in the TODO block with two resources:
- An
AWS::IAM::Roletrusted byssm.amazonaws.com, with an inline policy allowingec2:DescribeSecurityGroupsandec2:RevokeSecurityGroupIngress. This is the role the automation assumes to do the fix.DescribeSecurityGroupsdoes not support resource-level permissions, so the policy uses*. Give the role aRoleNamesoCAPABILITY_NAMED_IAMcovers it. - An
AWS::Config::RemediationConfigurationon the rule, withTargetType: SSM_DOCUMENT,TargetId: AWSConfigRemediation-RemoveUnrestrictedSourceIngressRules,Automatic: true, and the requiredMaximumAutomaticAttemptsandRetryAttemptSeconds. ItsParameterspassSecurityGroupIdfromRESOURCE_IDandAutomationAssumeRoleas the role’s ARN.
If you want the mechanics first, read the walk-through post linked at the bottom.
Run it
# Defaults: stack dop-lab-01, region ap-southeast-2.
./scripts/deploy.sh # deploys src/template.yaml
./scripts/test.sh # forces an evaluation and checks the group
./scripts/teardown.sh # empties the Config bucket and deletes everything
With the unedited src/template.yaml, test.sh forces the rule to re-evaluate,
watches Config report the demo group non-compliant, and then finds the open SSH
rule is still there because no remediation has fixed it. Fill in the TODO,
redeploy, and run the test again.
What success looks like
./scripts/test.sh prints (Config and remediation are both eventually consistent,
so the “still waiting” lines are normal):
Asking Config to re-evaluate dop-lab-01-restricted-ssh ...
Waiting for Config to evaluate the demo security group (this can take a minute or two) ...
Config reports the demo security group as: NON_COMPLIANT
Checking whether sg-... still allows SSH from 0.0.0.0/0 ...
ok: sg-... no longer allows SSH from 0.0.0.0/0
PASS: the Config rule flagged the group and the remediation ran, so the
open inbound SSH rule has been revoked.
The test never launches an instance, so it stays cheap: it nudges the rule, reads the compliance result, and reads the group’s inbound rules.
If it fails
- The open SSH rule is never revoked. The
RemediationConfigurationis missing (or notAutomatic: true). Detection without remediation just leaves the group flagged. - The remediation is present but the group still is not fixed. Check the
automation role: it must be trusted by
ssm.amazonaws.comand allowec2:RevokeSecurityGroupIngress(andec2:DescribeSecurityGroups), and its ARN must be passed as theAutomationAssumeRoleparameter. - The stack fails to deploy with a capabilities error. The template creates
named IAM roles; deploy with
--capabilities CAPABILITY_NAMED_IAM(the deploy script already does this).
Reveal the solution
Deploy the complete reference template without editing anything:
SRC=solution ./scripts/deploy.sh && ./scripts/test.sh
What you just learned
- AWS Config detects drift; a
RemediationConfigurationis what turns detection into a fix. SetAutomatic: trueand Config runs the remediation itself when the rule reportsNON_COMPLIANT, with no human in the loop. - Remediations run SSM Automation documents.
AWSConfigRemediation-RemoveUnrestrictedSourceIngressRulesis AWS-owned, so you do not write the fix logic; you point Config at it and pass the parameters it needs. RESOURCE_IDis how the flagged resource flows into the document: Config substitutes the non-compliant group’s id for theSecurityGroupIdparameter, so one remediation fixes whichever group the rule flags.- Remediation needs a role to act under. The document assumes the
AutomationAssumeRoleyou supply, and that role, not your credentials, must hold the permission to make the change.
Next
The rest of the DOP lab track is listed in labs/README-dop.md.