Deploy ephemeral Environments
The following tutorial describes how to set up ephemeral environments using Score with the Humanitec Platform Orchestrator.
What are ephemeral Environments?
At its core, an ephemeral environment is a temporary, on-the-fly instance of an application.
It’s built to mirror production settings but exists solely for the duration of a specific task, such as testing a feature or bug fix. Once the task is done, the environment is torn down.
The Humanitec Platform Orchestration makes it possible to not only spin up your container, but also to define which resource to wire the running service to. This is possible using the power of dynamic configuration management, which essentially means the Platform Orchestrator is dynamically creating app and infrastructure configurations with every git-push, based on the configuration you provide.
For information on setting up preview environments, see Dynamic Previews.
Configuring repositories for ephemeral Environments
To effectively enable ephemeral environments, it’s essential to understand the repository setup and the necessary configurations.
- Initialize Repositories and CI/CD Pipelines: Begin by setting up your repositories and CI/CD pipelines. This ensures that whenever a pull request is made, the Platform Orchestrator automatically creates an ephemeral environment.
- Understand the Workload: The workload in focus resides in the given repository. For example, a containerized Node.js application, might rely on both Postgres for data storage and a DNS for domain name resolution. AWS furnishes the target infrastructure.
- Introduce the Workload Specification:
The source code of the workload includes a specification using Score, represented as a
score.yaml
file. This file abstractly describes our service, making it agnostic to the specific environment. The Platform Orchestrator then interprets this file.
Here’s a glimpse of its structure:
# Define the resources that this service requires
resources:
dns: # A DNS record to point to the service
type: dns
db: # A database for data storage
type: postgres
In the score.yaml
file, it’s important to note that express the resource type and let the platform team handle the rest.
For instance, you don’t specify the exact DNS record or database that is needed, just that our service requires a DNS record and a database. The Platform Orchestrator then interprets this abstract request and creates the necessary DNS record and database for the ephemeral environment.
Setting up your pipeline with GitHub Actions
While this tutorial outlines the steps to set up ephemeral environments using GitHub Actions, the same can be achieved using any CI/CD tool.
Set up your pipeline to create ephemeral environments using GitHub Actions.
To leverage GitHub Actions for spinning up ephemeral environments, follow the steps below:
Describing your Workload
Describe your service and its resources using Score.
This is done by creating a score.yaml
file in the root directory of your repository.
apiVersion: score.dev/v1b1
metadata:
name: hello-world
# Define the ports that this service exposes
service:
ports:
www:
port: 80 # Exposed service port
targetPort: 3000 # Port the container listens on
# Define the service's containers
containers:
frontend:
image: registry.humanitec.io/public/sample-score-app:latest
variables:
MESSAGE: "Hello World"
PORT: "3000"
DB_DATABASE: ${resources.db.name}
DB_USER: ${resources.db.username}
DB_PASSWORD: ${resources.db.password}
DB_HOST: ${resources.db.host}
DB_PORT: ${resources.db.port}
# Specify required resources
resources:
dns: # DNS record for the service
type: dns
db: # Database for data storage
type: postgres
View the full configuration here.
Configuring pipelines
Create a new pipeline in GitHub Actions and set it to activate when a new pull request event occurs. The configuration for this trigger is:
on:
pull_request:
types: [opened, reopened, synchronize]
Orchestrator API calls
Within the pipeline, make a call to the Humanitec Orchestrator API to create a new environment:
- name: Create Humanitec Env
run: |
# Get deployment ID of the main development environment
curl \
-H "Content-Type: application/json" \
-H 'Authorization: Bearer ${{ secrets.HUMANITEC_TOKEN }}' \
https://api.humanitec.io/orgs/${{ vars.HUMANITEC_ORG }}/apps/${{ vars.APP_NAME }}/envs/${{ env.BASE_ENVIRONMENT }} \
| jq -r ".last_deploy.id" > deploy_id.txt
# Create a new environment for the PR
curl -X POST \
-H "Content-Type: application/json" \
-H 'Authorization: Bearer ${{ secrets.HUMANITEC_TOKEN }}' \
https://api.humanitec.io/orgs/${{ vars.HUMANITEC_ORG }}/apps/${{ vars.APP_NAME }}/envs \
--data-binary @- << EOF
{
"from_deploy_id": "$(cat deploy_id.txt)",
"id": "${{ env.ENVIRONMENT_ID }}",
"name": "${{ env.ENVIRONMENT_NAME }}",
"type": "${{ env.ENVIRONMENT_TYPE }}"
}
EOF
Setting Environment variables
These variables are crucial as they act as metadata, guiding the Orchestrator in understanding and materializing the abstract requests from the workload specifications:
env:
BASE_ENVIRONMENT: 'development' # Base environment reference
ENVIRONMENT_TYPE: 'development' # Environment type
SCORE_HUMANITEC_VERSION: 0.6.0 # Score version
ENVIRONMENT_ID: pr-${{ github.event.number }} # New environment ID
ENVIRONMENT_NAME: PR-${{ github.event.number }} # New environment name
For instance, the Orchestrator can interpret the general need “I need a Postgres” and instantiate a new Postgres instance for the ephemeral environment.
5. Trigger Deployment with Score-Humanitec CLI:
Lastly, configure the pipeline to execute the Score-Humanitec CLI, which initiates the deployment:
- name: Run Score
run: |
score-humanitec delta \
--retry \
--deploy \
--token ${{ secrets.HUMANITEC_TOKEN }} \
--org ${{ vars.HUMANITEC_ORG }} \
--app ${{ vars.APP_NAME }} \
--env ${{ env.ENVIRONMENT_ID }}
Using ephemeral Environments
Once the initial setup is complete, developers can seamlessly integrate ephemeral environments into their daily workflows. This integration simplifies the review and testing process significantly.
Creating a pull request
Creating a pull request triggers the pipeline, which then creates a new ephemeral environment. For example, let’s change the environment variable to “Hello Team!” in the score.yaml
file:
containers:
frontend:
image: registry.humanitec.io/public/sample-score-app:latest
variables:
MESSAGE: "Hello Team!"
Upon making this modification and submitting the pull request, the configured pipeline gets triggered. This process involves:
- Running the pipeline.
- Pushing the updated Score file to the Orchestrator.
- The Orchestrator then interprets the changes, formulates the necessary application and infrastructure configurations, and subsequently establishes the new environment.
Once the deployment is finalized, our pipeline is designed to append a comment on the pull request. This comment furnishes pertinent details about the newly created environment, ensuring developers have all the necessary information at their fingertips.
Cleaning up
To prevent incurring unnecessary costs, it’s advisable to automate the teardown of these environments post their utility.
Implementation Steps:
- Pipeline Trigger on PR Closure
- Configure your pipeline to be invoked when a pull request concludes. This ensures the associated ephemeral environment is targeted for teardown.
- Request Deletion through the Humanitec Platform Orchestrator.
- Within the pipeline, send a DELETE request to the Humanitec Orchestrator API, instructing it to dismantle the environment associated with the closed PR.
name: Close Pull Request
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Delete Humanitec Env
run: |
curl -X DELETE \
-H "Content-Type: application/json" \
-H 'Authorization: Bearer ${{ secrets.HUMANITEC_TOKEN }}' \
https://api.humanitec.io/orgs/${{ vars.HUMANITEC_ORG }}/apps/${{ vars.APP_NAME }}/envs/pr-${{ github.event.number }}
Find the complete configuration here.
Advantages of ephemeral Environments
Having successfully set up ephemeral environments, you unlock a host of advantages:
- Efficient Testing: Test your changes swiftly without navigating lengthy merge processes.
- Collaborative Review: Showcase modifications to colleagues, QA teams, and gather feedback more proactively.
- Enhanced Code Review: Before green-lighting a PR, team members can run the new features to ascertain they operate as intended.
- Support for Sales Team: Empower sales teams with dedicated environments tailored for potential customers and demos.
However, to strike a balance between flexibility and cost-efficiency, it’s essential to manage the lifecycle of these ephemeral environments. Automating their creation and teardown is pivotal to reap maximum benefits while keeping costs in check.
This step-by-step guide should equip teams with the knowledge to harness ephemeral Environments effectively.