AWS CDK 100 实战练习 #002:IAM 基础 —— 用户、角色与安全密码管理

发布: (2025年12月10日 GMT+8 00:00)
6 min read
原文: Dev.to

Source: Dev.to

介绍

这是 AWS CDK 100 Drill Exercises 系列的第二个练习。

想了解更多关于该系列,请参阅这篇介绍文章

在学习了第一个练习中的 S3 基础后,我们现在深入 AWS 身份与访问管理 (IAM)。IAM 是 AWS 安全的基石,负责控制谁可以访问你的资源以及他们可以对资源执行的操作。

为什么在 S3 之后学习 IAM?

  • 安全基石 – IAM 对所有 AWS 资源的安全至关重要。
  • 真实需求 – 每个 AWS 部署都需要恰当的访问管理。
  • CDK 集成 – 了解 CDK 如何生成 IAM 策略和角色。
  • 最佳实践 – 从一开始就学习安全模式,可防止未来的漏洞。

你将学到的内容

  • CDK 如何创建 IAM 用户、组和角色。
  • 使用 AWS Secrets Manager 进行安全密码管理。
  • 托管策略与内联策略的区别。
  • 带 MFA 要求的切换角色实现。
  • CloudFormation 的动态密钥解析。
  • IAM 安全最佳实践。

📁 代码仓库:所有示例均可在GitHub上获取。

架构概览

我们将在四个构造体中实现六种不同的模式。

构造体 1:基础用户 (CDKDefaultUser)

  • 模式 1 – 最小化的 IAM 用户配置。

构造体 2:密码管理用户 (IAMUserWithPassword)

  • 模式 2A – 硬编码密码(⚠️ 不推荐)。
  • 模式 2B – 使用 Secrets Manager 的安全密码管理(✅ 推荐)。
  • 模式 3A – 附加 AWS 托管策略。
  • 模式 3B – 附加内联策略。

构造体 3:组管理用户 (IamUserGroup)

  • 模式 4 – 基于组的权限管理。

构造体 4:切换角色用户 (SwitchRoleUser)

  • 模式 5 – 需要 MFA 的角色假设。

前置条件

  • 已安装并配置 AWS CLI v2。
  • Node.js 20+。
  • AWS CDK CLI(npm install -g aws-cdk)。
  • 基础的 TypeScript 知识。
  • AWS 账户(免费套餐即可)。
  • 对 IAM 概念(用户、角色、策略)有基本了解。

项目目录结构

iam-basics/
├── bin/
   └── iam-basics.ts                      # 应用入口点
├── lib/
   ├── stacks/
   └── iam-basics-stack.ts            # 主栈定义
   └── constructs/
       ├── iam-user-with-password.ts      # 模式 2‑3
       ├── iam-user-with-group.ts         # 模式 4
       └── iam-user-with-switch-role.ts   # 模式 5
├── test/
   ├── compliance/
   └── cdk-nag.test.ts                # 测试(后文解释)
   ├── snapshot/
   └── snapshot.test.ts               # 测试(后文解释)
   └── unit/
       └── iam-basics.test.ts             # 测试(后文解释)
├── cdk.json
├── package.json
└── tsconfig.json

模式 1:了解 CDK 默认用户

import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as iam from 'aws-cdk-lib/aws-iam';

export class IamBasicsStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 最小化的 IAM 用户配置
    const cdkDefaultUser = new iam.User(this, 'CDKDefaultUser', {});
  }
}

生成的 CloudFormation

{
  "Resources": {
    "CDKDefaultUserF7AAA71A": {
      "Type": "AWS::IAM::User",
      "Metadata": {
        "aws:cdk:path": "Dev/DrillexercisesIamBasics/CDKDefaultUser/Resource"
      }
    }
  }
}

默认配置细节

  • 用户名 – 由 AWS 自动生成。
  • 密码 – 无;默认情况下禁用控制台访问。
  • 策略 – 没有任何权限(最小特权原则)。
  • 访问密钥 – 无;默认禁用编程访问。

在显式授予权限之前,该用户无法访问任何资源。

模式 2A:带硬编码密码的用户(⚠️ 不推荐

⚠️ 此模式演示在生产环境中硬编码密码的危险性。

const userWithPassword = new iam.User(this, 'PasswordUser', {
  password: cdk.SecretValue.unsafePlainText('InitialPassword123!'),
  passwordResetRequired: true,
});

生成的 CloudFormation

{
  "UserWithPasswordPasswordUserA5E8EDB8": {
    "Type": "AWS::IAM::User",
    "Properties": {
      "LoginProfile": {
        "Password": "InitialPassword123!",
        "PasswordResetRequired": true
      }
    }
  }
}

为什么这很危险

  • 密码写在源码中 – 在版本控制中可见。
  • CloudFormation 模板 – 密码会在控制台和日志中暴露。
  • 未加密 – 以明文形式存储。
  • 审计追踪 – 难以追踪密码的变更。

切勿在生产环境中使用此模式。

模式 2B:使用 Secrets Manager 的用户(✅ 推荐

import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import * as iam from 'aws-cdk-lib/aws-iam';
import * as cdk from 'aws-cdk-lib';

const userName = 'SecretsPasswordUser';

// 创建包含自动生成密码的密钥
const userSecret = new secretsmanager.Secret(this, 'UserSecret', {
  generateSecretString: {
    secretStringTemplate: JSON.stringify({ username: userName }),
    generateStringKey: 'password',
    excludePunctuation: true,
    passwordLength: 16,
    requireEachIncludedType: true,
  },
});

// 使用 Secrets Manager 中的密码创建 IAM 用户
const user = new iam.User(this, 'SecretsPasswordUser', {
  userName: userName,
  password: userSecret.secretValueFromJson('password'),
  passwordResetRequired: true,
});

// 附加允许用户自行更改密码的 AWS 托管策略
user.addManagedPolicy(
  iam.ManagedPolicy.fromAwsManagedPolicyName('IAMUserChangePassword')
);

这种做法将密码安全地存储在 Secrets Manager 中,避免了硬编码机密,并且在需要时可以实现密码轮换。

Back to Blog

相关文章

阅读更多 »