IAM Role を使用した AWS クロスアカウントアクセスついて(AssumeRole 使用)

こんにちは、インフラの天津です。

今回は AWS のクロスアカウントアクセスを AssumeRole により権限を引き受けて行う方法について、弊社で使用されている GitLab Runner を例に書いていきます。

IAM アクセスキー、シークレットキー利用による課題

タイトルの方法の前に、まずクロスアカウントアクセスを IAM Role を使用せず行う場合はどのような構成になるでしょうか。

下記のように、IAM アクセスキー、シークレットキーを使用した構成になると思います。 (この GitLab Runner は共用のため、複数の AWS アカウントにアクセスします)

f:id:AdwaysEngineerBlog:20210708140408p:plain

この構成は一見普通に見えますが、IAM アクセスキー、シークレットキーの使用という課題を内包しています。

下記の AWS のドキュメントやクラスメソッドさんの記事にもあるとおり、可能な限り IAM アクセスキーを使用しないこと、代わりに AssumeRole による一時的な権限引受けを行うことがベストプラクティスとされています。

docs.aws.amazon.com

dev.classmethod.jp

IAM アクセスキー、シークレットキーは漏洩による影響(情報漏洩、意図しない利用による高額請求、攻撃への加担など)が大きいため、可能な限り使用せず IAM Role と AssumeRole でなんとかしてしまいましょう。

そもそも AssumeRole とは

AssumeRole とは、別アカウントなどの IAM Role を引き受けることを指します。

下記クラスメソッドさんの記事が非常に分かりやすいのでおすすめです。

dev.classmethod.jp

AWS 上の GitLab Runner からの クロスアカウントアクセスとその設定方法

では具体的な設定方法について、GitLab Runner を例に書いていきます。

全体像

GitLab Runner インスタンスと GitLab-CI 実行対象の AWS アカウント間で IAM Role の引き受け設定(AssumeRole 設定)を行ないます。

f:id:AdwaysEngineerBlog:20210708140441p:plain

設定手順

下記の手順で設定します。

  1. GitLab Runner を利用する AWS アカウントで IAM Role を作成
  2. GitLab Runner インスタンスにて、1. で作成した IAM Role を引き受ける IAM Role をインスタンスプロファイルとしてアタッチ
  3. 1.で作成した IAM Role にて 2.の IAM Role を信頼する設定を行う

文字だけで見ると IAM Role がいっぱい出てきて分かりづらいですので図示してみました。

この例では、GitLab Runner にて s3:ListAllMyBuckets の実行権限が引き受けられるよう設定しています。

f:id:AdwaysEngineerBlog:20210708140456p:plain

テキストも下記に記載しておきます

1: GitLab Runenr での Job 実行に必要 IAM Role 作成

gitlab-runner-user-role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:ListAllMyBuckets"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::*"]
    }
  ]
}

2: 1.の IAM Role を引き受ける IAM Role を作成

gitlab-runner-assume-role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::999999:role/gitlab-runner-user-role"
    }
  ]
}

3: GitLab Runenr の IAM Role を信頼する設定を実施

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111:role/gitlab-runner-assume-role"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

GitLab-CI での動作確認

動作確認用にプロジェクトを作成し、CI/CD Variables で下記のように aws cli 用のクレデンシャルを設定します。

今回は file type variables とし、cp だけで使用可能になるようにします

[default]
role_arn = arn:aws:iam::999999:role/gitlab-runner-user-role
credential_source=Ec2InstanceMetadata

次に下記のように.gitlab-ci.yml を記載します。

先程作成した variable を ~/.aws/credentials にコピーし aws cli に使用させます

---
stages:
  - run

aws_s3_ls_test:
  stage: run
  image:
    name: amazon/aws-cli
    entrypoint: [""]
  before_script:
    - mkdir ~/.aws
    - cp -p ${aws_credentials} ~/.aws/credentials
  script:
    - aws s3 ls

この設定で GitLab にて pipeline を実行すれば、利用側 AWS アカウントの bucket 一覧が表示されます。

意外と容易ではないでしょうか。

なお、こちらの例では単純にするため GitLab Runner に引き受けさせる権限として s3:ListAllMyBuckets のみ与えています。

実際には GitLab-CI で実行したい権限(これまで IAM アクセスキー、シークレットキーを使用していた場合は、その IAM ユーザの権限)を与えることで、任意の操作が可能になります。

おわりに

今回は AWS クロスアカウントアクセスについて書いてきました。

クロスアカウントアクセスにて IAM Role を活用することで、IAM アクセスキーを排除することができ、結果としてセキュリティリスクの低減につながると思います。

みなさんも管理・使用しているプロジェクトで IAM アクセスキーを使用している場合は置き換えれないか見直ししてみてはいかがでしょうか。

この記事が、 IAM アクセスキーの利用について見直す一助になれば、筆者としては幸いです。

最後までお読みいただきありがとうございました。