흰 스타렉스에서 내가 내리지

AWS IAM 이란? 그리고 Terraform 으로 IAM user, group, role, policy 생성 본문

DevOps

AWS IAM 이란? 그리고 Terraform 으로 IAM user, group, role, policy 생성

주씨. 2024. 9. 5. 17:26
728x90

 

# IAM 이란?

IAM 은 AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹서비스다. 

IAM 을 사용하여 리소스를 사용하도록 인증(로그인) 및 권한부여(권한 있음)된 대상을 제어한다. 

 

 

# IAM 구성요소

IAM user AWS 내에서 생성하는 사용자로, AWS 와 상호작용하는 사용자 혹은 애플리케이션을 의미한다.
IAM group IAM User의 집합이고, Group 을 사용함으로써 다수 사용자에 대하여 동일한 권한을 보다 쉽게 관리할 수 있다. 
IAM role 특정 권한을 가진 IAM 자격증명이다. 이 Role 을 사용함으로써 특정 사용자 혹은 어플리케이션에 혹은 AWS 서비스에 접근 권한을 위임할 수 있다. 
(예. EC2 에 role 을 할당해서 지정한 권한을 줄 수 있다. )
IAM policy AWS 의 접근하는 해당 권한을 정의하는 개체로, AWS IAM 리소스들과 연결하여 사용할 수 있다. 

AWS Managed policy : AWS 에서 먼저 생성해놓은 Policy set 이다. 사용자가 권한(permission) 을 변경할 수 없다.
Customer Managed policy : User 가 직접 생성하는 policy 로 권한을 직접 상세하게 만들어 관리할 수 있다. 

 

IAM user, IAM group, IAM role 도 각각의 IAM Policy 를 가지고 있는 것이다. 

 

 

# IAM Policy Structure

Policy json 양식 (좌) / 실제 AdministratorAccess Policy 내용

Effect "Allow" 또는 "Deny" 일 수 있다. 
기본적으로 IAM 사용자에게는 리소스 및 API 작업을 사용할 권한이 없으므로 모든 요청이 거부된다. 
Action action 은 권한을 부여하거나 거부할 특정 API 작업이다.
Resource 작업의 영향을 받는 리소스이다. 
Amazon 리소스 이름 (ARN) 을 사용하거나 명령문이 모든 리소스에 적용됨을 표시하는 와일드카드(*) 를 사용한다.
Condition 선택사항으로서 정책이 적용되는 시점을 제어하는 데 사용할 수 있다. 
다양한 조건을 넣어 권한을 부여할 수 있다. 
(예. 특정 IP 혹은 VPC 에서만 접근을 허용하라.)

 

 

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": [
            "ec2:AuthorizeSecurityGroupIngress",
            "ec2:AuthorizeSecurityGroupEgress",
            "ec2:RevokeSecurityGroupIngress",
            "ec2:RevokeSecurityGroupEgress"
        ],
        "Resource": "arn:aws:ec2:region:account:security-group/*",
        "Condition": {
            "StringEquals": {
                "ec2:Vpc": "arn:aws:ec2:region:account:vpc/vpc-11223344556677889"
            }
        }
    }]
}

 

구글에 `Aws policy examples` 라고 검색하면 수많은 템플릿을 확인할 수 있을 것이다. 

AWS IAM 콘솔의 Policies 탭에는, 자주 사용하는 Policy 형태를 미리 만들어 두었다. 

 


 

# Terraform 으로 IAM user 생성하기

vim provider.tf
provider "aws" {
  region = "ap-northeast-2"
}

 

vim user_joos-devops-user.tf
resource "aws_iam_user" "joos-devops-user" {
  name = "joos-devops-user"
}

 

사실 IAM 은 리전 종속적 서비스가 아니기 때문에 ap로 하든 us 로 하든 상관이 없다. 

즉, 글로벌 리소스이다.

(사실 ChangePassword 정책을 부여해줘야 콘솔에서 해당 user 로 로그인할 수 있다. 그 방법은 조금만 스크롤 내리면 나온다.)

 

terraform init
terraform plan
terrafrom apply

ok 잘 생성됨

 

 

 

위 Terraform 코드를 통해 IAM user 를 생성해주었다고 하더라도, console 을 접속할 수는 없습니다. 생성한 user의 password 가 설정되어있지 않기 때문입니다. 비밀번호와 MFA는 직접 console을 통해 설정해야 합니다. 혹은 AWS CLI를 통해서 자동화를 진행할 수 도 있습니다. 물론 테라폼을 통해 설정을 할 수 도 있으나, aws_iam_user_login_profile 을 사용해야합니다. 해당 리소스는 AWS와 Terraform 중급 수준의 이해가 있어야 사용이 편합니다.

 

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-services-iam.html#cli-services-iam-set-pw

 

AWS Identity and Access Management 에서 사용 AWS CLI - AWS Command Line Interface

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

aws iam create-login-profile --user-name joos-devops-user --password My!User1Login8P@ssword --password-reset-required

 

++ account alias 설정하기

aws iam create-account-alias --account-alias my-awesome-account

 

별칭을 설정하면 AWS 로그인 URL은 https://<account-alias>.signin.aws.amazon.com/console/ 형태로 변경됩니다.


