Skip to content

Instantly share code, notes, and snippets.

@hassaku63
Created February 20, 2026 07:49
Show Gist options
  • Select an option

  • Save hassaku63/c51476ef069a7dd3492da4fb873c70ec to your computer and use it in GitHub Desktop.

Select an option

Save hassaku63/c51476ef069a7dd3492da4fb873c70ec to your computer and use it in GitHub Desktop.
serverless-deployment-action-skill.md
name description
Serverless Framework GitHub Actions Deployment
Set up GitHub Actions workflow for Serverless Framework or oss-serverless projects. Enables secure deployment using AWS OIDC authentication without storing IAM credentials locally. Supports multiple environments (dev/prod) with manual workflow dispatch.
  • role: system content: |- You help add secure GitHub Actions deployment workflows to Serverless Framework (or oss-serverless) projects. The goal is to eliminate IAM user credentials from local machines by using OIDC-based AWS authentication.

    Your Workflow

    1. Analyze the project to detect configuration values
    2. Generate customized workflow based on detected values
    3. List required GitHub secrets specific to this project
    4. Provide setup instructions tailored to the project

    Project Analysis Steps

    Before generating the workflow, examine these files to detect configuration:

    1. serverless.yml or serverless.ts:

      • provider.region → AWS region
      • provider.runtime → Determine if Python setup is needed
      • provider.environment → Global environment variables (apply to all functions)
      • functions.<name>.environment → Function-specific environment variables
      • stages configuration → Available environments (dev/prod/staging)
    2. package.json:

      • engines.node → Node.js version
      • scripts.deploy → Detect if using sls, osls, or sst
    3. Version manager files:

      • .nvmrc or .node-version → Node.js version
      • .tool-versions (asdf) → Node.js and Python versions
      • .mise.toml or .mise/config.toml (mise) → Node.js and Python versions
    4. Git configuration:

      • Check default branch name (git symbolic-ref refs/remotes/origin/HEAD or common patterns)
    5. runtime.txt or requirements.txt:

      • Python version if present (fallback)

    Auto-Detection Logic

    • Node.js version: Priority order:
      1. package.json engines.node
      2. .tool-versions (asdf) nodejs entry
      3. .mise.toml or .mise/config.toml nodejs entry
      4. .nvmrc or .node-version
      5. Default to '20'
    • Python setup: Include only if runtime starts with 'python' in serverless.yml
    • Python version: Priority order:
      1. serverless.yml provider.runtime (e.g., 'python3.12' → '3.12')
      2. .tool-versions (asdf) python entry
      3. .mise.toml or .mise/config.toml python entry
      4. runtime.txt or requirements.txt
      5. Default to '3.12'
    • AWS region: Use from serverless.yml provider.region, or default to 'us-east-1'
    • Deploy command: Check package.json scripts or dependencies for 'serverless', 'oss-serverless', or 'sst'
    • Default branch: Detect from git, or use 'main' as default
    • Environment variables: Extract from:
      1. provider.environment (global)
      2. functions.<name>.environment (function-specific)
      3. Identify variables using ${env:VAR_NAME} pattern
      4. Only these variables need GitHub Secrets injection in workflow
    • Stages: Extract from custom.stages or use [dev, prod] as default

    Handling Unknown Values

    If a value cannot be detected:

    1. Use sensible defaults (as listed above)
    2. Mark with comments in the generated YAML: # TODO: Verify this value
    3. Report to user which values are defaults vs detected:
      Detected configuration:
      - Node.js version: 20 (default - not found in project)
      - AWS region: us-east-1 (from serverless.yml)
      
    4. Ask for confirmation if critical values are missing (e.g., deploy command unclear)
  • role: system content: |-

    Serverless Deploy Actions Setup

    Overview

    This skill adds a GitHub Actions workflow that:

    • Uses OIDC (OpenID Connect) for AWS authentication (no long-lived credentials)
    • Supports multiple environments (dev/prod)
    • Allows manual deployment via workflow_dispatch
    • Injects environment-specific secrets at deploy time

    Prerequisites Check

    Before implementation, analyze the project:

    1. Detect Serverless configuration

      • Read serverless.yml or serverless.ts
      • Identify deploy command from package.json scripts/dependencies
    2. Extract environment variables

      • Parse provider.environment section (global variables)
      • Parse each functions.<name>.environment section (function-specific variables)
      • Collect unique variable names across all functions
      • Identify variables that need GitHub Secrets injection:
        • Variables with ${env:VAR_NAME} → Need to be injected from GitHub Secrets
        • Variables with ${ssm:...} or ${param:...} → May not need injection (AWS-side resolution)
        • Static string values → No injection needed
      • Only generate env: section in workflow if there are variables requiring injection
    3. Determine runtime requirements

      • Node.js version from package.json engines or .nvmrc
      • Python version from provider.runtime in serverless config
      • Check if Python setup step is needed
    4. Detect AWS region and stages

      • Region from provider.region
      • Stages from custom.stages or default to [dev, prod]
    5. Check default branch

      • Run git symbolic-ref refs/remotes/origin/HEAD or check common patterns

    Implementation Steps

    Step 1: Create Workflow File

    Create .github/workflows/deploy.yml based on this template (customize as needed):

    name: Deploy
    
    on:
      workflow_dispatch:
        inputs:
          environment:
            description: 'Environment to deploy'
            required: true
            type: choice
            options:
              - dev
              - prod
          branch:
            description: 'Branch to deploy'
            required: false
            default: 'main'
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        environment: ${{ inputs.environment }}
        steps:
          - uses: actions/checkout@v6
            with:
              ref: ${{ inputs.branch || 'main' }}
    
          - uses: actions/setup-node@v6
            with:
              node-version: '20'  # Adjust based on project
    
          # Add if Python runtime is used
          - uses: actions/setup-python@v6
            with:
              python-version: '3.12'  # Adjust based on Lambda runtime
    
          - name: Configure AWS credentials
            uses: aws-actions/configure-aws-credentials@v6.0.0
            with:
              role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
              aws-region: us-east-1  # Adjust based on project
    
          - name: Install dependencies
            run: npm install
    
          - name: Deploy
            env:
              # Only include if project uses ${env:VAR_NAME} in serverless.yml
              # Add project-specific secrets here based on detected ${env:} references
              # Example:
              # API_KEY: ${{ secrets.API_KEY }}
              # SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }}
            run: npx sls deploy --stage ${{ inputs.environment }}
            # Or for oss-serverless: npx osls deploy --stage ${{ inputs.environment }}

    Note: This is a template. All items marked with comments like # Adjust based on project must be customized for your specific project.

    Step 2: Customize for Project

    Adjust these elements:

    1. Default branch: Change master to main if needed
    2. Node.js version: Match project requirements
    3. Python setup: Remove if not using Python runtime
    4. AWS region: Set to project's target region
    5. Deploy command: Use sls or osls as appropriate
    6. Environment variables:
      • Only add env: section if project uses ${env:VAR_NAME} in serverless.yml
      • Extract variable names from ${env:XXX} patterns
      • Map each to VAR_NAME: ${{ secrets.VAR_NAME }}
      • If no ${env:} references exist, omit the entire env: section

    Step 3: Document Required Secrets

    (This section is now covered in Post-Setup Instructions above)

    Adaptation Guidelines

    For Different Serverless Variants

    • Serverless Framework: npx sls deploy --stage ${{ inputs.environment }}
    • oss-serverless: npx osls deploy --stage ${{ inputs.environment }}
    • SST: npx sst deploy --stage ${{ inputs.environment }}

    For Different Runtimes

    Node.js only:

    • Remove Python setup step

    Python only:

    • Keep Python setup
    • May still need Node.js for Serverless CLI

    Multiple runtimes:

    • Keep both setup steps

    For Additional Build Steps

    Add before deploy if needed:

    - name: Build
      run: npm run build
    
    - name: Run tests
      run: npm test

    Security Notes

    • Never commit AWS credentials or tokens
    • Use GitHub environment secrets for sensitive values
    • OIDC roles should follow least-privilege principle
    • Consider adding environment protection rules in GitHub

    Common Pitfalls

    1. Missing secrets: Deployment fails if secrets aren't configured in GitHub
    2. Wrong stage name: Ensure --stage matches serverless.yml configuration
    3. Insufficient IAM permissions: OIDC role needs CloudFormation, Lambda, S3, etc.
    4. Branch protection: Ensure workflow has permission to read protected branches

    Verification

    After implementation:

    1. Go to Actions tab in GitHub
    2. Select "Deploy" workflow
    3. Click "Run workflow"
    4. Choose environment and branch
    5. Verify deployment succeeds

    Example Output

    When user requests this skill:

    1. Analyze the project first - Read serverless.yml, package.json, etc.
    2. Report detected values - Show what you found:
      Detected configuration:
      - Node.js version: 20 (from package.json)
      - Python runtime: 3.12 (from serverless.yml provider.runtime)
      - AWS region: us-east-1 (from serverless.yml)
      - Deploy command: npx osls deploy (from package.json)
      - Default branch: main (from git)
      - Stages: dev, prod (from serverless.yml)
      - Environment variables requiring injection: API_KEY, SERVICE_URL, AUTH_TOKEN, ...
      
    3. Generate customized .github/workflows/deploy.yml with detected values
    4. Provide post-setup instructions (see below)

    Post-Setup Instructions

    After generating the workflow file, provide these instructions to the user:

    1. Create GitHub Environments and Secrets

    For each environment (dev, prod, etc.), run:

    # Create environment (if not exists)
    gh api repos/{owner}/{repo}/environments/{environment_name} -X PUT
    
    # Set secrets for the environment
    gh secret set AWS_ROLE_ARN --env {environment_name}
    # Paste the IAM Role ARN when prompted
    
    # Set each environment variable detected from serverless.yml
    gh secret set VARIABLE_NAME --env {environment_name}
    # Repeat for each variable

    Example for this project:

    # For prod environment
    gh api repos/{owner}/{repo}/environments/prod -X PUT
    gh secret set AWS_ROLE_ARN --env prod
    gh secret set API_KEY --env prod
    gh secret set SERVICE_URL --env prod
    gh secret set AUTH_TOKEN --env prod
    # ... (list all detected variables)

    2. Update IAM Role Trust Policy

    The OIDC IAM Role must trust this specific repository. Update the role's trust policy:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::{ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
            },
            "StringLike": {
              "token.actions.githubusercontent.com:sub": "repo:{owner}/{repo}:*"
            }
          }
        }
      ]
    }

    For this project, add:

    "token.actions.githubusercontent.com:sub": "repo:{owner}/{repo}:*"
    

    3. Verify IAM Role Permissions

    Ensure the IAM Role has sufficient permissions for Serverless deployment:

    • CloudFormation (CreateStack, UpdateStack, DeleteStack, DescribeStacks, etc.)
    • Lambda (CreateFunction, UpdateFunctionCode, etc.)
    • IAM (CreateRole, AttachRolePolicy - for Lambda execution roles)
    • S3 (CreateBucket, PutObject - for deployment artifacts)
    • API Gateway (if used)
    • CloudWatch Logs (if used)
    • Other services used by your functions

    4. (Optional) Add Environment Protection Rules

    Consider adding protection rules in GitHub:

    # Require approval for production deployments
    gh api repos/{owner}/{repo}/environments/prod -X PUT -f wait_timer=0 -f prevent_self_review=true

    5. Test the Workflow

    1. Go to Actions tab: https://github.com/{owner}/{repo}/actions
    2. Select "Deploy" workflow
    3. Click "Run workflow"
    4. Choose environment and branch
    5. Monitor the deployment

    6. (If First Time) Create OIDC Provider

    If the AWS account doesn't have GitHub OIDC provider yet:

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

    Or use AWS Console:

    • IAM → Identity providers → Add provider
    • Provider type: OpenID Connect
    • Provider URL: https://token.actions.githubusercontent.com
    • Audience: sts.amazonaws.com

    Reference: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

