2
1

【AWS】CI/CDの権限不足を防いで開発体験を向上する

Posted at

クラウド環境の構成管理ツールとしてIaCを使う場合、GitHub ActionsやAWS CodeBuildなどを活用することで構成管理を自動化して運用の安定性を高めることができます。

しかし、CI/CDパイプラインが権限不足でコケるというのはあるあるなのではないでしょうか(ぼくは稀によくにやります)
特にリポジトリの初期化や、CI/CD周りの仕組みを改修する際、修正のコミットを多く重ねて何度もトライ&エラーする必要が出るハメになったり・・・。

上記の悩みを解決するTipsを紹介します。
本記事ではAWSの利用を前提とします。

TL;DL - AWS Providerのassume_roleを使おう

provider "aws"の設定にassume_roleセクションを追加します。

provider.tf
provider "aws" {
  region = "ap-northeast-1"

+ assume_role {
+   role_arn = "arn:aws:iam::12345678910:role/role-to-assume"
+ }
}

これを使うとterraform planterraform applyの実行時に内部的にロールを切り替えて(assume role)処理を続行します。
切り替えた後のロールに権限不足がある場合、その時点で気づける可能性があります。しかし、これでも絶対に防げるとは限りません…。

通常CI/CDを自動化している場合、原則はローカルでterraform applyは実行せずterraform planを確認するのみ、という運用ルールが考えられます。
terraform planapplyとでは実際に実行するアクションは異なるため、やはり権限不足の可能性は残ることになります。

設定方法

上述のassume_roleに指定するIAMロールの作成方法も紹介します。

前提知識:IAMロールの信頼関係

AWS IAMにおいて「あるIAMユーザー or ロールが別のロールを使用する(= 引き受ける)」操作はAssume Roleと呼ばれます。
Assume Roleを実現するために必要な設定が信頼関係(または信頼ポリシー)で、引き受ける対象のロールに設定します。

サンプルコード

このようなIAMロールをTerraformで作成する例です。
ローカル作業用にIAMユーザー(kokado-iam-user)を使っているケースを考えます。

参考 - terraform-aws-modules/iam/aws | iam-assumable-role Submodule | Terraform Registry

role_to_assume.tf
data "aws_caller_identity" "current" {}

# --- 信頼ポリシーに設定する「Assume Role可能な(= 信頼できる)IAMユーザー」
data "aws_iam_user" "user" {
  user_name = "kokado-iam-user"
}

# --- terraform plan/apply の中で切り替えるIAMロールを定義する
module "role_to_assume_for_cicd" {
  source  = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"

  create_role = true

  role_name         = "role-to-assume-for-cicd"
  role_requires_mfa = false

  trusted_role_arns = [
    # 1. ローカル用のIAMユーザーを信頼する
    data.aws_iam_user.user.arn,
    # 2. ここで作成するロール自体も信頼する(自己信頼)
    "arn:aws:iam::${data.aws_caller_identity.current}:role/role-to-assume-for-cicd",
  ]

  custom_role_policy_arns = [
    # Assume Roleの際に iam:GetUser が必要であるため追加
    "arn:aws:iam::aws:policy/IAMReadOnlyAccess",
    # 以降は構成管理に必要なポリシーを追加する
    # arn:aws:iam::aws:policy/AmazonS3FullAccess,
    # ...
  ]
}

2. ここで作成するロール自体も信頼する(自己信頼)の解説は割愛します。詳しくは以下をご覧ください。
参考 - [仕様変更] IAM ロール信頼ポリシーの挙動が変更になり IAM ロールの「暗黙的な自己信頼」がなくなりました | DevelopersIO

なお、このIAMロール自体は事前に手動で作成しておくといった準備が必要です。
最後に動作確認です。

main.tf
data "aws_caller_identity" "current" {}
output "caller_identity" {
  value = data.aws_caller_identity.current.arn
}

簡単ですが、上記のコードを実行すると、outputで使用中の認証情報がIAMユーザーではなくassumed-role`に変わることが確認できます。

$ terraform plan
data.aws_caller_identity.current: Reading...
...
module.role_to_assume_for_cicd.aws_iam_role_policy_attachment.custom[0]: Refreshing state... [id=role-to-assume-for-cicd-20231206153119131500000001]

Changes to Outputs:
  + caller_identity    = "arn:aws:sts::12345678910:assumed-role/role-to-assume-for-cicd/aws-go-sdk-xxx"
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1