GitHub ActionsでAWSへアクセスする際に認証をどう突破するかが重要です。
GitHub の Actions secrets and variables からAWSの認証情報を読み込む方法もありますが、
機密情報を持たせておくのはセキュリティ的にはよろしくない。
そこで、AWSでOIDCを作成し、使用することを考えます。
今回は「terraform_test」という名前のGitリポジトリを使用し、
OIDCはTerraformを使用して作成します。
OIDC(OpenID Connect)を作成
こちらを参考に main.tf および iam.tfを作成します
(ディレクトリ)
terraform_test
├── .gitignore
├── README.md
├── iam.tf // 作成
└── main.tf // 作成
(main.tf)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.16" } } required_version = ">= 1.2.0" } provider "aws" { region = "ap-northeast-1" } |
(iam.tf)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#============================================================================ # Github Actions 用ロール #============================================================================ # ----------------------------------------------------------------------------- # GitHub Actions プロバイダー設定 # ----------------------------------------------------------------------------- resource "aws_iam_openid_connect_provider" "terraform_cicd" { url = "https://token.actions.githubusercontent.com" client_id_list = ["sts.amazonaws.com"] # このコードは固定値 # OIDC ID プロバイダーのサムプリント thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"] } # ----------------------------------------------------------------------------- # GitHub Actions 用ロール作成 # ----------------------------------------------------------------------------- resource "aws_iam_role" "terraform_cicd_oidc_role" { name = "TerraCICDDemoOIDCRole" path = "/" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = "sts:AssumeRoleWithWebIdentity" Principal = { Federated = aws_iam_openid_connect_provider.terraform_cicd.arn } Condition = { StringLike = { "token.actions.githubusercontent.com:sub" = [ # リポジトリ制限 # 複数定義可能 # xxxxx:GitHubのアカウント名 # terraform_testの部分はGitHubActionsを使用したいリポジトリ名 "repo:xxxxx/terraform_test:*", ] } } }] }) } # ----------------------------------------------------------------------------- # ポリシーのアタッチ(AdministratorAccess_attachment) # ----------------------------------------------------------------------------- resource "aws_iam_role_policy_attachment" "AdministratorAccess_attachment" { role = aws_iam_role.terraform_cicd_oidc_role.name # Admin権限を指定 policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" } |
上記をterraform applyしてIDプロバイダを作成します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
terraform_test$ terraform plan aws_s3_bucket.terraform_state: Refreshing state... [id=terraform-state-hisui] aws_s3_bucket_versioning.terraform_state: Refreshing state... [id=terraform-state-hisui] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_iam_openid_connect_provider.terraform_cicd will be created + resource "aws_iam_openid_connect_provider" "terraform_cicd" { + arn = (known after apply) + client_id_list = [ + "sts.amazonaws.com", ] + id = (known after apply) + tags_all = (known after apply) + thumbprint_list = [ + "6938fd4d98bab03faadb97b34396831e3780aea1", ] + url = "https://token.actions.githubusercontent.com" } # aws_iam_role.terraform_cicd_oidc_role will be created + resource "aws_iam_role" "terraform_cicd_oidc_role" { + arn = (known after apply) + assume_role_policy = (known after apply) + create_date = (known after apply) + force_detach_policies = false + id = (known after apply) + managed_policy_arns = (known after apply) + max_session_duration = 3600 + name = "TerraCICDOIDCRole" + name_prefix = (known after apply) + path = "/" + role_last_used = (known after apply) + tags_all = (known after apply) + unique_id = (known after apply) } # aws_iam_role_policy_attachment.AdministratorAccess_attachment will be created + resource "aws_iam_role_policy_attachment" "AdministratorAccess_attachment" { + id = (known after apply) + policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" + role = "TerraCICDOIDCRole" } Plan: 3 to add, 0 to change, 0 to destroy. ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. terraform_test$ terraform apply -auto-approve aws_s3_bucket.terraform_state: Refreshing state... [id=terraform-state-hisui] aws_s3_bucket_versioning.terraform_state: Refreshing state... [id=terraform-state-hisui] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_iam_openid_connect_provider.terraform_cicd will be created + resource "aws_iam_openid_connect_provider" "terraform_cicd" { + arn = (known after apply) + client_id_list = [ + "sts.amazonaws.com", ] + id = (known after apply) + tags_all = (known after apply) + thumbprint_list = [ + "6938fd4d98bab03faadb97b34396831e3780aea1", ] + url = "https://token.actions.githubusercontent.com" } # aws_iam_role.terraform_cicd_oidc_role will be created + resource "aws_iam_role" "terraform_cicd_oidc_role" { + arn = (known after apply) + assume_role_policy = (known after apply) + create_date = (known after apply) + force_detach_policies = false + id = (known after apply) + managed_policy_arns = (known after apply) + max_session_duration = 3600 + name = "TerraCICDOIDCRole" + name_prefix = (known after apply) + path = "/" + role_last_used = (known after apply) + tags_all = (known after apply) + unique_id = (known after apply) } # aws_iam_role_policy_attachment.AdministratorAccess_attachment will be created + resource "aws_iam_role_policy_attachment" "AdministratorAccess_attachment" { + id = (known after apply) + policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" + role = "TerraCICDOIDCRole" } Plan: 3 to add, 0 to change, 0 to destroy. aws_iam_openid_connect_provider.terraform_cicd: Creating... aws_iam_openid_connect_provider.terraform_cicd: Creation complete after 1s [id=arn:aws:iam::××××××××××××:oidc-provider/token.actions.githubusercontent.com] aws_iam_role.terraform_cicd_oidc_role: Creating... aws_iam_role.terraform_cicd_oidc_role: Creation complete after 1s [id=TerraCICDOIDCRole] aws_iam_role_policy_attachment.AdministratorAccess_attachment: Creating... aws_iam_role_policy_attachment.AdministratorAccess_attachment: Creation complete after 1s [id=TerraCICDOIDCRole-××××××××××××] |
AWSコンソールでも作成が確認できました
いったんここまでの内容をmainブランチにcommit、pushしておきます
1 2 3 |
$ git add . $ git commit -m "create_OIDC" $ git push |
GitHub Actions でAWSにアクセスできるかテスト
terraform_testリポジトリからAWSにアクセスできるかテストしてみます!
mainブランチからテスト用のtestブランチをきります
1 2 3 4 5 6 7 |
terraform_test$ git branch * main terraform_test$ git checkout -b test Switched to a new branch 'test' terraform_test$ git branch main * test |
GitHub Actionsのワークフローを定義するため、
.github/workflows/aws_access_test.yml を作成します
(ディレクトリ)
terraform_test
├── .github
│ └── workflows
│ └── aws_access_test.yml // 作成
├── .gitignore
├── README.md
├── iam.tf
└── main.tf
こちらを参考にaws_access_test.ymlに記述していきます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
name: AWS Deploy on: push: branches: # 作業ブランチ - test env: # ×××××××××:AWSアカウントID AWS_ROLE_ARN: arn:aws:iam::×××××××××:role/TerraCICDOIDCRole permissions: id-token: write contents: read jobs: aws-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: ${{ env.AWS_ROLE_ARN }} aws-region: ap-northeast-1 - run: aws sts get-caller-identity |
testブランチにpushした際に
aws sts get-caller-identity
が実行されるワークフローが定義できました!
このワークフローでGitHub ActionsからAWSにアクセスできるかpushして確認します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
terraform_test$ git add . terraform_test$ git commit -m "commit aws_access_test.yml" terraform_test$ git push origin test Enumerating objects: 6, done. Counting objects: 100% (6/6), done. Delta compression using up to 16 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (5/5), 743 bytes | 743.00 KiB/s, done. Total 5 (delta 1), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), completed with 1 local object. remote: remote: Create a pull request for 'test' on GitHub by visiting: remote: https://github.com/×××××××××/terraform_test/pull/new/test remote: To https://github.com/×××××××××/terraform_test.git * [new branch] test -> test |
GitHub > リポジトリ > Actions から結果を確認できます
無事成功していますね!
参考
コメント