📌

GitHub Actionsを使ってAWS SAMアプリをデプロイする use OpenID Connect

2022/06/10に公開

現行、GitHub + CodeBuildでSAMアプリをデプロイしているのですが、CodeBuildをGitHub Actionsに置き換えたらどうなるか試してみました。
GitHub ActionsとAWSの連携は、シークレットをGitHubに保存しなくて済む、OpenID Conncetを使っています。

GitHub ActionsとCodeBuild両方使った感想は、Actionsのほうが機能が多く、複雑なことができるので新規ではじめるならActionsのほうが良いかなぁ、という印象でした。
もっとも、CodeBuildで出来ていることをわざわざActionsに移植しても、あまりメリットを感じないので、現行の環境はCodeBuildのままにしておこうと思いました。

GitHubリポジトリの準備

リポジトリの作成

  1. GitHubにログインする

  2. GitHub右上の「+」を押して「New Repository」を選択する

  3. 適当に入力して、新規リポジトリを作成する

  4. 表示されたリポジトリのURLを控えておく

Personal access tokenの作成

  1. 右上の自分のアイコンをクリック、Settingsを選択する

  2. 左メニューからDeveloper settingsを選択する

  3. 左メニューからPersonal access tokensを選択する

  4. Generate New Tokenを選択する

  5. パスワードの入力を求められたら、パスワードを入力する

  6. 下記を入力して「Generate token」を押す。

    • Note: 利用目的
    • Expiration: 30 days
    • Select scopes: repoとworkflowにチェック

Cloud9 環境作成

  1. AWSコンソールでCloud9のページを開く

  2. 「Create Environment」を押す

  3. 任意の名前を入力して「Next step」を押す

  4. スペックを選んで「Next step」を押す
    (最低スペックでも問題ないと思うが、筆者はt3.smallインスタンスを選択)

  5. 確認画面が表示されるので、内容を確認して「Create Envrionment」を押す

  6. Cloud9 コンソールで下記コマンドを実行する(名前とメールアドレスは、自分のものを入力)

    $ git config --global user.name "hoge fuga"
    $ git config --global user.email hoge-fuga@example.com
    $ git config --global init.defaultBranch main
    
  7. Cloud9 コンソールで下記コマンドを実行する

    $ git init
    $ echo ".c9*" >> .gitignore
    $ git add -A
    $ git commit -m "initial commit"
    
  8. Cloud9 コンソールで下記コマンドを実行する(リモートURLは、GitHubリポジトリ作成時に控えておいたもを入力。Usernameは、GitHubのログインに使用するものを入力。Passwordは、Personal Access Tokenを入力する)

    $ git remote add origin https://github.com/hoge-fuga/actions-sam.git
    $ git push -u origin main
    Username for 'https://github.com/hoge-fuga/actions-sam.git': hoge-fuga
    Password for 'https://hoge-fuga@github.com/hoge-fuga/actions-sam.git': 
    ...
    

SAMの準備

Lambdaのコードの準備

  1. 下記コマンドを実行してディレクトリを準備する

    $ mkdir lambda
    $ mkdir lambda/hello_aws
    $ mkdir lambda/hello_github
    $ touch lambda/hello_aws/lambda_function.py
    $ touch lambda/hello_github/lambda_function.py
    
  2. lambda/hello_aws/lambda_function.py を開き下記のようにする

    def lambda_handler(event, context):
        return("hello aws")
    
    
  3. lambda/hello_github/lambda_function.py を開き下記のようにする

    def lambda_handler(event, context):
        return("hello github")
    
    

SAMテンプレートを追加

  1. 下記コマンドを実行してSAMテンプレートファイルを作成する

    $ touch template.yaml
    
  2. template.yamlを開き下記のようにする

    AWSTemplateFormatVersion: "2010-09-09"
    Transform: AWS::Serverless-2016-10-31
    Description: >
    GitHub Actions + SAM + Lambda Kensho
    
    Globals:
    Function:
        Timeout: 60
    
    Resources:
    ###
    ### Lambda Fn.
    ###
    
    cfnFunctionHelloAws:
        Type: AWS::Serverless::Function
        Properties:
        CodeUri: lambda/hello_aws/
        Handler: lambda_function.lambda_handler
        Runtime: python3.9
    
    cfnFunctionHelloGithub:
        Type: AWS::Serverless::Function
        Properties:
        CodeUri: lambda/hello_github/
        Handler: lambda_function.lambda_handler
        Runtime: python3.9
    
  3. .gitignoreにsam関連ファイルを追加する

    $ echo ".aws-sam/*" >> .gitignore
    

