1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CircleCI からOIDCを利用して AWS へ安全にデプロイする方法

1
Posted at

AWSでアプリケーションを構築・運用している場合、CI / CDサービスとAWSアカウントの連携は避けて通れません。コンテナイメージのデプロイやE2Eテスト用の環境構築の自動化、CloudFormation / AWS CDKなどを利用したアプリケーションの本番リリース作業やAmazon Bedrockを利用したCIタスクの実行など、さまざまな形でAWSアカウントとの連携が必要となります。

CircleCIとAWSアカウントの安全な連携には、 OIDC(OpenID Connect)が利用できます。この記事では、CircleCI と AWS を OIDC で連携し、ECR へのイメージ push までを自動化するパイプラインを構築します。

なぜ OIDC なのか

AWS は現在、セキュリティ上の理由から永続的なアクセスキーとシークレットキーの利用を非推奨としています。

ベストプラクティスとして、AWS アカウント内に個別に IAM ユーザーを作成するのではなく、ID プロバイダーとのフェデレーションを使用して AWS リソースにアクセスするように人間のユーザーに求めることをお勧めします。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers.html

そのため、CircleCI から AWS へアクセスする際は、最新のベストプラクティスである OIDC(OpenID Connect)連携を採用します。

OIDC を採用するメリット

OIDCを利用した場合、AWSへのアクセスに利用する認証情報を使い捨てにします。CircleCI が発行した「一定時間で利用できなくなる認証情報」にてアクセスするため、万が一の漏洩リスクについても最小限に抑えることができます。

このように必要な時にだけアクセスキーを使い捨てる形を取るため、CircleCI上に保存した情報のローテーション作業なども不要となります。

より安全かつ効率的にAWSアカウントへのアクセスを実現する方法として、OIDCを利用した連携を推奨します。

AWSとCircleCIそれぞれで設定を行う

OIDCでの連携は、AWS / CircleCI両方で設定が必要です。
AWSにて指定したCircleCIの組織(Organization)へのアクセスを許可するIAMロールやIdentity Providerを発行します。
その後、作成したIAMロールをCircleCIのOrganization Contextに保存することで、連携が完了します。

ここからはstep by stepで方法を紹介します。

AWS 側の設定

まずAWS側でOIDCに利用するProviderやIAMロールを作成しましょう。

Step 1: CircleCI 組織ID を取得

CircleCI の Web アプリにログインし、Organization Settings → Overview に移動します。Organization ID(UUID 形式)が表示されていますので、コピーしましょう。

スクリーンショット 2026-01-09 14.15.59.png

この ID は AWS 側の設定で複数回使用します。

Step 2: Identity Provider を作成

AWS Console で IAM → Identity providers → Add provider に移動し、以下を情報を入力しましょう。

項目
Provider type OpenID Connect
Provider URL https://oidc.circleci.com/org/<organization_id>
Audience <organization_id>

スクリーンショット 2026-01-09 14.18.04.png

<organization_id> には Step 1 で取得した組織ID を入れ、プロバイダーを作成しましょう。

Step 3: IAM Role を作成

Identity Provider の作成に成功すると下の画像のようなメッセージが表示されます。「ロールの割り当て」ボタンをクリックしましょう。もしメッセージが消えてしまった場合は、IAMのページからロールを新しく作成する画面操作でも、同様のアクションが行えます。

スクリーンショット 2026-01-09 14.19.14.png

まずは「信頼されたエンティティタイプ」から「ウェブアイデンティティ」を選びます。その後下にフォームが表示されます。

スクリーンショット 2026-01-09 14.19.53.png

以下の表を参考に情報を選択・入力しましょう。

項目
Identity provider 作成した CircleCI provider
Audience 組織ID

続いてロールに設定する権限を付与しましょう。ここで付与する権限は、CircleCI上で実行されるパイプラインにて利用するAWSリソースやアクションについて設定します。例えばECRへのpushを行う場合はAmazonEC2ContainerRegistryPowerUserなどを設定しましょう。

スクリーンショット 2026-01-09 14.20.24.png

