今回やりたいこと
mainブランチにマージされたタイミングで、自動的にサーバーへ最新のソースコードを反映したい!!!!!!!😿
なんでOIDCを選ぶ流れになったのか
最初はアクセスキーや SSH を使った方法でやろうと思っていたのですが、SSH接続する場合IP制限をかけていたためGitHub Actions からの接続がすべて弾かれてしまいました。
(全部綺麗に整えてから、これいけるで!って思ったら根本がダメでした🫨)
弾かれたならば、許可IPを追加すれば、、、!と思いましたが世の中うまく行きませんよね🥲💦
GitHub Actions の実行環境は IP が固定ではないため、この方法は現実的ではありません。
けどIP制限を外すわけにもいかないし今の条件のまま行くことはできないんですかぇ???っと思ってたどり着いた先が
💡OIDC + AWS SSM💡というわけでした。
以下私が行った手順になります。
手順
1.IDプロバイダーの作成
コンソールから>IAM>IDプロバイダの画面へ行き追加を行ってください。
設定は下記画像の通りになります。
プロバイダのタイプ:OpenID Connect
プロバイダのURL:https://token.actions.githubusercontent.com
対象者:sts.amazonaws.com
2.IAMロールの作成
コンソールからロールを開き、ロールの作成を行います。
2.1カスタム信頼ポリシーの設定
信頼されたエンティティタイプの選択で、カスタム信頼ポリシーを選びます。
カスタム信頼ポリシーには下記JSONを貼り付けてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<AWSアカウントID>:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:<GitHubユーザー名>/<GitHubリポジトリ名>:ref:refs/heads/<ブランチ名>"
}
}
}
]
}
上記コード内にある以下4項目を書き換えていきます!
- < AWSアカウントID>
- < GitHubユーザー名>
- < GitHubリポジトリ名>
- < ブランチ名>
< GitHubユーザー名 >と< GitHubリポジトリ名 >がわからない場合はGitHubリポジトリのURLを見れば確認できます!👀
例)
例えば、リポジトリurlが下記の場合
https://github.com/xxxxx/banana
< GitHubユーザー名 >->xxxxx
< GitHubリポジトリ名 >->banana
"token.actions.githubusercontent.com:sub":
"repo:<GitHubユーザー名>/<GitHubリポジトリ名>:ref:refs/heads/<ブランチ名>"
今回のポリシーではこの部分を追加することで、特定のリポジトリの特定のブランチのみから許可するようになっています!
今回はmainブランチからのみ反映されて欲しいのでこのような設定を行っています。
2.2許可ポリシーの設定
先ほど作成したロールに対して許可するアクションを設定してきます!
ここでこのロールがやっていいアクションを設定します。
今回は、サーバーの中に入ってコマンドを叩いて欲しいのでこちらのアクションを許可していきます!
先ほど作成したロールから>ポリシーの作成>サービスの選択を行ってください。
選択するサービスはSystems Manageです。
SSM = AWS Systems Managerとは???????
こちらが今回やりたいSSH接続せずにサーバー操作する!という願いを叶えてくれるawsのサービスです
許可アクションの設定
以下アクションを許可。
今回以下3つを入れたんだけど記事書きながら下二つの括弧で囲んでるやつはいらないなと思った。。
入れるならGetCommandInvocationこっちの方が良さそう。
ssm:SendCommand ->EC2 に対してコマンド実行を指示
(ssm:ListCommands -> 過去に実行したコマンド一覧を見る)
(ssm:ListCommandInvocations -> 各コマンドの実行状況一覧を見る)
-----------------------
今回こちら入れてないけどこれを追加するとコマンドの実行結果を知れるみたい。
- GetCommandInvocation
最小構成なら以下がおすすめかも
{
"Action": [
"ssm:SendCommand",
"ssm:GetCommandInvocation"
]
}
2.3リソースの設定
先ほどのポリシーの許可アクションの下にあるリソースを全て許可ではなく特定のものに絞る!
知らないところで勝手にコマンド実行されていたら怖いからSendCommandのアクションにはリソースを特定に絞って設定した!
documentには
instanceには実行を許可したいインスタンスARNを入れてください
コンソールよりEC2>実行したいインスタンス>詳細>インスタンスARNを貼り付けでOK
document: arn:aws:ssm:ap-northeast-1::document/AWS-RunShellScript
instance: arn:aws:ec2:<リージョン>:<AWSアカウントID>:instance/<インスタンスID>
間違ったインスタンスでコマンドが実行されないようにっていうのが私の中ではいちばんのこいつの目的!

3.ワークフローを作成
最後にワークフローを作成することで準備は完了です!
設定がうまく行っていればsshを使わずともサーバー内でコマンドを実行することができるでしょう!!!
参考