Python 3.9のインストール

Python 3.9でLambda動かしたいときだけ、実施。バージョンにこだわりがない場合は、template.yamlのRuntime: python3.7 に変更すれば、当手順は省略可能。

  1. 下記コマンドを実行する

    $ sudo yum install gcc openssl-devel bzip2-devel libffi-devel 
    $ cd /opt 
    $ sudo wget https://www.python.org/ftp/python/3.9.12/Python-3.9.12.tgz 
    $ sudo tar xzf Python-3.9.12.tgz 
    $ cd Python-3.9.12
    $ sudo ./configure --enable-optimizations 
    $ sudo make altinstall 
    $ sudo rm -f /opt/Python-3.9.12.tgz 
    $ python3.9 -V
    Python 3.9.12
    

    参考:https://tecadmin.net/install-python-3-9-on-amazon-linux/

SAM Configの作成

  1. 下記コマンドのようにsam build、sam deploy --guidedを途中まで実行することによって、SAM Configファイルの作成までを行う

    $ cd ~/environment/
    $ sam build
    $ sam deploy --guided
    
    Configuring SAM deploy
    ======================
    
            Looking for config file [samconfig.toml] :  Not found
    
            Setting default arguments for 'sam deploy'
            =========================================
            Stack Name [sam-app]: actions-test 
            AWS Region [ap-northeast-1]: 
            #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
            Confirm changes before deploy [y/N]: y
            #SAM needs permission to be able to create roles to connect to the resources in your template
            Allow SAM CLI IAM role creation [Y/n]: 
            Save arguments to configuration file [Y/n]: 
            SAM configuration file [samconfig.toml]: 
            SAM configuration environment [default]: 
    
    ...
    
    
    Previewing CloudFormation changeset before deployment
    ======================================================
    Deploy this changeset? [y/N]: N
    
  2. 作成された samconfig.tomlの内容を確認する

    version = 0.1
    [default]
    [default.deploy]
    [default.deploy.parameters]
    stack_name = "actions-test"
    s3_bucket = "aws-sam-cli-managed-default-samclisourcebucket-<ランダムな値>"
    s3_prefix = "actions-test"
    region = "ap-northeast-1"
    confirm_changeset = true
    capabilities = "CAPABILITY_IAM"
    image_repositories = []
    

OIDCプロバイダ、IAMロールの作成

GitHub Actions用OIDCプロバイダの作成

  1. 下記コマンドを実行して、Cloudformationテンプレート用ファイルを作成する

    $ cd ~/environment/
    $ mkdir cloudformation
    $ cd cloudformation/
    $ touch iam-oidc.yml
    
  2. iam-oidc.ymlの中を下記のように編集する

    AWSTemplateFormatVersion: "2010-09-09"
    Description: >
    
    GitHub Actions Kensho
    
    IAM OIDC Provider for GitHub
    
    Resources:
    cfnIamOidcGithub:
        Type: AWS::IAM::OIDCProvider
        Properties:
        Url: https://token.actions.githubusercontent.com
        ClientIdList:
            - sts.amazonaws.com
        ThumbprintList:
            # Fixed Value
            - 6938fd4d98bab03faadb97b34396831e3780aea1
    
    Outputs:
    OidcGithub:
        Value: !GetAtt cfnIamOidcGithub.Arn
        Export:
        Name: OidcGithub
    
  3. 下記コマンドを実行して、Cloudformationスタックを作成する

    $ CFN_TEMPLATE="iam-oidc.yml"
    $ CFN_STACK_NAME="github-actions-kensho-iam-oidc"
    $ aws cloudformation deploy --stack-name ${CFN_STACK_NAME} \
        --template-file ${CFN_TEMPLATE}
    

