1. 로그인 계정 설정

backend와 provider 설정

  • terraform/iam/art-id/backend.tf 파일을 수정합니다.

terraform/iam/art-id/backend.tf
terraform {
  required_version = ">= 1.0.0" # Terraform Version

  backend "s3" {
    bucket         = "art-id-apnortheast2-tfstate" # Set bucket name 
    key            = "art/terraform/iam/art-id/terraform.tfstate"
    region         = "ap-northeast-2"
    encrypt        = true
    dynamodb_table = "terraform-lock" # Set DynamoDB Table
  }
}
vim provider.tf
provider "aws" {
  region = "us-east-1" # IAM is global
}

공통 권한 생성

  • 모든 사용자가 공통으로 가져야 할 권한을 생성합니다.

  • 이후 각 그룹마다 권한을 매핑할 예정입니다.

terraform/iam/art-id/every_policy.tf 를 확인합니다. 수정하실 필요는 없습니다.

terraform/iam/art-id/every_policy.tf
#### Permission to rotate key
resource "aws_iam_policy" "rotate_keys" {
  name        = "RotateKeys"
  description = "allow users to change their aws keys, and passwords."

  policy = data.aws_iam_policy_document.rotate_keys.json
}

data "aws_iam_policy_document" "rotate_keys" {
  statement {
    actions = [
      "iam:*LoginProfile",
      "iam:*AccessKey*",
      "iam:*SSHPublicKey*"
    ]
    resources = ["arn:aws:iam::${var.account_id}:user/$${aws:username}"]
  }

  statement {
    actions = [
      "iam:ListAccount*",
      "iam:GetAccountSummary",
      "iam:GetAccountPasswordPolicy",
      "iam:ListUsers"
    ]
    resources = ["*"]
  }
}

#### Permission to self managed MFA
resource "aws_iam_policy" "self_managed_mfa" {
  name        = "SelfManageMFA"
  description = "allow a user to manage their own MFA device."

  policy = data.aws_iam_policy_document.self_managed_mfa.json
}

data "aws_iam_policy_document" "self_managed_mfa" {
  statement {
    actions = [
      "iam:*VirtualMFADevice"
    ]
    resources = ["arn:aws:iam::${var.account_id}:mfa/$${aws:username}"]
  }

  statement {
    actions = [
      "iam:GetAccountPasswordPolicy"
    ]
    resources = ["*"]
  }

  statement {
    actions = [
      "iam:ChangePassword"
    ]
    resources = ["arn:aws:iam::${var.account_id}:user/$${aws:username}"]
  }

  statement {
    actions = [
      "iam:DeactivateMFADevice",
      "iam:EnableMFADevice",
      "iam:ListMFADevices",
      "iam:ResyncMFADevice"
    ]
    resources = ["arn:aws:iam::${var.account_id}:user/$${aws:username}"]
  }

  statement {
    actions = [
      "iam:ListVirtualMFADevices"
    ]
    resources = ["arn:aws:iam::${var.account_id}:mfa/*"]
  }

  statement {
    actions = [
      "iam:ListUsers"
    ]
    resources = ["arn:aws:iam::${var.account_id}:user/*"]
  }
}

#### Force user to use MFA for security issue
resource "aws_iam_policy" "force_mfa" {
  name        = "ForceMFA"
  description = "disallow a user anything unless MFA enabled"

  policy = data.aws_iam_policy_document.force_mfa.json
}


data "aws_iam_policy_document" "force_mfa" {
  statement {
    not_actions = [
      "iam:*",
      "sts:AssumeRole",
      "s3:*",
      "dynamodb:*",
    ]
    resources = ["*"]
    effect    = "Deny"

    condition {
      test     = "Null"
      variable = "aws:MultiFactorAuthAge"
      values   = ["true"]
    }
  }
}

Module 세팅

  • Multi-account 세팅을 위해서 각 account마다 필요한 정책을 생성해야 합니다.

  • 공통 리소스는 module을 통해서 생성합니다.

    • terraform/iam/art-id/_module_assume_policy 폴더를 생성하여 정의

