1. Overview
Sensitive information such as API keys, database credentials, and other confidential data shouldn’t be stored carelessly. Accidental exposure can lead to security breaches that can compromise individuals and organizations. With environment variables, we can manage this information outside of code. However, securely integrating them into automated workflows can be challenging.
In this tutorial, we’ll explore various ways to use an env file to securely store and manage environment variables within the GitHub Actions workflow.
2. Understanding Environment Variables
Environment variables dynamically influence the behavior of running processes. In essence, they serve as containers for configuration settings and sensitive data, such as API keys and database credentials, which are essential for applications to function properly.
2.1. Importance of Environment Variables
Environment variables are important for several reasons:
- Security: They allow sensitive information to be stored outside the source code, reducing the risk of exposure
- Configuration Management: Environment variables make managing configurations for different environments easier; for example, development, staging, or production
- Portability: They enable applications to be more portable and adaptable to different environments; it is particularly useful in CI/CD pipelines, containerization, and cloud deployments where applications need to run in various contexts
2.2. How Environment Variables Work
Applications and scripts can access environment variables during runtime. These dynamic configurations enhance security and flexibility, especially in CI/CD pipelines like GitHub Actions.
For instance, GitHub Actions leverages environment variables to dynamically tailor pipeline setup, such as specifying environments or providing deployment details:
name: Deploy Application
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
env:
ENVIRONMENT: production
DEPLOYMENT_URL: https://baeldung.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to Server
run: |
curl -X POST ${{ env.DEPLOYMENT_URL }} \
-H "Content-Type: application/json" \
-d '{"environment":"${{ env.ENVIRONMENT }}"}'
This example defines ENVIRONMENT and DEPLOYMENT_URL as environment variables directly within the workflow. The deployment step then dynamically uses these variables to specify the target environment and deployment URL.
2.3. Best Practices
To ensure optimal security and flexibility, we can follow these key practices when managing environment variables:
- Avoid hardcoding sensitive data
- Use a consistent naming convention
- Document variables
- Limit the scope of variables; only expose the necessary environment variables to the scope that requires them
Understanding and properly managing environment variables enhances applications’ security and flexibility.
3. Storing Environment Variables in GitHub Actions
GitHub Actions offers several methods for managing environment variables, ensuring both security and efficiency in workflows. Primarily, we can define environment variables directly within the workflow configuration or leverage GitHub Secrets for sensitive data.
3.1. Using the env Key in Workflow Files
We can define environment variables directly in the workflow file using the env key. This method is straightforward and suitable for non-sensitive data.
Firstly, let’s create a directory and navigate to it:
$ mkdir gh-action-env-files && cd gh-action-env-files
Next, we create a new GitHub Actions workflow file in the .github/workflows directory:
$ mkdir -p .github/workflows
$ touch .github/workflows/env-key-example.yml
Now, let’s add the following code to the env-key-example.yml file:
name: Env Key Example
on: [push]
jobs:
create-env-file:
runs-on: ubuntu-latest
env:
SOME_API_KEY: "123456abcdef"
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Create .env file
run: echo "SOME_API_KEY=${{ env.SOME_API_KEY }}" > .env
The env-key-example.yml file defines a GitHub Actions workflow named Env Key Example, triggered upon any push to the repository. This workflow contains a single job titled create-env-file that is configured to run on the latest Ubuntu environment.
Within the job, we defined SOME_API_KEY, an environment variable with the value 123456abcdef. The workflow includes two steps. Firstly, it checks out the repository using the actions/checkout action, which ensures that the repository’s content is available in the workflow environment. Secondly, it creates an env file using the echo command to write the value of SOME_API_KEY into the file.
3.2. Pushing to GitHub
After defining the workflow, we can push the changes to a GitHub repository to trigger the workflow and see it in action. Firstly, let’s create a new GitHub repository. Next, we push to GitHub:
$ git init
$ git add .
$ git commit -m "Add GitHub Actions workflow to use env key"
$ git branch -M main
$ git remote add origin <your-github-repo-url>
$ git push -u origin main
With these changes pushed to GitHub, we can navigate to the Actions tab in the GitHub repository to see the workflow in action:
Now, let’s see the details of this workflow file. Firstly, click on the Add GitHub Actions workflow to use env key commit message as shown in the previous image. This will expand the details of the workflow run.
Next, click on the create-env-file job and on the Create .env file step to view the specific actions taken during this part of the workflow:
We can now verify that the SOME_API_KEY environment variable was correctly used and that the .env file was successfully created.
Using environment variables directly within a GitHub Actions workflow via the env key effectively handles non-sensitive data. In the next section, let’s see how to manage sensitive data securely using GitHub Secrets.
3.3. Using GitHub Secrets
When handling sensitive information like API keys, database credentials, or any other confidential data, it’s crucial to ensure that this information is not exposed in the source code or the workflow files. GitHub Secrets provide a secure way to store and manage this data within GitHub Actions.
These secrets are encrypted and can be referenced within workflows. This allows sensitive information to be used without being exposed in plain text. To start using GitHub Secrets, let’s navigate to the Settings tab. Expand the Secrets and variables in the sidebar, and click on Actions:
Next, let’s click on the green New repository secret button, and enter a name for the secret in the Name field. Here we can use TEST_SECRETS and the following dummy secrets in the Secret input:
SECRET_KEY=your_sample_secret_key
DATABASE_URL=your_sample_database_url
API_KEY=your_sample_api_key
AWS_ACCESS_KEY_ID=your_sample_access_key_id
AWS_SECRET_ACCESS_KEY=your_sample_secret_access_key
GOOGLE_CLIENT_ID=your_sample_client_id
GOOGLE_CLIENT_SECRET=your_sample_client_secret
TWITTER_API_KEY=your_sample_api_key
TWITTER_API_SECRET=your_sample_api_secret
FACEBOOK_APP_ID=your_sample_app_id
FACEBOOK_APP_SECRET=your_sample_app_secret
GITHUB_TOKEN=your_sample_github_token
MAILGUN_API_KEY=your_sample_api_key
SENDGRID_API_KEY=your_sample_api_key
SLACK_API_TOKEN=your_sample_api_token
STRIPE_SECRET_KEY=your_sample_secret_key
TWILIO_ACCOUNT_SID=your_sample_account_sid
TWILIO_AUTH_TOKEN=your_sample_auth_token
MONGODB_URI=your_sample_mongodb_uri
REDIS_URL=your_sample_redis_url
With these updates, let’s click on the Add secret button to save the secrets to the repository.
Once the secrets are stored in the repository, we can use them in a workflow file. Firstly, let’s create a new workflow file in the .github/workflows directory:
$ touch .github/workflows/using-github-secrets.yml
Next, let’s add the following code to the using-github-secrets.yml file:
name: Using GitHub Secrets
on: [push]
jobs:
using-github-secrets:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Create .env file
run: |
touch .env
echo "${{secrets.TEST_SECRETS}}" >> .env
- name: Test printing your secret (Remove this step in production)
run: |
cat .env
Similarly, we can trigger this workflow by any push event to the repository. It has a single job named using-github-secrets, which runs on the latest Ubuntu environment (runs-on: ubuntu-latest).
The first step uses the actions/checkout@v3 action to clone the repository, making the files available to the workflow. The next step, Create .env file, creates an empty .env file using touch .env. After this, we append the value of the TEST_SECRETS secret to the .env file.
With the secrets appended, we print the contents of the .env file. This step is primarily for testing purposes to ensure the secret was correctly processed.
3.4. Pushing to GitHub
Now, let’s push to GitHub:
$ git add . && git commit -m "Use GitHub Secrets" && git push origin main
After that, let’s navigate to the Actions tab, select the Use GitHub Secrets commit message, and view the contents of the workflow:
Here, we can see the secrets masked to protect their values. This ensures that sensitive information remains secure, even when reviewing logs or debugging issues.
4. Conclusion
In this article, we learned how to manage environment variables in GitHub Actions using an env file. Firstly, we discussed the importance of protecting sensitive information like API keys and configuration settings. Then, we checked out how to use the env to directly define non-sensitive data.
For more sensitive information, we leveraged GitHub Secrets, which offers an encrypted and secure way to store and reference these variables within workflows.
In addition, the optimal approach to managing environment variables depends on the sensitivity of the data involved. GitHub Actions offers flexibility, but careful consideration is essential. The complete code for this article is available on GitHub.