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\
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.
Store configuration and secrets in SSM Parameter Store with SecureString encryption, path hierarchies, versions, labels, standard vs advanced tiers and cost.
Set up multi-account AWS with Organizations. Learn why separate accounts beat separate VPCs, how to design OUs, create accounts and use consolidated billing.