今回はシンプルさを優先してAWSが用意しているポリシーを選択しました。
実際のプロジェクトでは、最小限の権限に絞ったカスタムのポリシーを作成されることを推奨します。

ロールの作成後、信頼関係タブに移動します。

スクリーンショット 2026-01-09 14.23.58.png

ここでは以下のような JSON が表示されています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<account_id>:oidc-provider/oidc.circleci.com/org/<organization_id>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.circleci.com/org/<organization_id>:aud": "<organization_id>"
        }
      }
    }
  ]
}

各フィールドの意味は次の通りです。

  • Principal.Federated: どの Identity Provider を信頼するか
  • Action: Web Identity での Role 引き受けを許可
  • Condition: CircleCI の組織ID が一致する場合のみ許可

作成したロールの ARN(例: arn:aws:iam::123456789012:role/circleci-oidc-role)をメモしておきましょう。

これでAWS側の作業は完了です。

CircleCI 側の設定

続いてCircleCI側の設定を行います。ここからは、先ほど作成したAWSのIAMロールやプロバイダーをパイプラインで利用できるようにしていきます。

Context を作成する

まずCircleCIのContextを作成しましょう。これはCircleCIにおける環境変数をプロジェクト間で共有できる仕組みです。OIDCで利用するIAMロールをContextへ保存することで、複数のプロジェクトで追加設定なくAWSアクセスができるようになります。

スクリーンショット 2026-02-19 14.14.49.png

コンテキストは特定のチーム・ユーザーでのみ利用できる設定にすることが可能です。
これにより「本番リリースのパイプラインは特定のユーザーのみ実施できる」などの運用管理が実現できます。

詳細はドキュメントをご確認ください。
https://circleci.com/docs/guides/security/contexts/#restrict-a-context

CircleCI のダッシュボードにて、 Organization Settings → Contexts に移動しましょう。Create Contextボタンをクリックして、コンテキストを作成します。
スクリーンショット 2026-01-09 14.24.40.png

名前は aws-oidc など、わかりやすいものにします。もし本番とテスト環境などで複数のAWSアカウントあるいはIAMポリシーを使い分けたい場合は、そのような名前にしましょう。

スクリーンショット 2026-01-09 14.24.52.png

フォームでは環境変数の名前と値を入力します。名前にはAWS_ROLE_ARNを入力し、コピーしたIAMロールのARNを入力しましょう。

スクリーンショット 2026-01-09 14.26.05.png

この作業を3回繰り返し、以下の表にあるデータをContextへ登録してください。

変数名 値の例
AWS_ROLE_ARN arn:aws:iam::123456789012:role/circleci-oidc-role
AWS_REGION ap-northeast-1
AWS_ACCOUNT_ID 123456789012

スクリーンショット 2026-01-09 14.27.15.png

プロジェクトの環境変数に、プロジェクト固有の情報を保存する

デプロイや取得・操作を行いたいAWSリソースに関する情報は、プロジェクトごとに環境変数へ保存しましょう。ECR リポジトリ名や ECS クラスター名・S3バケット名などを保存します。

変数名 値の例
ECR_REPO_NAME my-app

スクリーンショット 2026-01-09 14.28.02.png

config.yml を実装する

最後にCircleCIのジョブを設定しましょう。.circleci/config.ymlに次のような形でジョブを定義します。

workflows:
  deploy:
    jobs:
      - aws-ecr/build_and_push_image:
          context: aws-oidc
          auth:
            - aws-cli/setup:
                role_arn: ${AWS_ROLE_ARN}
                region: ${AWS_REGION}
          repo: ${ECR_REPO_NAME}
          tag: ${CIRCLE_SHA1}

ポイントは、workflowsjobsそれぞれにcontext: aws-oidcを追加することです。これにより該当のジョブでコンテキストを利用したOIDCによる認証情報の取得が行えるようになります。

スクリーンショット 2026-01-09 14.33.41.png

実際の認証については、CircleCIが提供するorbsを組み合わせることで、AWS CLIのコマンドなどを記述せずに実行できます。

