Skip to content

Commit ca4ad82

Browse files
committed
[infra] update
1 parent 8734493 commit ca4ad82

19 files changed

Lines changed: 946 additions & 142 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Invalidate CloudFront Cache
3+
4+
on:
5+
workflow_dispatch:
6+
7+
jobs:
8+
invalidate:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
id-token: write
12+
contents: read
13+
steps:
14+
- name: Invalidate CloudFront Cache
15+
uses: Mad-Pixels/github-workflows/actions/cloudfront-invalidation@v1
16+
with:
17+
aws_region: us-east-1
18+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC
19+
distribution_id: E1234567890ABC
20+
paths: "/* /index.html /assets/*"
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# ⚡️ CloudFront Invalidation
2+
Create a CloudFront invalidation to purge cached content after deploys. Supports OIDC or static AWS credentials, multiple paths (space‑separated), optional custom caller reference, and rich summary output.
3+
4+
## ✅ Features
5+
- Create invalidations for one or many paths (supports wildcards)
6+
- Auto‑generated caller reference (or provide your own)
7+
- OIDC role assumption or static AWS credentials
8+
- Input validation (distribution ID format, path count, path prefixes)
9+
- Summary output with invalidation ID, status, and paths
10+
11+
## 📖 Related Documentation
12+
- CloudFront Invalidation API: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html
13+
- AWS CLI cloudfront create‑invalidation: https://docs.aws.amazon.com/cli/latest/reference/cloudfront/create-invalidation.html
14+
- GitHub OIDC for AWS: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
15+
16+
## 🚀 Prerequisites
17+
Your workflow must:
18+
- Run on `ubuntu-latest` with AWS CLI and `jq` available
19+
- Provide AWS credentials (static keys) or OIDC role assumption
20+
- Have a valid CloudFront distribution ID
21+
22+
## 🔧 Quick Example
23+
```yaml
24+
name: Invalidate CloudFront Cache
25+
26+
on:
27+
workflow_dispatch:
28+
29+
jobs:
30+
invalidate:
31+
runs-on: ubuntu-latest
32+
permissions:
33+
id-token: write
34+
contents: read
35+
steps:
36+
- name: Create invalidation via OIDC
37+
uses: Mad-Pixels/github-workflows/actions/cloudfront-invalidation@v1
38+
with:
39+
aws_region: us-east-1
40+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC
41+
distribution_id: E1234567890ABC
42+
paths: "/* /index.html /assets/*"
43+
```
44+
45+
## 📥 Inputs
46+
| **Name** | **Required** | **Description** | **Default** |
47+
|--------------------|--------------|---------------------------------------------------------------------------------------------------------|-------------|
48+
| `aws_access_key` | ❌ No | AWS access key ID (optional if using OIDC) | - |
49+
| `aws_secret_key` | ❌ No | AWS secret access key (optional if using OIDC) | - |
50+
| `aws_region` | ✅ Yes | AWS region (used by the CLI) | - |
51+
| `role_to_assume` | ❌ No | AWS IAM role ARN to assume (OIDC) | - |
52+
| `distribution_id` | ✅ Yes | CloudFront distribution ID (format: E + 13 alphanumeric chars, e.g. `E1234567890ABC`) | - |
53+
| `paths` | ❌ No | Space‑separated list of paths to invalidate (must start with `/`; max 1000 entries; wildcards allowed) | `/*` |
54+
| `caller_reference` | ❌ No | Custom caller reference for idempotency (auto‑generated if not provided) | - |
55+
56+
## 📤 Outputs
57+
| **Name** | **Description** |
58+
|-------------------|-----------------------------------|
59+
| `invalidation_id` | ID of the created invalidation |
60+
| `status` | Status returned by CloudFront |
61+
62+
## 📋 Examples
63+
[View example →](./examples/base.yml)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Restart Lambda
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
lambda-restart:
8+
runs-on: ubuntu-latest
9+
permissions:
10+
id-token: write
11+
contents: read
12+
steps:
13+
- name: Restart Lambda with specific image
14+
uses: Mad-Pixels/github-workflows/actions/lambda-restart@v1
15+
with:
16+
aws_region: us-east-1
17+
aws_account_id: 123456789012
18+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC
19+
function_name: my-service-prod
20+
repository: my-service
21+
image_tag: latest
22+
wait_for_update: 'true'
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# 🚀 Lambda Restart
2+
Update an AWS Lambda function to a new container image (ECR). Supports direct `image_uri` or `repository` + `image_tag`, OIDC or static AWS credentials, and optional wait for completion.
3+
4+
## ✅ Features
5+
- Update Lambda to a specific container image (ECR)
6+
- Accept either full `image_uri` or `repository` + `image_tag`
7+
- AWS auth via OIDC role assumption or static credentials
8+
- Validates Lambda existence before update
9+
- Optional wait until function update completes
10+
- Summary output with key details
11+
12+
## 📖 Related Documentation
13+
- AWS Lambda container images: https://docs.aws.amazon.com/lambda/latest/dg/images-create.html
14+
- Update function code (CLI): https://docs.aws.amazon.com/cli/latest/reference/lambda/update-function-code.html
15+
- ECR repositories and images: https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html
16+
- GitHub OIDC for AWS: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
17+
18+
## 🚀 Prerequisites
19+
Your workflow must:
20+
- Run on `ubuntu-latest` with AWS CLI and `jq` available
21+
- Provide AWS credentials or an assumable IAM role
22+
- Ensure the target ECR image exists and the Lambda function is configured for images
23+
24+
## 🔧 Quick Example
25+
```yaml
26+
name: Restart Lambda
27+
28+
on:
29+
workflow_dispatch:
30+
31+
jobs:
32+
update:
33+
runs-on: ubuntu-latest
34+
permissions:
35+
id-token: write
36+
contents: read
37+
steps:
38+
- name: Update Lambda to specific image URI (OIDC)
39+
uses: Mad-Pixels/github-workflows/actions/lambda-restart@v1
40+
with:
41+
aws_region: us-east-1
42+
aws_account_id: 123456789012
43+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC
44+
function_name: my-service-prod
45+
image_uri: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-service@sha256:deadbeef
46+
wait_for_update: 'true'
47+
48+
# Alternative: use repository + tag instead of full image_uri
49+
# - name: Update Lambda with repository/tag
50+
# uses: Mad-Pixels/github-workflows/actions/lambda-restart@v1
51+
# with:
52+
# aws_region: us-east-1
53+
# aws_account_id: 123456789012
54+
# role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC
55+
# function_name: my-service-prod
56+
# repository: my-service
57+
# image_tag: latest
58+
# wait_for_update: 'true'
59+
```
60+
61+
## 📥 Inputs
62+
| **Name** | **Required** | **Description** | **Default** |
63+
|--------------------------|--------------|--------------------------------------------------------------------------------------|-------------|
64+
| `aws_access_key_id` | ❌ No | AWS access key ID (optional if using OIDC) | - |
65+
| `aws_secret_access_key` | ❌ No | AWS secret access key (optional if using OIDC) | - |
66+
| `aws_region` | ✅ Yes | AWS region | - |
67+
| `aws_account_id` | ✅ Yes | AWS account ID (12 digits) | - |
68+
| `role_to_assume` | ❌ No | AWS IAM role ARN to assume (for OIDC authentication) | - |
69+
| `function_name` | ✅ Yes | Full Lambda function name | - |
70+
| `image_uri` | ❌ No | Full ECR image URI (overrides `repository`/`image_tag` when provided) | - |
71+
| `repository` | ❌ No | ECR repository name (used if `image_uri` not provided) | - |
72+
| `image_tag` | ❌ No | ECR image tag (used with `repository`) | `latest` |
73+
| `wait_for_update` | ❌ No | Wait for function update to complete (`true`/`false`) | `true` |
74+
75+
## 📤 Outputs
76+
| **Name** | **Description** |
77+
|------------------|-----------------------------------------|
78+
| `function_arn` | Lambda function ARN |
79+
| `last_modified` | Function last modified timestamp |
80+
| `code_sha256` | Lambda code SHA256 |
81+
82+
## 📋 Examples
83+
[View example →](./examples/base.yml)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Sync Directory to S3
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
jobs:
9+
sync-to-s3:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
id-token: write # required if using role_to_assume (OIDC)
13+
contents: read
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
# Example: build static site into ./dist (optional)
19+
# - name: Build site
20+
# run: |
21+
# npm ci
22+
# npm run build
23+
24+
- name: Sync ./dist to S3 via OIDC
25+
uses: Mad-Pixels/github-workflows/actions/s3-sync@v1
26+
with:
27+
aws_region: us-east-1
28+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC-Deploy
29+
bucket_name: my-static-site-bucket
30+
source_dir: dist
31+
bucket_prefix: web
32+
delete_removed: 'true'
33+
exclude_patterns: ".git/* .github/* .DS_Store"
34+
cache_control: "public, max-age=31536000, immutable"
35+
36+
# Example for static credentials instead of OIDC:
37+
# - name: Sync using static keys
38+
# uses: Mad-Pixels/github-workflows/actions/s3-sync@v1
39+
# with:
40+
# aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
41+
# aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
42+
# aws_region: us-east-1
43+
# bucket_name: my-static-site-bucket
44+
# source_dir: dist
45+
# bucket_prefix: web
46+
# delete_removed: 'true'