terraform/iam/art-id/_module_assume_policy/main.tf 를 확인합니다. 따로 수정하실 필요는 없습니다.

terraform/iam/art-id/_module_assume_policy/main.tf
resource "aws_iam_policy" "policy" {
  name        = "assume-${var.aws_account}-${var.subject}-policy"
  path        = "/"
  description = "${var.aws_account}-${var.subject}-policy"
  policy      = data.aws_iam_policy_document.policy-document.json
}

data "aws_iam_policy_document" "policy-document" {
  statement {
    effect = "Allow"

    resources = var.resources

    actions = [
      "sts:AssumeRole",
    ]
  }
}

Production 계정 접근을 위한 Policy 생성

  • Production 계정에 Assume하기 위해서는 권한이 필요합니다.

  • id 계정에서 production계정의 role을 사용하기 위한 권한 설정이므로, 추후에 production 계정에 해당 Role을 생성해야 합니다.( 본 설정만으로는 assume할 수 없습니다.)

terraform/iam/art-id/assume_policy_prod.tf 를 수정합니다.

terraform/iam/art-id/assume_policy_prod.tf
### Create policies for allowing user to assume the role in the production account
### You can copy this file and change `prod` to other environment if you have any other account

# Admin Access policy 
# If this policy is applied, then you will be able to assume role in the production account with admin permission
module "art_prod_admin" {
  source      = "./_module_assume_policy/"
  aws_account = "art-prod"
  subject     = "admin"
  resources   = ["arn:aws:iam::${var.prod_account_id}:role/assume-art-prod-admin"]
}

output "assume_art_prod_admin_policy_arn" {
  value = module.art_prod_admin.assume_policy_arn
}

# Poweruser Access policy 
# If this policy is applied, then you will be able to assume role in the production account with poweruser permission
module "art_prod_poweruser" {
  source      = "./_module_assume_policy/"
  aws_account = "art-prod"
  subject     = "poweruser"
  resources   = ["arn:aws:iam::${var.prod_account_id}:role/assume-art-prod-poweruser"]
}

output "assume_art_prod_poweruser_policy_arn" {
  value = module.art_prod_poweruser.assume_policy_arn
}


# ReadOnly Access policy 
# If this policy is applied, then you will be able to assume role in the production account with readonly permission
module "art_prod_readonly" {
  source      = "./_module_assume_policy/"
  aws_account = "art-prod"
  subject     = "readonly"
  resources   = ["arn:aws:iam::${var.prod_account_id}:role/assume-art-prod-readonly"]
}

output "assume_art_prod_readonly_policy_arn" {
  value = module.art_prod_readonly.assume_policy_arn
}

팀별로 그룹과 사용자 생성

  • 편의상 아래와 같이 세팅했습니다.

    • group_devops_black

      • 모든 계정에서 admin 권한을 사용할 수 있는 사용자의 그룹

      • 예제 사용자 : [email protected]

    • group_devops_white

      • 모든 계정에서 readonly 권한을 사용할 수 있는 사용자의 그룹

      • 예제 사용자 : [email protected]

사용자 생성

로그인 계정에 실제 로그인을 할 사용자를 생성합니다.

terraform/iam/art-id/user_samples.tf
resource "aws_iam_user" "jupiter_devart_com" {
  name = "[email protected]"
}

resource "aws_iam_user" "daniel_devart_com" {
  name = "[email protected]"
}

그룹 생성

사용자를 할당할 그룹을 생성합니다.

Black Group

terraform/iam/art-id/group_devops_black.tf
############## art DevOps Group ##################
resource "aws_iam_group" "art_devops_black" {
  name = "art_devops_black"
}

resource "aws_iam_group_membership" "art_devops_black" {
  name = aws_iam_group.art_devops_black.name

  users = [
    aws_iam_user.jupiter_devart_com.name,
  ]

  group = aws_iam_group.art_devops_black.name
}

