/website-cicd
Sets up GitHub Actions CI/CD workflow for automatic deployment to AWS on push to main. Uses GitHub OIDC for keyless AWS authentication.
$ npx -y skills add GRCEngClub/claude-grc-engineering --skill website-cicd --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/website-cicd
Context preview
The summary Claude sees to decide when to auto-load this skill.
Sets up GitHub Actions CI/CD workflow for automatic deployment to AWS on push to main. Uses GitHub OIDC for keyless AWS authentication.
SKILL.md
website-cicd.SKILL.mdname: website-cicd
description: Sets up GitHub Actions CI/CD workflow for automatic deployment to AWS on push to main. Uses GitHub OIDC for keyless AWS authentication.
allowed-tools: Bash, Read, Write, Edit, Glob
Website CI/CD Skill
You are running the `/grc-portfolio:cicd` skill. Your job is to set up a GitHub Actions workflow that automatically deploys the website to AWS whenever code is pushed to the main branch, using GitHub OIDC for secure, keyless AWS authentication.
Step 1: Locate and Validate Config
Find `site-config.json`:
- Check `$ARGUMENTS` for a project directory path
- Check the current working directory
- Ask the user if not found
Read it and validate:
- `status.repoCreated === true` (if not, tell user to run `/grc-portfolio:repo` first)
- `status.infraDeployed === true` (if not, tell user to run `/grc-portfolio:infra` first)
Step 2: Set Up GitHub OIDC IAM Role
2a: Ensure OIDC Provider Exists
Check if the GitHub OIDC identity provider already exists in the AWS account:
aws iam list-open-id-connect-providers --profile <aws.profile>
Look for `token.actions.githubusercontent.com`. If it doesn't exist, create it:
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 \
--profile <aws.profile>
2b: Create IAM Role with Trust Policy
Create a trust policy that allows only this specific GitHub repo's `main` branch (and `workflow_dispatch` runs against `main`) to assume the role. The `:*` wildcard is too broad — it would let any PR, tag, or environment in the repo assume this 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",
"token.actions.githubusercontent.com:sub": "repo:<github.owner>/<github.repoName>:ref:refs/heads/main"
}
}
}
]
}If the project deploys from a different branch, replace `main` accordingly. For preview deploys from PRs, add a second statement scoped to `repo:<owner>/<repo>:pull_request` and a separate, narrower IAM policy.
Create the role:
aws iam create-role \
--role-name <projectName>-github-deploy \
--assume-role-policy-document file:///tmp/<projectName>-trust-policy.json \
--description "GitHub Actions OIDC role for <projectName> website deployment" \
--profile <aws.profile>
2c: Attach Least-Privilege Deploy Policy
Create an inline policy scoped to only the S3 bucket and CloudFront distribution for this project:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Deploy",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<aws.bucketName>",
"arn:aws:s3:::<aws.bucketName>/*"
]
},
{
"Sid": "CloudFrontInvalidate",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::<account-id>:distribution/<aws.distributionId>"
}
]
}Attach it:
aws iam put-role-policy \
--role-name <projectName>-github-deploy \
--policy-name <projectName>-deploy-access \
--policy-document file:///tmp/<projectName>-deploy-policy.json \
--profile <aws.profile>
Step 3: Create Workflow File
Create `.github/workflows/deploy.yml` in the project directory.
The workflow uses OIDC — no static AWS keys needed. Bucket name, distribution ID, and role ARN are stored as workflow env vars (not secrets, since they're not sensitive):
name: Deploy to AWS
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
env:
AWS_BUCKET_NAME: <aws.bucketName>
AWS_DISTRIBUTION_ID: <aws.distributionId>
AWS_REGION: us-east-1
AWS_ROLE_ARN: arn:aws:iam::<account-id>:role/<projectName>-github-deploy
jobs:
deploy:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
env:
NODE_ENV: production
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to S3
run: |
aws s3 sync dist/ s3://${{ env.AWS_BUCKET_NAME }} \
--delete \
--cache-control "public,max-age=31536000,immutable" \
--exclude "index.html" \
--exclude "*.html"
aws s3 sync dist/ s3://${{ env.AWS_BUCKET_NAME }} \
--cache-control "public,max-age=0,must-revalidate" \
--exclude "*" \
--include "*.html"
- name: Invalidate CloudFront
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ env.AWS_DISTRIBUTION_ID }} \
--paths "/*"If `features.contactForm` is true, add to the Build step's env:
env:
NODE_ENV: production
VITE_CONTACT_API_ENDPOINT: <aws.contactApiEndpoint>Step 4: Commit and Push
cd <projectDir>
git add .github/workflows/deploy.yml
git commit -m "Add GitHub Actions deploy workflow (OIDC auth)"
git push
Step 5: Verify Workflow
Check that the workflow was triggered:
gh
Read more
name: website-cicd description: Sets up GitHub Actions CI/CD workflow for automatic deployment to AWS on push to main. Uses GitHub OIDC for keyless AWS authentication. allowed-tools: Bash, Read, Write, Edit, Glob
Website CI/CD Skill
You are running the `/grc-portfolio:cicd` skill. Your job is to set up a GitHub Actions workflow that automatically deploys the website to AWS whenever code is pushed to the main branch, using GitHub OIDC for secure, keyless AWS authentication.
Step 1: Locate and Validate Config
Find `site-config.json`:
- Check `$ARGUMENTS` for a project directory path
- Check the current working directory
- Ask the user if not found
Read it and validate:
- `status.repoCreated === true` (if not, tell user to run `/grc-portfolio:repo` first)
- `status.infraDeployed === true` (if not, tell user to run `/grc-portfolio:infra` first)
Step 2: Set Up GitHub OIDC IAM Role
2a: Ensure OIDC Provider Exists
Check if the GitHub OIDC identity provider already exists in the AWS account:
aws iam list-open-id-connect-providers --profile <aws.profile>
Look for `token.actions.githubusercontent.com`. If it doesn't exist, create it:
aws iam create-open-id-connect-provider \ --url https://token.actions.githubusercontent.com \ --client-id-list sts.amazonaws.com \ --thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1 \ --profile <aws.profile>
2b: Create IAM Role with Trust Policy
Create a trust policy that allows only this specific GitHub repo's `main` branch (and `workflow_dispatch` runs against `main`) to assume the role. The `:*` wildcard is too broad — it would let any PR, tag, or environment in the repo assume this 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",
"token.actions.githubusercontent.com:sub": "repo:<github.owner>/<github.repoName>:ref:refs/heads/main"
}
}
}
]
}If the project deploys from a different branch, replace `main` accordingly. For preview deploys from PRs, add a second statement scoped to `repo:<owner>/<repo>:pull_request` and a separate, narrower IAM policy.
Create the role:
aws iam create-role \ --role-name <projectName>-github-deploy \ --assume-role-policy-document file:///tmp/<projectName>-trust-policy.json \ --description "GitHub Actions OIDC role for <projectName> website deployment" \ --profile <aws.profile>
2c: Attach Least-Privilege Deploy Policy
Create an inline policy scoped to only the S3 bucket and CloudFront distribution for this project:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3Deploy",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::<aws.bucketName>",
"arn:aws:s3:::<aws.bucketName>/*"
]
},
{
"Sid": "CloudFrontInvalidate",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::<account-id>:distribution/<aws.distributionId>"
}
]
}Attach it:
aws iam put-role-policy \ --role-name <projectName>-github-deploy \ --policy-name <projectName>-deploy-access \ --policy-document file:///tmp/<projectName>-deploy-policy.json \ --profile <aws.profile>
Step 3: Create Workflow File
Create `.github/workflows/deploy.yml` in the project directory.
The workflow uses OIDC — no static AWS keys needed. Bucket name, distribution ID, and role ARN are stored as workflow env vars (not secrets, since they're not sensitive):
name: Deploy to AWS
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
env:
AWS_BUCKET_NAME: <aws.bucketName>
AWS_DISTRIBUTION_ID: <aws.distributionId>
AWS_REGION: us-east-1
AWS_ROLE_ARN: arn:aws:iam::<account-id>:role/<projectName>-github-deploy
jobs:
deploy:
name: Build and Deploy
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
env:
NODE_ENV: production
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to S3
run: |
aws s3 sync dist/ s3://${{ env.AWS_BUCKET_NAME }} \
--delete \
--cache-control "public,max-age=31536000,immutable" \
--exclude "index.html" \
--exclude "*.html"
aws s3 sync dist/ s3://${{ env.AWS_BUCKET_NAME }} \
--cache-control "public,max-age=0,must-revalidate" \
--exclude "*" \
--include "*.html"
- name: Invalidate CloudFront
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ env.AWS_DISTRIBUTION_ID }} \
--paths "/*"If `features.contactForm` is true, add to the Build step's env:
env:
NODE_ENV: production
VITE_CONTACT_API_ENDPOINT: <aws.contactApiEndpoint>Step 4: Commit and Push
cd <projectDir> git add .github/workflows/deploy.yml git commit -m "Add GitHub Actions deploy workflow (OIDC auth)" git push
Step 5: Verify Workflow
Check that the workflow was triggered:
gh
Showing the first part of this file.
Open-source GRC Engineering resource for Claude. claude-grc-engineering turns technical evidence from cloud, SaaS, code, and security tools into framework-aligned findings, gap reports, remediation guidance, evidence packages, and OSCAL workflows.
Repo: GRCEngClub/claude-grc-engineering
Other skills on trust-center.
- /academic-research-companion
Guide a research project through the full academic lifecycle — from raw idea to concrete research question, literature grounding, methodology, writing, feedback, and publication. Use this skill whenever the user shares a research idea, asks to "flesh out" a topic, wants sources
Open skill - /aws-inspector-expert
Expertise in evaluating AWS accounts for compliance — what checks are meaningful, which SCF controls they map to, and how to interpret aws CLI output.
Open skill - /azure-inspector-expert
Expertise in evaluating Azure subscription findings from azure-inspector and mapping them to SCF controls.
Open skill - /crowdstrike-inspector-expert
Interpret CrowdStrike Falcon findings for sensor coverage, policy visibility, and host group scoping.
Open skill - /datadog-inspector-expert
Interpret datadog-inspector findings and translate Datadog monitoring, audit, log-retention, SSO, and RBAC results into GRC evidence and remediation.
Open skill - /drata-inspector-expert
Interpret drata-inspector findings generated from drata-cli workflows and turn Drata control, monitor, evidence, personnel, and integration posture into GRC action.
Open skill