actions/aws-s3-sync/readme.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# ☁️ Sync Directory to S3
2+
Upload a local directory to an Amazon S3 bucket with optional key prefix, deletion of removed files, exclude patterns, and cache headers.
3+
4+
## ✅ Features
5+
- Sync any local directory to S3 with optional prefix subpath
6+
- Optional deletion of objects missing in source (keep destination clean)
7+
- Exclude files via space‑separated patterns (e.g., ".git/* *.tmp")
8+
- Optional Cache-Control header applied to uploaded objects
9+
- Works with AWS OIDC role assumption or static credentials
10+
- Summary with counts (uploaded/deleted) and total size
11+
12+
## 📖 Related Documentation
13+
- AWS CLI S3 sync: https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html
14+
- S3 bucket naming rules: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
15+
- GitHub OIDC for AWS: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
16+
17+
## 🚀 Prerequisites
18+
Your workflow must:
19+
- Run on `ubuntu-latest` with AWS CLI available
20+
- Provide AWS credentials (static keys) or OIDC role assumption
21+
- Ensure the target S3 bucket already exists and is accessible
22+
23+
## 🔧 Quick Example
24+
name: Sync Web Assets to S3
25+
26+
on:
27+
push:
28+
branches: [main]
29+
30+
jobs:
31+
s3-sync:
32+
runs-on: ubuntu-latest
33+
permissions:
34+
id-token: write # required only if using role_to_assume (OIDC)
35+
contents: read
36+
steps:
37+
- name: Sync dist/ to S3 (OIDC)
38+
uses: Mad-Pixels/github-workflows/actions/s3-sync@v1
39+
with:
40+
aws_region: us-east-1
41+
role_to_assume: arn:aws:iam::123456789012:role/GHA-OIDC-Deploy
42+
bucket_name: my-static-site-bucket
43+
source_dir: dist
44+
bucket_prefix: web
45+
delete_removed: 'true'
46+
exclude_patterns: ".git/* .github/* .DS_Store"
47+
cache_control: "public, max-age=31536000, immutable"
48+
49+
## 📥 Inputs
50+
| **Name** | **Required** | **Description** | **Default** |
51+
|--------------------|--------------|--------------------------------------------------------------------------------------------------|--------------------------------------------|
52+
| `aws_access_key` | ❌ No | AWS access key ID (optional if using OIDC) | - |
53+
| `aws_secret_key` | ❌ No | AWS secret access key (optional if using OIDC) | - |
54+
| `role_to_assume` | ❌ No | AWS IAM role ARN to assume (OIDC) | - |
55+
| `aws_region` | ✅ Yes | AWS region | - |
56+
| `bucket_name` | ✅ Yes | Target S3 bucket name | - |
57+
| `source_dir` | ✅ Yes | Local path to sync | - |
58+
| `bucket_prefix` | ❌ No | Optional subpath prefix inside the bucket (trimmed of leading/trailing slashes) | `""` |
59+
| `delete_removed` | ❌ No | Remove objects in S3 that are not present in `source_dir` (`true`/`false`) | `true` |
60+
| `exclude_patterns` | ❌ No | Space‑separated exclude patterns passed to `aws s3 sync --exclude` | `.git/* .github/* .gitignore .gitattributes` |
61+
| `cache_control` | ❌ No | Value for `Cache-Control` header applied to uploads | - |
62+
63+
## 📤 Outputs
64+
| **Name** | **Description** |
65+
|-------------------|------------------------------------------|
66+
| `files_uploaded` | Number of uploaded files |
67+
| `files_deleted` | Number of deleted files |
68+
| `total_size` | Total size in bytes of local files synced |
69+
| `s3_url` | Final S3 sync URL (e.g., `s3://bucket/prefix`) |
70+
71+
## 📋 Examples
72+
[View example →](./examples/base.yml)

