Secrets Manager stores credentials encrypted with KMS, controls access through IAM, logs every read to CloudTrail, and, the part that justifies its price, rotates supported secrets automatically without anyone touching a config file.\n\nThat last capability is the deciding factor. If you don't need rotation, Parameter Store does the same job for free.\n\n## Creating a secret\n\nbash\naws secretsmanager create-secret \\\n --name prod/payments/db \\\n --description \"Aurora credentials for the payments service\" \\\n --secret-string '{\"username\":\"payments\",\"password\":\"REPLACE_ME\",\"host\":\"db.internal\",\"port\":5432}'\n\n\njson\n{\n \"ARN\": \"arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/payments/db-AbCdEf\",\n \"Name\": \"prod/payments/db\",\n \"VersionId\": \"8f3c1e2a-...\"\n}\n\n\nNote the six random characters AWS appends to the ARN. They're deliberate: they stop a deleted secret's name from being immediately reusable by someone who might inherit its permissions. It also means you can't construct a secret ARN by hand, if you're writing IAM policies, either look the ARN up or end the resource with a wildcard: arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/payments/db-*.\n\nStore JSON rather than a bare string. Rotation functions expect structured fields, and it lets one secret carry the host and port alongside the credentials.\n\nUse a naming convention with a path-like shape, \u003cenv\u003e/\u003cservice\u003e/\u003cpurpose\u003e, because IAM policies can then grant a service everything under its own prefix:\n\njson\n{\n \"Effect\": \"Allow\",\n \"Action\": \"secretsmanager:GetSecretValue\",\n \"Resource\": \"arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/payments/*\"\n}\n\n\n## Reading a secret\n\nbash\naws secretsmanager get-secret-value \\\n --secret-id prod/payments/db \\\n --query SecretString --output text\n\n\nIn application code, retrieve at startup and cache, never call Secrets Manager on every request:\n\n```python\nimport json, boto3\nfrom botocore.exceptions import ClientError\n\n_cache = {}\n\ndef get_secret(name: str, region: str = "us-east-1") -\u003e dict:\n if name in _cache:\n return _cache[name]\n client = boto3.client("secretsmanager", region_name=region)\n try:\n response = client.get_secret_value(SecretId=name)\n except ClientError as err:\n # ResourceNotFoundException here is almost always a region mismatch.\n raise RuntimeError(f"Could not read secret {name}: {err}") from err\n _cache[name] = json.loads(response["SecretString\
Use AWS Config for continuous compliance: turn on the recorder, apply managed rules and conformance packs, auto-remediate with SSM and compare with CloudTrail.
Set up Systems Manager and fix managed instances that do not appear, then use Run Command, Patch Manager, State Manager and Automation to manage a fleet.
Get a shell on EC2 with Session Manager and no SSH, bastion or open ports. Meet the prerequisites, log sessions for audit and port-forward to a database.