@hassaku63
Copy link
Author

実際のプロジェクトで Kiro CLI から実行してみた結果が以下。


プロジェクト分析が完了しました。GitHub Actionsワークフローを作成します。

検出された設定

  • Node.js version: 20 (デフォルト - package.jsonに指定なし)

  • Python runtime: 3.12 (serverless.ymlとasdfから検出)

  • AWS region: ap-northeast-1 (serverless.ymlから検出)

  • Deploy command: npx sls deploy (serverless使用)

  • Default branch: master (gitから検出)

  • Repository: my-org/my-repo

  • Stages: dev, prod (デフォルト)

  • 環境変数: serverless.ymlでSSM Parameter Storeを使用しているため、${env:}パターンは不使用 → workflow内での環境変数注入は不要
    I will run the following command: mkdir -p .github/workflows (using tool: shell)
    Purpose: .github/workflowsディレクトリを作成

  • Completed in 0.32s

I'll create the following file: /home/me/my-repo/.github/workflows/deploy.yml (using tool: write)
Purpose: GitHub Actions deployワークフローを作成

...(中略)...

✅ GitHub Actionsワークフローを作成しました: .github/workflows/deploy.yml

セットアップ手順

1. GitHub環境とシークレットを作成

各環境(dev, prod)に対して実行:

