目的
- AWSソリューションアーキテクトの勉強を踏まえてUdemyで勉強中
- ただコンソールを触っていてもつまらないので
Terraform
の勉強を含めてハンズオンを実施
投稿で説明すること
- IAMについての基本的な説明
- IAMとは
- IAMユーザ
- IAMグループ
- IAMロール
- IAMポリシー
- Terraformを使ったハンズオン
- ポリシーの作成
- グループの作成
- ポリシーをアタッチ
- ユーザの作成
- グループに参加させる
IAMの概要
- AWS Identity and Access Managementの略をとってIAM
- AWS利用者認証の設定やアクセスポリシーの設定、ユーザまたはグループに対してアクセス制限を与えたりする
全体のイメージ
- IAMユーザにポリシーを適用する場合には1ユーザに紐づいている
- IAMグループは複数のIAMユーザが所属している
- IAMロールはあるAWSサービスが別のAWSサービスに操作を行う場合
- EC2がS3に対してファイルをアップロードするなど
IAMユーザ
-
ルートユーザ
とルートユーザから作成されるユーザ
が存在する-
ルートユーザ
はAWSアカウントを作成した際に一番最初に作られる - Admin権限以外にAWSサービスの停止やルートユーザのアカウントなど
ルートユーザ
にしかできない操作がある - アクセスキーが漏洩した場合には影響が非常に大きいため、通常の開発や運用では利用しない
- MFA(多要素認証)を設定しておき、乗っ取られない対策をしておく
-
- 1つのAWSアカウントに対して5000ユーザまで作成が可能
- 個人利用であればIAMユーザを作成してそれぞれにIAMポリシーを割り当てればいいかもしれない、各人毎にポリシーをアタッチするのは面倒が多すぎる
IAMグループ
- 複数のIAMユーザを特定のグループに束ねる
- AさんとBさんはシステム管理者なので
Administratorグループ
に所属 - Cさんはシステム運用者なので
Operationグループ
に所属
- AさんとBさんはシステム管理者なので
- 1つのAWSアカウントで300グループまで作成が可能
IAMポリシー
- どのリソースにアクセスできるのかJSON形式で定義したもの
- ACLに近いかもしれない
- Effect
-
Allow
:リソースへの操作を許可する -
Deny
:リソースへの操作を拒否する
-
- Action
- ポリシーをかける対象の操作
- S3に保存されているオブジェクトの取得など
- ポリシーをかける対象の操作
- Resource
- ある特定のAWSリソースに限定する場合に
ARN
で記述する
- ある特定のAWSリソースに限定する場合に
- Condition
- ポリシーが適用される条件
- 特定のIPアドレスからの接続のみ許可など
- ポリシーが適用される条件
S3へのフルアクセスを許可する場合
{
"Effect": "Allow",
"Action": [
"S3:*",
],
"Resources": [
"arn:aws:s3::mybucket"
],
"Condition": {
"IpAddress":{
"aws:SourceIP":
["192.168.10.1/32"]
}
}
}
- ポリシーには
管理ポリシー
とインラインポリシー
が存在する
管理ポリシー
- 1つのポリシーを複数のユーザやグループに同種の権限を付与できる
- AWS管理ポリシーとカスタマー管理ポリシーが存在する
- AWS管理ポリシーはAWS側が用意しているポリシー
- カスタマー管理ポリシーはユーザ自身が管理するポリシー
- 最大5世代までバージョン管理が可能
インラインポリシー
- ポリシーと対象が
1対1
で紐づくポリシー- 複数のユーザ・グループで同種のポリシーを共有できない
Terraformでのハンズオン
前提
- Terraformを扱える
AdministratorAccess
ポリシーをアタッチしたIAMユーザを作成している - Terraformの環境構築が完了している
想定
-
AdministratorPolicy
の操作権限もつIAMグループを作成する(グループ名Administrator) -
AmazonEC2FullAccess
・AmazonS3FullAccess
の操作権限をもつIAMグループを作成する(グループ名Application) -
AmazonEC2FullAccess
・AmazonS3FullAccess
・AWSConfigRole
も操作権限をもつIAMグループを作成する
ディレクトリ構造
.
├── iam_policy
│ ├── main.tf
│ └── policy
│ ├── administrator_policy.json
│ ├── application_policy.json
│ └── operation_policy.json
├── main.tf
└── note.md
IAMグループを作成(/iam_policy)
- AWS管理ポリシーをそのまま利用しているため、ポリシーのJSONについては今回は割愛
-
resource aws_iam_policy
でIAMポリシーを作成する -
policy = "${file("ファイルパス")}
で適用するポリシーを定義する- もちろんtfファイルにインラインで書くこともできる
- 後でIAM Groupにアタッチするので
output
でARNを出力させています
iam_policy/main.tf
resource "aws_iam_policy" "AdministrationPolicy" {
name = "AdministerPolicy"
policy = "${file("iam_policy/policy/administrator_policy.json")}"
}
resource "aws_iam_policy" "ApplicationPolicy" {
name = "AppcalitionPolicy"
policy = "${file("iam_policy/policy/application_policy.json")}"
}
resource "aws_iam_policy" "OperationPolicy" {
name = "OpperationPolicy"
policy = "${file("iam_policy/policy/operation_policy.json")}"
}
#
# Ouput
#
output "Administrator_policy_arn" {
value = "${aws_iam_policy.AdministrationPolicy.arn}"
}
output "Application_policy_arn" {
value = "${aws_iam_policy.ApplicationPolicy.arn}"
}
output "Operation_policy_arn" {
value = "${aws_iam_policy.OperationPolicy.arn}"
}
IAMユーザを作成
-
aws_iam_user
でIAMユーザを作成する-
force_destory
を設定するとIAMユーザを削除時にログインプロファイルやアクセスキーも一緒に削除してくれる
-
-
aws_iam_user_login_profile
はWebコンソールログイン時のログイン情報となる-
pgp_key
の設定にはbase64でエンコードされた公開鍵かkeybaseで作成したユーザと紐付ける - 今回はgpgコマンドで作成し、base64文字列を変数に入れて実装
- テストだから1個しか作らなかったが、本番利用時にはユーザ毎に証明書を作成する
-
-
aws_iam_access_key
はAWS-CLIやAPIを利用する際に使う認証情報となる
iam_user/main.tf
variable "pgp_key" {
default = "(base64でエンコードされた公開鍵)"
}
#
# Adminユーザ
#
resource "aws_iam_user" "admin_exp" {
name = "admin.example.one"
path = "/"
force_destroy = true
}
resource "aws_iam_user_login_profile" "admin_exp_login_profile" {
user = "${aws_iam_user.admin_exp.name}"
pgp_key = "${var.pgp_key}"
}
resource "aws_iam_access_key" "admin_exp_access_key" {
user = "${aws_iam_user.admin_exp.name}"
pgp_key = "${var.pgp_key}"
}
output "administrator_IAM_name" {
value = "${aws_iam_access_key.admin_exp_access_key.*.user}"
}
output "administrator_IAM_id" {
value = "${aws_iam_access_key.admin_exp_access_key.*.id}"
}
output "administrator_IAM_encrypted_secret" {
value = "${aws_iam_access_key.admin_exp_access_key.*.encrypted_secret}"
}
#
# Operationユーザ
#
resource "aws_iam_user" "operation_exp" {
name = "operaion.example.one"
path = "/user/operation"
force_destroy = true
}
resource "aws_iam_user_login_profile" "operation_exp_login_profile" {
user = "${aws_iam_user.operation_exp.name}"
pgp_key = "${var.pgp_key}"
}
resource "aws_iam_access_key" "operation_exp_acccess_key" {
user = "${aws_iam_user.operation_exp.name}"
pgp_key = "${var.pgp_key}"
}
output "operations_IAM_name" {
value = "${aws_iam_access_key.operation_exp_acccess_key.*.user}"
}
output "operations_IAM_id" {
value = "${aws_iam_access_key.operation_exp_acccess_key.*.id}"
}
output "operations_IAM_encrypted_secret" {
value = "${aws_iam_access_key.operation_exp_acccess_key.*.encrypted_secret}"
}
#
# Application ユーザ
#
resource "aws_iam_user" "application_exp" {
name = "operaion.example.one"
path = "/user/application"
force_destroy = true
}
resource "aws_iam_user_login_profile" "application_exp_login_profile" {
user = "${aws_iam_user.application_exp.name}"
pgp_key = "${var.pgp_key}"
}
resource "aws_iam_access_key" "application_exp_access_key" {
user = "${aws_iam_user.application_exp.name}"
pgp_key = "${var.pgp_key}"
}
output "applications_IAM_name" {
value = "${aws_iam_access_key.application_exp_access_key.*.user}"
}
output "application_IAM_id" {
value = "${aws_iam_access_key.operation_exp_acccess_key.*.id}"
}
output "application_IAM_encrypted_password" {
value = "${aws_iam_access_key.operation_exp_acccess_key.*.encrypted_secret}"
}
IAMグループを作成
-
variable
は他のモジュールで作成したOutputを受け取る想定 -
aws_iam_group
でIAMグループを作成する -
aws_iam_group_policy_attachment
でポリシーをアタッチする -
aws_iam_group_policy_attachment
が肝- usersは配列を想定している
-
element
を利用する
/iam_group/main.tf
variable "AdministrationsRoleARN" {}
variable "OperationsRoleARN" {}
variable "ApplicationsRoleARN" {}
variable "AdministrationsUsers" {
type = "list"
}
variable "OperationsUsers" {
type = "list"
}
variable "ApplicationsUsers" {
type = "list"
}
#
# グループ作成
resource "aws_iam_group" "Administrators" {
name = "Administrators"
path = "/"
}
resource "aws_iam_group" "Applications" {
name = "Applications"
path = "/users/applications/"
}
resource "aws_iam_group" "Operations" {
name = "Operations"
path = "/users/operations/"
}
#
# グループへのポリシーアタッチ
#
resource "aws_iam_group_policy_attachment" "AdministratorsPolicyAttachment" {
group = "${aws_iam_group.Administrators.name}"
policy_arn = "${var.AdministrationsRoleARN}"
}
resource "aws_iam_group_policy_attachment" "ApplicationsPolicyAttachment" {
group = "${aws_iam_group.Applications.name}"
policy_arn = "${var.OperationsRoleARN}"
}
resource "aws_iam_group_policy_attachment" "OperationsPolicyAttachment"{
group = "${aws_iam_group.Operations.name}"
policy_arn = "${var.OperationsRoleARN}"
}
#
# ユーザをグループに参加させる
#
resource "aws_iam_group_membership" "Administrations" {
count = "${length(var.AdministrationsUsers)}"
name = "Administrators-group-membership"
users = [
"${element(var.AdministrationsUsers, count.index)}"
]
group = "${aws_iam_group.Administrators.name}"
}
resource "aws_iam_group_membership" "Operations" {
count = "${length(var.OperationsUsers)}"
name = "Operations-group-membership"
users = [
"${element(var.OperationsUsers, count.index)}"
]
group = "${aws_iam_group.Operations.name}"
}
resource "aws_iam_group_membership" "Applications" {
count = "${length(var.ApplicationsUsers)}"
name = "Applications-group-membership"
users = [
"${element(var.ApplicationsUsers, count.index)}"
]
group = "${aws_iam_group.Applications.name}"
}
main.tf
provider "aws" {
region = "ap-northeast-1"
}
module "iam_policy" {
source = "./iam_policy"
}
module "iam_user" {
source = "./iam_user"
}
module "iam_group" {
# Policy Arn
AdministrationsRoleARN = "${module.iam_policy.Administrator_policy_arn}"
OperationsRoleARN = "${module.iam_policy.Operation_policy_arn}"
ApplicationsRoleARN = "${module.iam_policy.Application_policy_arn}"
# Users
AdministrationsUsers = "${module.iam_user.administrator_IAM_name}"
OperationsUsers = "${module.iam_user.operations_IAM_name}"
ApplicationsUsers = "${module.iam_user.applications_IAM_name}"
source = "./iam_group"
}