한 AWS 계정에는 하나의 alias만 설정할 수 있습니다.

 

account alias 를 설정하고, 로그인 URL 을 통해 접속하고, IAM username 과 password 로 aws 계정에 로그인할 수 있다. 

 

그러나 로그인을 하면 비밀번호를 변경하라는 페이지가 뜨는데, 비밀번호 변경을 시도하면 비밀번호 변경이 되지 않을 것이다. 

왜냐? iam:ChangePassword 정책이 이 user 에 할당되어 있지 않기 때문이다.

 

root 계정으로 다시 로그인하여 정책 할당을 해도 되지만, terraform 으로 간단하게 설정할 수 있다. 

 

위에서 작성했던 tf 파일을 수정한다. 

vim user_joos-devops-user.tf
resource "aws_iam_user" "joos-devops-user" {
  name = "joos-devops-user"
}

# 관리형 정책인 IAMUserChangePassword를 사용하여 비밀번호 변경 권한 부여
resource "aws_iam_user_policy_attachment" "joos-devops-user-password-policy" {
  user       = aws_iam_user.joos-devops-user.name
  policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"
}

 

정책이 잘 추가되었고, 이제 User 로그인 후 비밀번호 변경이 가능할 것이다. 

 

 


# Terraform 으로 group 생성하기

vim devops_group.tf
resource "aws_iam_group" "joos_devops_group" {
  name = "joos_devops_group"
}

 

terraform plan
terraform apply

group 이 잘 생성되었죠

 

 


# 생성한 IAM user 를 IAM group 에 등록 

기존에 만들었던 group.tf 에 user 를 추가하는 코드를 작성한다. 

vim devops_group.tf
resource "aws_iam_group" "joos_devops_group" {
  name = "joos_devops_group"
}

resource "aws_iam_group_membership" "joos_devops_group_membership" {
  name = aws_iam_group.joos_devops_group.name
  
  users = [
    aws_iam_user.joos-devops-user.name
  ]
  
  group = aws_iam_group.joos_devops_group.name
}

 

users 속성이 리스트인 이유는 여러 사용자를 동시에 추가할 수 있게 하기 위함이다. 

terraform plan
terraform apply

 

group 에 user 가 잘 추가된 것을 볼 수 있다.

 

 

 

group 에 policy 를 추가하면, user 도 해당 policy 를 갖게 된다. 


# Terraform 으로 IAM Role 생성하고 Permission Policies 할당하기

 

trust relationship 설정 

vim iam_role_hello.tf
resource "aws_iam_role" "hello" {
  name               = "hello-iam-role"
  path               = "/"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

}
terraform plan
terraform apply

 

role 역시 잘 생성된 것을 확인할 수 있습니다.

 

이 신뢰 정책(Trust Policy)이 없으면 EC2 인스턴스가 IAM 역할을 가정(Assume Role)할 수 없게 됩니다. 
신뢰 정책은 EC2 인스턴스가 IAM 역할을 가정하고, 필요한 AWS 리소스에 액세스할 수 있도록 하는 필수적인 설정입니다. 

이 정책이 없다면 EC2 인스턴스는 권한을 가정할 수 없고, AWS 서비스와 상호작용하는 작업이 불가능하게 됩니다.

 

 

이제 실제 permission 을 추가해보자. 

s3 에 GetObject 를 허용한다. 

vim iam_role_hello.tf
resource "aws_iam_role" "hello" {
  name               = "hello-iam-role"
  path               = "/"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

}

resource "aws_iam_role_policy" "hello_s3" {
  name   = "hello-s3-download"
  role   = aws_iam_role.hello.id
  policy = <<EOF
{
  "Statement": [
    {
      "Sid": "AllowAppArtifactsReadAccess",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  ]
}
EOF

}

resource "aws_iam_instance_profile" "hello" {
  name = "hello-profile"
  role = aws_iam_role.hello.name
}
terraform plan
terraform apply

허용정책이 잘 생성된 것을 확인할 수 있다. 

 

aws_iam_instance_profile 은 IAM 역할을 위한 컨테이너로서 인스턴스 시작 시 EC2 인스턴스에 역할 정보를 전달하는 데 사용됩니다.
만약 AWS Management 콘솔을 사용하여 Amazon EC2 역할을 생성하는 경우, 콘솔이 자동으로 인스턴스 프로파일을 생성하여 해당 역할과 동일한 이름을 부여합니다.

 

 


# Terraform 으로 IAM Policy 생성하기

위에서 작성했던 user_joos-devops-user.tf 파일에 내용을 추가한다. 

vim user_joos-devops-user.tf
resource "aws_iam_user" "joos-devops-user" {
  name = "joos-devops-user"
}

# 관리형 정책인 IAMUserChangePassword를 사용하여 비밀번호 변경 권한 부여
resource "aws_iam_user_policy_attachment" "joos-devops-user-password-policy" {
  user       = aws_iam_user.joos-devops-user.name
  policy_arn = "arn:aws:iam::aws:policy/IAMUserChangePassword"
}

# policy 생성
resource "aws_iam_user_policy" "joos-policy" {
  name  = "super-admin"
  user  = aws_iam_user.joos-devops-user.name

  policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
EOF
}
terraform plan
terraform apply

super-admin 정책이 잘 추가가 되었다.