{Terraform} GitHub Actions with OIDC

 

 

参考文献: Terraform Up & Running (Yevgeniy Brikman著)
https://future-architect.github.io/articles/20230405a/

 

 


-- 1. OIDCプロバイダとロールの作成(ローカルで実行するコード)

 

cat <<-'EOF' > variables.tf

#variable "allowed_repos_branches" {
#  description = "allowed_repos_branches"
#  type = list(object({
#    org = string
#    repo = string
#    branch = string
#  }))
#  
#}
#
#variable "role_name" {
#  description = "role_name"
#  type = string
#  default = "role01"
#}

locals {
  allowed_repos_branches = [
    {
      org    = "githubuser"
      repo   = "githubrepo"
      branch = "main"
    }
  ]

  role_name = "role01"
}

 

EOF


cat <<-'EOF' > main.tf


terraform {
  required_version = "= 1.6.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "= 4.17.0"
    }
  }
}


provider "aws" {
  region = "ap-northeast-1"
}

data "tls_certificate" "github" {
  url = "https://token.actions.githubusercontent.com"
}


resource "aws_iam_openid_connect_provider" "github_actions" {
  url = "https://token.actions.githubusercontent.com"
  client_id_list = ["sts.amazonaws.com"]
  thumbprint_list = [
    data.tls_certificate.github.certificates[0].sha1_fingerprint
  ]
}

 


data "aws_iam_policy_document" "role01" {
  statement {
    actions = ["sts:AssumeRoleWithWebIdentity"]
    effect = "Allow"
    
    principals {
      identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
      type = "Federated"
    }
    
    condition {
      test = "StringEquals"
      variable = "token.actions.githubusercontent.com:sub"
      
      values = [
        for a in local.allowed_repos_branches :
        "repo:${a["org"]}/${a["repo"]}:ref:refs/heads/${a["branch"]}"
      ]
    }
  }
}

 


data "aws_iam_policy_document" "policy01" {
  statement {
    effect = "Allow"
    actions = ["ec2:*"]
    resources = ["*"]
  }
}


resource "aws_iam_role" "role01" {
  name_prefix = local.role_name
  assume_role_policy = data.aws_iam_policy_document.role01.json
}


resource "aws_iam_role_policy" "role01_policy01" {
  role = aws_iam_role.role01.id
  policy = data.aws_iam_policy_document.policy01.json
}

 


EOF


terraform init
terraform fmt

terraform -version


terraform apply -auto-approve


-- 2. EC2インスタンス作成(githubで実行するコード)

シークレット変数の設定
リポジトリの[Settings] > [Secrets and variables]からrepository secretを追加

Name → AWS_IAM_ROLE_ARN
Secret → role01のARM


mkdir test
cd test


mkdir -p .github/workflows


cat <<-'EOF' > .github/workflows/terraform.yml

name: Terraform Apply
# Only run this workflow on commits to the main branch

on:
  push:
    branches:
      - 'main'

env:
  TF_VERSION: 1.4.1
  AWS_REGION: ap-northeast-1
jobs:
  TerraformApply:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v2
      
      # Authenticate to AWS using OIDC
      
      - uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}
      # Run Terraform using HashiCorp's setup-terraform Action

      - name: terraform setup
        uses: hashicorp/setup-terraform@v1
        with: 
          terraform_version: 1.1.0
          terraform_wrapper: false

      - name: terraform run
        run: |
          terraform init
          terraform apply -auto-approve

 

 

EOF

cat <<-'EOF' > main.tf

 

provider "aws" {
  region = "ap-northeast-1"
}

resource "aws_instance" "instance01" {
  ami = "ami-0404778e217f54308"
  instance_type = "t3.nano"
  key_name = "key1"

}

EOF

 

git init

cat <<-'EOF' > .gitignore

.terraform
*.tfstate
*.tfstate.backup
EOF


git add .

git commit -m "initial commit"

git remote add origin git@github.com:githubuser/githubrepo.git

git push origin main

git tag -a "v0.0.1" -m "first release"

git push --set-upstream origin main

git push --follow-tags

 

github Actions動作確認
EC2作成確認

 

-- 3. クリーンアップ

EC2を手動で削除

※tfstateをS3で管理していないため、削除はできない

 


cd ..
terraform destroy -auto-approve