完成系の例として、NodejsのアプリをビルドしてECRにプッシュする例を用意しました。build と test を並列実行し、両方成功したら ECR に pushします。

version: 2.1

orbs:
  node: circleci/node@7.2.1
  aws-cli: circleci/aws-cli@5.4.1
  aws-ecr: circleci/aws-ecr@9.8.1

jobs:
  build:
    executor: node/default
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: npm
      - run:
          name: TypeScript ビルド
          command: npm run build

  test:
    executor: node/default
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: npm
      - run:
          name: Run tests with JUnit reporter
          command: |
            mkdir -p test-results
            npm test -- --reporter=junit --outputFile=test-results/junit.xml --coverage
      - store_test_results:
          path: test-results
      - store_artifacts:
          path: coverage

workflows:
  build-test-deploy:
    jobs:
      - build
      - test
      - aws-ecr/build_and_push_image:
          context: aws-oidc
          auth:
            - aws-cli/setup:
                role_arn: ${AWS_ROLE_ARN}
                region: ${AWS_REGION}
          region: ${AWS_REGION}
          account_id: ${AWS_ACCOUNT_ID}
          repo: ${ECR_REPO_NAME}
          tag: ${CIRCLE_SHA1}
          requires:
            - build
            - test
          filters:
            branches:
              only: main

この構成では4つの orbs を使用しています。

orbs を使うことで、複雑な処理を数行の設定で実現できます。

例えば「Docker イメージのビルドと ECR へのプッシュ」というタスクは、aws-ecr orbにあるaws-ecr/build_and_push_image を利用しています。

スクリーンショット 2026-01-09 14.35.03.png

regionaccount_id を明示的に指定しないと、ECR の URL が正しく構築されずエラーになる点に注意しましょう。

region: ${AWS_REGION}
account_id: ${AWS_ACCOUNT_ID}
repo: ${ECR_REPO_NAME}
tag: ${CIRCLE_SHA1}

tag には ${CIRCLE_SHA1}(コミットハッシュ)を使用しています。これにより、どのコミットからビルドされたイメージかを追跡できます。

トラブルシューティング

実際に構築する中で遭遇しやすいエラーと解決策を紹介します。

AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity

このエラーが出た場合、原因は3つ考えられます。

原因1: Context が指定されていない

OIDC トークンは Context を使用するジョブでのみ発行されます。ワークフローで context: を指定しているか確認してください。

# NG: context がない
- aws-ecr/build_and_push_image:
    requires:
      - build

# OK: context を指定
- aws-ecr/build_and_push_image:
    context: aws-oidc
    requires:
      - build

原因2: Identity Provider が作成されていない

AWS IAM → Identity providers に CircleCI の Provider が存在するか確認してください。Trust Policy に ARN を書いただけでは Provider は作成されません。

原因3: Organization ID の不一致

CircleCI の Organization ID と、AWS の Identity Provider / Trust Policy に設定した ID が完全に一致しているか確認してください。余分なスペースや改行が入っていることもあります。

invalid tag / invalid reference format(ECR URL エラー)

スクリーンショット 2026-01-09 14.29.45.png

ECR の URL にリージョンが含まれていないと発生します。

ERROR: failed to build: invalid tag "************.dkr.ecr..amazonaws.com/..."

aws-ecr/build_and_push_imageregionaccount_id パラメータを追加してください。

- aws-ecr/build_and_push_image:
    region: ${AWS_REGION}
    account_id: ${AWS_ACCOUNT_ID}
    # ...

まとめ

CircleCI と AWS の OIDC 連携を設定し、ECR へのデプロイパイプラインを構築しました。OIDCを利用した連携にすることで、シークレット情報を発行・保存する必要がなくなり、よりセキュアにアプリケーションのデプロイやテストをAWSと連携して行えるようになります。

またAWSへのデプロイについては、サービスに対応したさまざまな orbs が公開されています。今回はECRを紹介しましたが、SAMやAWS CLI / CodeDeployなどにも対応していますので、ぜひお試しください。

terrafromにも対応しています。

参考リンク

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?