AWS SAM GraphQL Design

Production Showcase Source Code

The why, the how and the what

Use this repository when you want to automate creating a serverless Laravel environment.

It uses AWS SAM to create the AWS resources including:

  • Route 53 entries && SSL certificates
  • CloudFront
  • API Gateway for Lambda & Artisan
  • Assets S3 bucket for static files
  • Storage S3 bucket for internal files

It also makes use of GitHub actions for CI/CD automation.

Setup

  • Fork rdok/serverless-laravel template
  • Update the repository secrets with AWS credentials & others.
  • Update environment variables of artisan.yml & deploy.yml.
  • The IAM policies required for the CI/CD user are outside the scope of this post. However, you can reference the automated policies for the showcase here.
  • Deploy using Deploy Github action.
  • Run artisan commands using the Artisan GitHub action.

Pre-requisites

To automate the creation of the subdomain & it’s certificate.

An existing base domain & wild card certificate.

.github/workflows/deploy.yml view raw
BASE_DOMAIN_ROUTE_53_HOSTED_ZONE_ID: ${{ secrets.BASE_DOMAIN_ROUTE_53_HOSTED_ZONE_ID }}
BASE_DOMAIN_WILD_CARD_CERTIFICATE_ARN: ${{ secrets.BASE_DOMAIN_WILD_CARD_CERTIFICATE_ARN }}

Future additions

The following Laravel features will be supported in future posts:

  • Aurora serverless MySQL database
  • Broadcasting through SNS
  • Job dispatching through SQS
  • Scheduling through additional Lambda

Environment variables

Instruct Laravel how to load static assets & access storage bucket:

template.yaml view raw
Variables:
  APP_KEY: !Ref AppKey
  APP_STORAGE: /tmp
  AWS_PUBLIC_BUCKET: !Ref Assets
  MIX_ASSET_URL: !Join [ '', [ 'https://', !Ref DomainName, '/assets' ] ]
  ASSET_URL: !Join [ '', [ 'https://', !Ref DomainName, '/assets' ] ]
  LOG_CHANNEL: stderr
  FILESYSTEM_DRIVER: s3
  AWS_BUCKET: !Ref Storage

Domain Certificate

CloudFront only supports ACM certificates in the US East (N. Virginia) Region. As such, a separate stack is created in the us-east-1 region.

template-certificate.yml view raw
Certificate:
  Type: AWS::CertificateManager::Certificate
  Properties:
    ValidationMethod: DNS
    DomainValidationOptions:
      - DomainName: !Ref DomainName
        HostedZoneId: !Ref BaseDomainRoute53HostedZoneId
    DomainName: !Ref DomainName

Storage

Instruct Laravel to properly get AWS credentials by adding the AWS session token:

laravel/config/filesystems.php view raw
'token' => env('AWS_SESSION_TOKEN'),

CI/CD

CI/CD uses AWS SAM to build & deploy AWS resources:

.github/workflows/deploy.yml view raw
sam deploy \
  --region "eu-west-1" \
  --s3-bucket "${{ steps.env.outputs.cicd-bucket-laravel }}" \
  --s3-prefix "${NAME}" \
  --stack-name "${{ steps.env.outputs.stack-laravel-name }}" \
  --capabilities CAPABILITY_IAM \
  --no-fail-on-empty-changeset \
  --no-confirm-changeset \
  --parameter-overrides \
    CertificateARN="${CERTIFICATE_ARN}" \
    AppKey="${APP_KEY}" \
    DomainName="${{ steps.env.outputs.domain-name }}" \
    WildcardCertificateARN="${BASE_DOMAIN_WILD_CARD_CERTIFICATE_ARN}" \
    BaseDomainRoute53HostedZoneId="${BASE_DOMAIN_ROUTE_53_HOSTED_ZONE_ID}"