############### DevOps Basic Policy ##################
resource "aws_iam_group_policy" "art_devops_black" {
  name  = "art_devops_black"
  group = aws_iam_group.art_devops_black.id

  policy = data.aws_iam_policy_document.art_devops_black.json
}

data "aws_iam_policy_document" "art_devops_black" {
  statement {
    actions = [
      "*"
    ]

    resources = [
      "*"
    ]
  }
}

######################################################

########### DevOps Assume Policies ####################
resource "aws_iam_group_policy_attachment" "art_devops_black" {
  count      = length(var.assume_policy_art_devops_black)
  group      = aws_iam_group.art_devops_black.name
  policy_arn = var.assume_policy_art_devops_black[count.index]
}

variable "assume_policy_art_devops_black" {
  description = "IAM Policy to be attached to user"
  type        = list(string)

  default = [
    # Please change <account_id> to the real account id number of id account 
    "arn:aws:iam::<account_id>:policy/assume-art-prod-admin-policy", # Add admin policy to black group user 
  ]
}

#######################################################


############### MFA Manager ###########################
resource "aws_iam_group_policy_attachment" "art_devops_black_rotatekeys" {
  group      = aws_iam_group.art_devops_black.name
  policy_arn = aws_iam_policy.rotate_keys.arn
}

resource "aws_iam_group_policy_attachment" "art_devops_black_selfmanagemfa" {
  group      = aws_iam_group.art_devops_black.name
  policy_arn = aws_iam_policy.self_managed_mfa.arn
}

resource "aws_iam_group_policy_attachment" "art_devops_black_forcemfa" {
  group      = aws_iam_group.art_devops_black.name
  policy_arn = aws_iam_policy.force_mfa.arn
}

#######################################################

White Group

############## art DevOps Group ##################
resource "aws_iam_group" "art_devops_white" {
  name = "art_devops_white"
}

resource "aws_iam_group_membership" "art_devops_white" {
  name = aws_iam_group.art_devops_white.name

  users = [
    aws_iam_user.daniel_devart_com.name,
  ]

  group = aws_iam_group.art_devops_white.name
}

#######################################################

########### DevOps Assume Policies ####################
resource "aws_iam_group_policy_attachment" "art_devops_white" {
  count      = length(var.assume_policy_art_devops_white)
  group      = aws_iam_group.art_devops_white.name
  policy_arn = var.assume_policy_art_devops_white[count.index]
}

variable "assume_policy_art_devops_white" {
  description = "IAM Policy to be attached to user"
  type        = list(string)

  default = [
    # Please change <account_id> to the real account id number of id account 
    "arn:aws:iam::<account_id>:policy/assume-art-prod-readonly-policy", # Add readonly policy to while group user
  ]
}

#######################################################


############### MFA Manager ###########################
resource "aws_iam_group_policy_attachment" "art_devops_white_rotatekeys" {
  group      = aws_iam_group.art_devops_white.name
  policy_arn = aws_iam_policy.rotate_keys.arn
}

resource "aws_iam_group_policy_attachment" "art_devops_white_selfmanagemfa" {
  group      = aws_iam_group.art_devops_white.name
  policy_arn = aws_iam_policy.self_managed_mfa.arn
}

resource "aws_iam_group_policy_attachment" "art_devops_white_forcemfa" {
  group      = aws_iam_group.art_devops_white.name
  policy_arn = aws_iam_policy.force_mfa.arn
}

#######################################################

사용자 비밀번호 초기화

  • 테라폼으로 생성한 사용자에게 초기 비밀번호를 세팅해줍니다.

  • 세팅한 후에 해당 사용자에게 id와 비밀번호를 알려주고 패스워드 변경과 MFA 설정을 요청하시면 됩니다.

IAM > Users > 사용자 선택 > Security credentials 로 이동합니다.

Enable console access 버튼을 클릭하여 아래와 같이 세팅합니다.

Enable console access 를 진행한 후에, 해당 정보를 사용자에게 전달합니다.

Last updated

Was this helpful?