GitHub Actions用IAMロール、ポリシーの作成

  1. 下記コマンドを実行して、Cloudformationテンプレート用ファイルを作成する

    $ touch iam-role.yml
    $ touch iam-role-policy.yml
    
  2. iam-role-policy.ymlの中を下記のように編集する

    AWSTemplateFormatVersion: "2010-09-09"
    Description: >
    
    GitHub Actions Kensho
    
    IAM Role and Policy for GitHub
    
    Parameters:
    GithubOrg:
        Type: String
    RepositoryName:
        Type: String
    
    Resources:
    cfnIamRoleGithub:
        Type: AWS::IAM::Role
        Properties:
        AssumeRolePolicyDocument:
            Statement:
            - Effect: Allow
                Action: sts:AssumeRoleWithWebIdentity
                Principal:
                Federated:
                    - !ImportValue OidcGithub
                Condition:
                StringLike:
                    token.actions.githubusercontent.com:sub: !Sub repo:${GithubOrg}/${RepositoryName}:*
        RoleName: github-actions-kensho
        ManagedPolicyArns:
            - !Ref cfnIAMPolicyGithub
            
    cfnIAMPolicyGithub:
        Type: AWS::IAM::ManagedPolicy
        Properties:
        PolicyDocument:
            Version: "2012-10-17"
            Statement:
            - Sid: S3ObjectPolicy
                Effect: Allow
                Action:
                - s3:*
                Resource:
                - arn:aws:s3:::aws-sam-cli-managed-default-*/*
                - arn:aws:s3:::aws-sam-cli-managed-default-*
            - Sid: CF
                Effect: Allow
                Action:
                - cloudformation:*
                Resource:
                - arn:aws:cloudformation:*:*:stack/*
                - arn:aws:cloudformation:*:aws:transform/Serverless-2016-10-31
            - Sid: IAM
                Effect: Allow
                Action:
                - iam:*
                Resource:
                - arn:aws:iam::*:role/*
            - Sid: Lambda
                Effect: Allow
                Action:
                - lambda:*
                Resource:
                - arn:aws:lambda:*:*:function:*
        ManagedPolicyName: github-actions-kensho
    
    1. 下記コマンドを実行して、Cloudformationスタックを作成する
    $ GithubOrg=<GitHubのOrganization名>
    $ RepositoryName=<GitHubのRepository名>
    $ CFN_TEMPLATE="iam-role-policy.yml"
    $ CFN_STACK_NAME="github-actions-kensho-iam-role"
    $ aws cloudformation deploy --stack-name ${CFN_STACK_NAME} \
        --template-file ${CFN_TEMPLATE} \
        --capabilities CAPABILITY_NAMED_IAM \
        --parameter-overrides \
        GithubOrg=${GithubOrg} \
        RepositoryName=${RepositoryName}
    

GitHub Actionsの作成と実行

GitHub Actionsの実行

  1. Actionsのワークフローファイルを作成する

    $ cd ~/environment/
    $ mkdir -p .github/workflows
    $ cd .github/workflows/
    $ touch sam-build-and-deploy.yml
    
  2. sam-build-and-deploy.yml の中を下記のようにする

    name: OIDC SAM Kensho
    
    on:
    push:
        branches:
        - main
    
    permissions:
    id-token: write
    contents: read
    
    jobs:
    build-and-deploy:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v2
        - uses: aws-actions/configure-aws-credentials@v1
            with:
            role-to-assume: arn:aws:iam::<AWSアカウントID>:role/github-actions-kensho
            aws-region: ap-northeast-1
        - uses: actions/setup-python@v2
            with:
            python-version: '3.9'
        - uses: aws-actions/setup-sam@v1
        - run: sam build
        - run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset
    

Actions の実行

  1. コードをコミット、プッシュする

    $ git add -A
    $ git commit -m "add-sam-lambda"
    $ git push
    
  2. GitHubのActionsの画面から実行結果を確認する

  3. Lambda関数が作成されていることを確認する

Discussion