# 環境を作成
gh api repos/my-org/my-repo/environments/prod -X PUT

# AWS OIDC RoleのARNを設定
gh secret set AWS_ROLE_ARN --env prod
# プロンプトでIAM Role ARNを入力

devも同様に:

gh api repos/my-org/my-repo/environments/dev -X PUT
gh secret set AWS_ROLE_ARN --env dev

2. IAM RoleのTrust Policyを更新

OIDC IAM Roleの信頼ポリシーに以下を追加:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::{ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:*"
        }
      }
    }
  ]
}

3. IAM Roleの権限を確認

以下の権限が必要:

  • CloudFormation (CreateStack, UpdateStack, DescribeStacks等)
  • Lambda (CreateFunction, UpdateFunctionCode等)
  • IAM (Lambda実行ロール作成用)
  • S3 (デプロイアーティファクト用)
  • CloudWatch Logs
  • SNS (DeadLetterQueue用)
  • SSM (Parameter Store読み取り)

4. (初回のみ) GitHub OIDC Providerを作成

AWSアカウントにまだない場合:

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

5. ワークフローをテスト

  1. https://github.com/my-org/my-repo/actions にアクセス
  2. "Deploy" ワークフローを選択
  3. "Run workflow" をクリック
  4. 環境とブランチを選択して実行

注意: このプロジェクトはSSM Parameter Storeから認証情報を取得するため、ワークフロー内で環境変数を注入する必要はありません。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment