In this step-by-step guide, we're going to create a production stage for a brand-new project and deploy it to AWS Lambda.
The first step is to create two IAM Roles that will govern what the CloudFormation stack and stage functions can do. We'll also create an IAM user who will be used to start deployments and interact with AWS via Hover.
A step-by-step guide for creating the two roles and the user can be found here.
After this step, we'll collect the following information:
- The ARN of the CloudFormation execution role.
- The ARN of the Lambda execution role.
- The
aws_access_key_id
andaws_secret_access_key
of the IAM user.
In a CI environment, we will add those keys to the AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
environment variables. On local machines, however, we will create an AWS named profile inside the ~/.aws/credentials
file:
[production]
aws_access_key_id = AKIA******
aws_secret_access_key = uw6*******
Let's run the following command inside the root directory of our project:
hover stage new clouder production
clouder
here is the name of our app and production
is the name of the stage.
Hover is going to ask us for the following:
- Name of the AWS region.
- Name of the AWS profile.
- The ARN of the CloudFormation execution role.
- The ARN of the Lambda execution role.
Once the command successfully executes, the following files will be created inside a .hover
directory:
production.yml
.gitignore
.Dockerfile
production-secrets.plain.env
Hover will show us a warning to ensure some composer dependencies are installed in the application. These are:
- hollodotme/fast-cgi-client:^3.1
- guzzlehttp/promises:^1.5
- aws/aws-sdk-php:^3.2
We will run the following command to require these dependencies:
composer require hollodotme/fast-cgi-client:^3.1 guzzlehttp/promises:^1.5 aws/aws-sdk-php:^3.2
These are dependencies of the Hover runtime and must be installed prior to deployment.
Every Laravel application requires an APP_KEY
environment variable configured. Let's generate one:
php artisan key:generate --show
The command will output a new encryption key. We'll copy this key and update the APP_KEY
variable inside the production-secrets.plain.env
file:
APP_KEY=base64:pbx6nnS****
We also want to update the DB_PASSWORD
variable to hold the production database password.
DB_PASSWORD:CA&G********
In this file, we may add any variables that hold sensitive information which shouldn't be exposed when committing to git. Once all changes are done, let's run the following command:
hover secret encrypt --stage=production
This command will encrypt the secrets into a production-secrets.env
file and delete the production-secrets.plain.env
one.
Note: For more information on secrets, check this guide
For non-sensitive variables, we will store them inside the production.yml
manifest file:
environment:
APP_DEBUG: false
APP_LOG_LEVEL: debug
FILESYSTEM_DRIVER: s3
FILESYSTEM_CLOUD: s3
LOG_CHANNEL: stderr
QUEUE_CONNECTION: sqs
SCHEDULE_CACHE_DRIVER: dynamodb
SESSION_DRIVER: cookie
Inside the ./hover/production.yml
manifest file, we may configure how Hover should deploy our application. A complete reference of the file can be found here.
One of the most important considerations is configuring the queue component so that Hover creates all queues required by the application. Otherwise, we'll get errors because the application is attempting to dispatch jobs to a non-existent queue.
Let's say our app pushes to 3 queues, here's how the setup will look:
queue:
default:
memory: 512
timeout: 120
concurrency: 5
tries: 3
backoff: "5, 10"
queues:
- default
- notifications
priority:
memory: 512
timeout: 300
concurrency: 10
tries: 5
backoff: "1"
queues:
- priority
We created 2 functions that process jobs from the three queues (default, notifications & priority).
Note: For more information on working with queues, check this guide
Hover containerizes our application and prepares it to run on AWS Lambda using Docker. It uses the same base docker image to run the tests, and uses a separate build stage to compile our application asset files.
To configure the build, we may edit the .hover/.Dockerfile
file.
For example, we can change the command that executes our tests by updating the tests
stage of the docker file:
FROM base as tests
- CMD vendor/bin/phpunit
+ CMD php artisan test
Note: For more information on the Docker file, check this guide
Now that we have everything configured, let's build the stage:
hover build production
During the build process, Hover will inject the runtime files and build the docker images defined in the .Dockerfile
. It will also run the tests on the "tests" docker stage.
Note: For more information on the build process, check this guide
Hover deploys our application by uploading the compiled assets files to S3 and the Docker image to ECR. It then provisions a CloudFormation stack to create all the needed AWS resources to run the stage. This includes:
- ApiGateway HTTP API
- Lambda Functions
- CloudFormation Distribution
- EventBridge Rules
- SQS Queues
Note: For the complete list of resources managed by Hover and a general overview of the architecture concept. Check this guide.
To start the deployment, let's run the following command:
hover deploy
Once the stack is provisioned, Hover will publish a new version of each of the functions, warm several HTTP function containers, run deployment commands and activate the new release.
Note: For more information on the deployment process, check this guide
After the deploy
command finishes, Hover will print an alias domain that looks like this:
https://<random_string>.cloudfront.net
We can visit our website using this domain to test things out, we can also configure a custom domain by following this guide.
To run artisan commands, we may use the command run
command:
hover command run "inspire" --stage=production
This will run the php artisan inspire
command inside the CLI function and print the output.
Note: For more information on how the runtime works, check this guide