Quickstart
Vendor Webform Relay into your project, deploy it to AWS, and send your first form submission — in under ten minutes.
This is the condensed path. Getting Started is the same flow with every step explained, plus CI/CD, rollback, teardown, and the flow’s known gaps. Working on webform-relay rather than with it? See the Contribution Guide.
Prerequisites
- Docker installed and running
- Task 3+ installed
vinstalled- An AWS account with an admin-level identity, used once to create the least-privilege deploy user
No host AWS CLI, SAM CLI, or ~/.aws/credentials needed — everything runs in
Docker.
1. Vendor it
From your own project’s repo root:
v add https://gitlab.com/frob/webform-relay <tag>2. Wire it into your Taskfile
In your project’s own Taskfile.yml:
version: '3'
dotenv: ['.env', '.env.project']
includes:
relay:
taskfile: ./vendor/gitlab.com/frob/webform-relay/taskfiles/deploy.yml
dir: ./vendor/gitlab.com/frob/webform-relay3. Copy the config templates out of the vendored directory
cp vendor/gitlab.com/frob/webform-relay/.env.example .env
cp vendor/gitlab.com/frob/webform-relay/.env.project .env.project.env holds the AWS keys and FORM_TOKEN_SECRET and is gitignored;
.env.project holds region, bucket names, and stack parameters and is
committed. Fill in the ADMIN_* keys in .env, and CONFIG_BUCKET /
SAM_ARTIFACTS_BUCKET in .env.project.
4. Bootstrap AWS
task relay:tools:build # SAM/AWS CLI tools image (once)
task relay:aws:bootstrap # deploy IAM user + both S3 bucketsCopy the printed AccessKeyId / SecretAccessKey into AWS_ACCESS_KEY_ID /
AWS_SECRET_ACCESS_KEY in .env.
5. Write a config file
Save this as webform.yaml at your project root:
cache_ttl: 30s
forms:
contact:
fields:
- name: name
required: true
- name: email
required: true
type: email
- name: message
required: true
type: textarea
outputs:
- type: email
to: you@example.com
subject: "New contact submission"
mapping:
from_name: name
from_email: email
body: messageUpload it to the config bucket:
task relay:upload:config CONFIG=webform.yaml6. Deploy
Fully non-interactive — every parameter comes from .env/.env.project, and no
samconfig.toml is created or needed:
task relay:build:container
task relay:deploy:appRe-run the same commands for every subsequent deploy. If you only changed the
config YAML, re-run task relay:upload:config CONFIG=webform.yaml and skip the
deploy — changes take effect within CACHE_TTL.
7. Get the form HTML
The deployed stack renders it for you:
curl https://<api-id>.execute-api.<region>.amazonaws.com/api/v1/form/contact(The webform-relay form html CLI does the same offline, but it lives in
cmd/cli and is built by taskfiles/dev.yml, which is not part of the vendored
deploy taskfile. Build it straight from the vendored source if you want it:
docker run --rm -v $PWD/vendor/gitlab.com/frob/webform-relay:/app -w /app golang:1.23 go run ./cmd/cli form html contact.)
Paste the output into your HTML page, or point an existing <form> at the endpoint:
<form method="post"
action="https://<api-id>.execute-api.<region>.amazonaws.com/api/v1/submit/contact"
enctype="application/x-www-form-urlencoded">
<input name="name" type="text" required>
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>8. Test the endpoint
curl -X POST \
https://<api-id>.execute-api.<region>.amazonaws.com/api/v1/submit/contact \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=Jane+Doe&email=jane@example.com&message=Hello"Expected response:
{"message": "ok"}