🐙

【インフラ_14日目】CI/CD_1冊目

2024/08/13に公開

こんにちは投資ロウトです。

背景

・CI/ CDをシステムに導入していかなければならない背景があります。

クレデンシャル

AWSやAzure, GCPなどで誰かがアクセスする際に、クレデンシャル情報を必要としますが、一時的なクレデンシャル情報でないと、セキュリティー的に懸念があるとのこと。

そういう時にOpenID Connectを使用すればいいとのことでした。逆に静的クレデンシャルであるSecretsなどを利用して実行するのは、アンチパターンとのこと。

またOpenID Connectは「OAuth 2.0」を利用しているため、その知識が必要不可欠とのことです。

また多くのクラウドがGitHubが生成した謎トークンを認証として使用できるかというと、GitHub OIDC Providerを信頼しているからというお話もありました。

Cloud Roles・・・一時クレデンシャルのアクセス先を管理

各クラウドを利用する認証アクション

・AWS・・・aws-actions/configure-aws-credentials
・Microsoft Azure・・・Azure/login
・GCP・・・google-github-actions/auth

OpenID Connectのハンズオンは危険な操作

誤って全GitHub アカウントへアクセスが許可されると、高額請求やデータの削除、漏洩が起きてしまう危険性があるとのこと。

そのため対策としては、プライベートリポジトリを使用しましょうとのことでした。

gh repo create リポジトリ名 --private --clone --add-readme
cd リポジトリ名

AWSを利用

# aws-cliがローカルに入っているかどうか
aws --version

awsのアカウントを開設し、AWS CloudShellを使用してもいいとのこと。

こんな感じで利用できるとのこと

# AWSのアカウントIDを取得する
aws sts get-caller-identity --query Account --output text

セキュリティー的に懸念があり、新しくユーザーを作って行う場合にCloud Shellで権限は以下を追加すれば大丈夫です。
※この先のハンズオンでもっと権限がいる必要あり。

# こちらは後ほど失敗するバージョンです
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudshell:CreateEnvironment",
                "cloudshell:GetEnvironmentStatus",
                "cloudshell:CreateSession"
            ],
            "Resource": "*"
        }
    ]
}

上記だとStsの取得コマンドでエラーが発生してしまうので、さらに権限の追加

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "sts:GetCallerIdentity",
			"Resource": "*"
		}
	]
}

AWS Cliでstsを取得しようとすると、以下のようなエラーが発生

Error when retrieving credentials from container-role: Error retrieving metadata: Received non 200 response 500 from container metadata: <?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>500 - Internal Server Error</title>
 </head>
 <body>
  <h1>500 - Internal Server Error</h1>
 </body>
</html>

類似する事象がないか調査すると、関連する記事が以下にあり。

https://dev.classmethod.jp/articles/cloudshell-lanched-minumum-authority/

どうやら以下ということらしい

CloudShellが設定なしでAWS CLIコマンドを実行できるのは、内部的かつ自動的にCloudShellの実態であるECSコンテナに付与されたIAMロール経由でクレデンシャル情報が渡されているからである

下記ポリシーに変更(stsの権限は残したままで)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudshell:CreateEnvironment",
                "cloudshell:GetEnvironmentStatus",
                "cloudshell:CreateSession",
                "cloudshell:PutCredentials",
                "cloudshell:DeleteEnvironment",
                "cloudshell:StartEnvironment"
            ],
            "Resource": "*"
        }
    ]
}

再度下記コマンドを実施してみる

# AWSのアカウントIDを取得する
aws sts get-caller-identity --query Account --output text

問題なくいった。

OpenID Connect Provider

AWSがGitHub OIDC Providerを信用するようにするとのこと。

aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 1111122222333334444455555666667777788888

また権限のエラーが発生。以下の権限を入れればよい

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:CreateOpenIDConnectProvider",
            "Resource": "arn:aws:iam::IDを入れる:oidc-provider/token.actions.githubusercontent.com"
        }
    ]
}

作業ミスをしないためにも、環境変数を利用していけばいいとのこと

export GIT_REPOSITORY="<OWNER>/<REPO>"
export GITHUB_OIDC_URL=token.actions.githubusercontent.com
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
export GITHUB_ACTIONS_ROLE=github-actions

次にロールを作成していく。特にCloud Shellではいけないわけではないので、GUIから登録していきます。

ロールを作成し

カスタム信頼ポリシーで入力していきます。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "sts:AssumeRoleWithWebIdentity",
			"Principal": {
				"Federated": "arn:aws:iam::<先ほどstsのコマンドで調べたawsのID>:oidc-provider/token.actions.githubusercontent.com"
			},
			"Condition": {
				"StringLike": {
					"token.actions.githubusercontent.com:sub": "repo:<Githubのユーザー>/<対象のリポジトリ>:*"
				}
			}
		}
	]
}

追加でIAMのReadOnlyAccessを追加します。

その後Secretsに以下の2つを登録するとのこと
・AWS_ID
・ROLE_NAME

と短いですが、以上で学習を区切りたいと思います。ご精読ありがとうございました。焦らずコツコツ頑張っていきたいと思います。

Discussion