AWS IAM là gì?
IAM (Identity and Access Management) kiểm soát ai có thể truy cập những gì trong AWS. Đây là nền tảng security quan trọng nhất.
Các thành phần chính
| Component | Mô tả |
|---|
| User | Identity cho người dùng |
| Group | Tập hợp users với cùng permissions |
| Role | Identity cho AWS services hoặc cross-account |
| Policy | JSON document định nghĩa permissions |
IAM Policies
Policy Structure
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DescriptiveName",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.1.0/24"
}
}
}
]
}
Các loại Policies
| Type | Mô tả |
|---|
| AWS Managed | Do AWS tạo và quản lý |
| Customer Managed | Bạn tự tạo, reusable |
| Inline | Embed trực tiếp vào user/role |
IAM User
# IAM User
resource "aws_iam_user" "developer" {
name = "developer"
path = "/developers/"
tags = {
Team = "Engineering"
}
}
# Access Key (lưu ý: nên dùng IAM Identity Center thay vì access keys)
resource "aws_iam_access_key" "developer" {
user = aws_iam_user.developer.name
}
# Attach existing policy
resource "aws_iam_user_policy_attachment" "developer_readonly" {
user = aws_iam_user.developer.name
policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
IAM Group
# IAM Group
resource "aws_iam_group" "developers" {
name = "developers"
path = "/teams/"
}
# Add user to group
resource "aws_iam_user_group_membership" "developer" {
user = aws_iam_user.developer.name
groups = [aws_iam_group.developers.name]
}
# Group policy
resource "aws_iam_group_policy" "developers" {
name = "developers-policy"
group = aws_iam_group.developers.name
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ec2:Describe*",
"s3:List*",
"s3:Get*"
]
Resource = "*"
}
]
})
}
IAM Role (quan trọng nhất!)
# IAM Role cho EC2 instance
resource "aws_iam_role" "ec2_app" {
name = "${var.project_name}-ec2-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}
]
})
}
# Custom policy
resource "aws_iam_policy" "s3_access" {
name = "${var.project_name}-s3-access"
description = "Allow access to specific S3 bucket"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Resource = "${aws_s3_bucket.app.arn}/*"
},
{
Effect = "Allow"
Action = ["s3:ListBucket"]
Resource = aws_s3_bucket.app.arn
}
]
})
}
# Attach policy to role
resource "aws_iam_role_policy_attachment" "ec2_s3" {
role = aws_iam_role.ec2_app.name
policy_arn = aws_iam_policy.s3_access.arn
}
# Instance Profile (để gắn role vào EC2)
resource "aws_iam_instance_profile" "ec2_app" {
name = "${var.project_name}-ec2-profile"
role = aws_iam_role.ec2_app.name
}
Cross-Account Role
# Role cho phép account khác assume
resource "aws_iam_role" "cross_account" {
name = "cross-account-readonly"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::123456789012:root" # Account ID khác
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"sts:ExternalId" = var.external_id # Extra security
}
}
}
]
})
}
AWS CLI Commands
# Liệt kê users
aws iam list-users
# Tạo user
aws iam create-user --user-name developer
# Tạo access key
aws iam create-access-key --user-name developer
# Attach policy
aws iam attach-user-policy \
--user-name developer \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# Tạo role
aws iam create-role \
--role-name MyRole \
--assume-role-policy-document file://trust-policy.json
# Assume role (lấy temporary credentials)
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/MyRole \
--role-session-name MySession
Best Practices
1. Principle of Least Privilege
# ❌ Quá rộng
resource "aws_iam_policy" "bad" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "*"
Resource = "*"
}]
})
}
# ✅ Cụ thể resources và actions
resource "aws_iam_policy" "good" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject"]
Resource = "arn:aws:s3:::my-bucket/public/*"
}]
})
}
2. Sử dụng Roles thay vì Access Keys
# EC2 với IAM Role - không cần hardcode credentials
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.app.name
}
3. Enable MFA
# Policy yêu cầu MFA
resource "aws_iam_policy" "require_mfa" {
policy = jsonencode({
Statement = [{
Effect = "Deny"
Action = "*"
Resource = "*"
Condition = {
BoolIfExists = {
"aws:MultiFactorAuthPresent" = "false"
}
}
}]
})
}
4. Không dùng Root Account
# Tạo admin user thay vì dùng root
resource "aws_iam_user" "admin" {
name = "admin"
}
resource "aws_iam_user_policy_attachment" "admin" {
user = aws_iam_user.admin.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
| Tool | Mô tả |
|---|
| IAM Access Analyzer | Phát hiện public/shared resources |
| IAM Policy Simulator | Test policies trước khi apply |
| Credential Report | CSV report tất cả users và credentials |
Bài tiếp theo: Security Services - Bảo vệ hạ tầng với GuardDuty, WAF, Shield.