actions/aws-terraform-runner/action.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: 'Terraform Runner'
3-
description: 'Invoke terraform actions'
3+
description: 'Invoke terraform actions with S3 backend and optional AWS OIDC authentication'
44

55
inputs:
66
aws_access_key_id:
@@ -54,7 +54,7 @@ runs:
5454
fetch-depth: 1
5555

5656
- name: Configure AWS authentication
57-
uses: Mad-Pixels/github-workflows/internal/aws-auth@main
57+
uses: Mad-Pixels/github-workflows/internal/aws-auth@v1
5858
with:
5959
aws_secret_key: ${{ inputs.aws_secret_access_key }}
6060
aws_access_key: ${{ inputs.aws_access_key_id }}
@@ -107,24 +107,34 @@ runs:
107107
run: terraform validate
108108

109109
- name: Run Terraform Command
110+
id: tf-run
110111
shell: bash
111112
working-directory: ${{ inputs.tf_dir }}
112113
run: |
113114
case "${{ inputs.tf_command }}" in
114115
plan)
115-
terraform plan -input=false ${{ inputs.tf_vars }}
116+
terraform plan -input=false -lock-timeout=300s -out=tfplan ${{ inputs.tf_vars }}
116117
;;
117118
apply)
118-
terraform apply -input=false -auto-approve ${{ inputs.tf_vars }}
119+
terraform apply -input=false -auto-approve -lock-timeout=300s ${{ inputs.tf_vars }}
119120
;;
120121
destroy)
121-
terraform destroy -input=false -auto-approve ${{ inputs.tf_vars }}
122+
terraform destroy -input=false -auto-approve -lock-timeout=300s ${{ inputs.tf_vars }}
122123
;;
123124
*)
124125
echo "❌ Unknown tf_command: ${{ inputs.tf_command }}" >&2
125126
exit 1
126127
;;
127128
esac
129+
130+
- name: Upload plan artifact
131+
if: inputs.tf_command == 'plan'
132+
uses: actions/upload-artifact@v4
133+
with:
134+
name: terraform-plan
135+
path: ${{ inputs.tf_dir }}/tfplan
136+
if-no-files-found: error
137+
128138
- name: Terraform Summary
129139
shell: bash
130140
run: |
@@ -135,3 +145,9 @@ runs:
135145
echo "- Directory: \`${{ inputs.tf_dir }}\`" >> "$GITHUB_STEP_SUMMARY"
136146
echo "- Workspace: \`$WORKSPACE\`" >> "$GITHUB_STEP_SUMMARY"
137147
echo "- Terraform version: \`${{ inputs.tf_version }}\`" >> "$GITHUB_STEP_SUMMARY"
148+
149+
if [ "${{ inputs.tf_command }}" = "plan" ]; then
150+
echo "" >> "$GITHUB_STEP_SUMMARY"
151+
echo "### 📄 Plan Diff" >> "$GITHUB_STEP_SUMMARY"
152+
terraform show -no-color ${{ inputs.tf_dir }}/tfplan >> "$GITHUB_STEP_SUMMARY"
153+
fi

0 commit comments

Comments
 (0)