Subchapter 130.8
references/deployment.mdMarkdown9 KBView on GitHub
Prerequisites: Backend defined in
amplify/backend.tswithdefineBackend({ auth, data }).
Before deploying, verify:
npx ampx --version returns a valid versionaws sts get-caller-identity succeeds.gitignore includes node_modules/, .env*, amplify_outputs.json,
.amplify/amplify_outputs.json is gitignored — it is generated at build
time, NOT committed to source control:
npx ampx sandbox generates it automaticallynpx ampx pipeline-deploy generates it during the build phasenpx ampx generate outputs --app-id <backend-app-id> to generate itamplify/backend.ts + defineBackend())Deploy a personal development environment:
AWS_REGION=us-east-1 npx ampx sandbox --onceUse the --once flag in agent and CI environments — without
it, the command starts a file watcher that never exits. If prompted to
bootstrap, run npx ampx sandbox --once again after bootstrapping
completes.
Verify amplify_outputs.json was generated in the project root.
REPO="github.com/<user>/<repo>"
APP_ID=$(aws amplify create-app \
--name my-app \
--repository "$REPO" \
--access-token "$(gh auth token)" \
--query 'app.appId' --output text)Use github.com/user/repo format — not https://.
Create a dedicated role for Amplify backend deployments:
ROLE_NAME="AmplifyBackendRole-${APP_ID}"
# 1. Create the role with Amplify trust policy
aws iam create-role --role-name "$ROLE_NAME" --assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "amplify.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# 2. Attach the backend deploy policy
aws iam attach-role-policy --role-name "$ROLE_NAME" \
--policy-arn arn:aws:iam::aws:policy/service-role/AmplifyBackendDeployFullAccess
# 3. Attach the role to the app
ROLE_ARN=$(aws iam get-role --role-name "$ROLE_NAME" --query 'Role.Arn' --output text)
aws amplify update-app --app-id "$APP_ID" --iam-service-role-arn "$ROLE_ARN"All three steps are required — missing the role causes
AccessDeniedException during deployment.
aws amplify create-branch --app-id "$APP_ID" --branch-name mainCreate amplify.yml in the project root. Set baseDirectory per
framework:
| Framework | baseDirectory |
|---|---|
| Vite (React/Vue) | dist |
| CRA | build |
| Next.js (export) | out |
| Next.js (SSR) | .next |
| Angular | dist/<project-name>/browser |
Wrong baseDirectory = blank page in production (silent failure).
Always match the framework table above.
version: 1
backend:
phases:
build:
commands:
- npm ci --cache .npm --prefer-offline
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
frontend:
phases:
build:
commands:
- npm ci
- npm run build
artifacts:
baseDirectory: dist # Change per framework (see table above)
files:
- '**/*'
cache:
paths:
- .npm/**/*
- node_modules/**/*Note:
$AWS_BRANCHand$AWS_APP_IDare automatically set by Amplify Hosting. For custom CI/CD pipelines (GitHub Actions, CodePipeline), set these manually or use your pipeline’s equivalent variables.
For monorepos, set appRoot in amplify.yml to the subdirectory
containing the Amplify app:
appRoot: packages/webWARNING: appRoot must have NO leading slash.
appRoot: packages/web (correct) vs appRoot: /packages/web (wrong)
Monorepo rules:
npx ampx pipeline-deploy; other apps use
npx ampx generate outputs --app-id <backend-app-id> to get their
amplify_outputs.json.npm ci at the repo root, NOT inside appRoot.aws amplify start-job --app-id "$APP_ID" --branch-name main --job-type RELEASESandbox: Set secrets via CLI:
echo -n "<value>" | npx ampx sandbox secret set MY_API_KEYSecurity: Avoid passing secret values as CLI arguments or via
echo— these appear in shell history and/proc. Instead, usenpx ampx sandbox secret set MY_SECRETwhich prompts for input interactively, or pipe from a secure source:aws ssm get-parameter --name /path/to/secret --with-decryption --query Parameter.Value --output text | npx ampx sandbox secret set MY_SECRET --from-stdin
Pipe the value via stdin — without the pipe, the command prompts interactively.
Important: Use
echo -n(no trailing newline) when piping values tosecret set. (The documented approach uses an interactive prompt; piping withecho -nis a practical alternative for scripts.)
This stores the secret for your personal sandbox environment.
Branch environments (production): Secrets are managed through the Amplify console (App settings → Environment variables → Secrets), NOT via CLI. The ampx sandbox secret command only works for local sandbox environments.
Alternatively, use the AWS CLI for non-secret environment variables:
aws amplify update-app --app-id "$APP_ID" \
--environment-variables MY_API_KEY=<value>Important:
--environment-variablesstores values as plain text. For sensitive values (API keys, tokens), usenpx ampx sandbox secret set(sandbox) ornpx ampx secret set --branch(production) which stores in SSM SecureString.Note: Under the hood, Amplify Gen2
secret()references are backed by AWS Systems Manager Parameter Store (SecureString parameters). Review access policies on the/amplify/parameter path in your account to ensure only authorized roles can read production secrets.
Reference secrets in functions using secret() — see
functions-and-api.md for the pattern.
Use branch-based environments — each Git branch deploys independently:
# Create a staging branch
git checkout -b staging
git push origin staging
aws amplify create-branch --app-id "$APP_ID" --branch-name staging
aws amplify start-job --app-id "$APP_ID" --branch-name staging --job-type RELEASEEach branch gets isolated backend resources (Cognito pool, AppSync API, DynamoDB tables). Set branch-specific secrets separately.
Associate a custom domain with the Amplify app:
aws amplify create-domain-association \
--app-id "$APP_ID" \
--domain-name example.com \
--sub-domain-settings '[
{"prefix": "", "branchName": "main"},
{"prefix": "staging", "branchName": "staging"}
]'Amplify auto-provisions an SSL certificate. Add the provided CNAME records to your DNS for verification. Check status:
aws amplify get-domain-association --app-id "$APP_ID" --domain-name example.comAmplify Hosting provides framework-aware builds with SSR support for
Next.js. The build pipeline auto-detects the framework from
package.json. For SSR apps, Amplify deploys a Lambda@Edge or
CloudFront function — no manual CloudFront configuration needed.
Production URL format: https://<branch>.<app-id>.amplifyapp.com
After deployment, check job status with aws amplify list-jobs --app-id "$APP_ID" --branch-name main --query 'jobSummaries[0].status' and verify amplify_outputs.json endpoints match expected values.
Rollback: Revert via Git and redeploy:
git revert HEAD --no-edit
git push origin main
# Amplify auto-triggers a new build from the pushFor CI/CD, manually trigger: aws amplify start-job --app-id "$APP_ID" --branch-name main --job-type RELEASE.
Despite the error name, this is a missing region, not a credential issue:
export AWS_REGION=us-east-1Each sandbox creates an AppSync API. Frequent sandbox creation/deletion can leave orphaned APIs. If deployment fails with “LimitExceededException”: