1. Introduction
In the previous articles, we created a docker image of a simple FastAPI project and deployed it to AWS ECS Fargate.
Most of the times, we deal with environment variables such as database connection info or some other 3rd-party API secret keys. In this article, we’ll talk about how we can manage environment variables in AWS server.
2. Modify source code
Previously, we made a super simple server with only one endpoint that returns “Welcome back to root!”.
1
2
3
4
5
6
7
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
def welcome_root():
return "Welcome back to root!"
Now, let’s modify the source code to include an environment variable called SECRET_NICKNAME
1
2
3
4
5
6
7
8
9
from fastapi import FastAPI
import os
app = FastAPI()
@app.get('/')
def welcome_root():
secret_nickname = os.environ.get("SECRET_NICKNAME")
return f"Welcome back to root. {secret_nickname}!"
3. Approach #1 - Inject env variables as arguments when running a container image
The first approach is to inject environment variables when we run the container image.
Let’s build the container image by running the following command.
Now run the following command to pass SECRET_NICKNAME
env variable.
1
docker run -e SECRET_NICKNAME=Jason -p 8000:8000 demo-env
If you check the localhost:8000
, you’ll see that we successfully passed the env variable.
4. Approach #2 - Pass the environment variable file when running a container image
Alternatively, we can pass the environment variable file path when running an image.
First create .env
file under the project root directory.
Then, run the container image by passing --enf-file
option and the target path .env
.
1
docker run --env-file .env -p 8000:8000 demo-env
You can see that the env variable has been successfully passed.
5. Approach #3 - Using AWS Systems Manager Parameter Store
AWS offers a good way to store and manage our environment variables in the Amazon system.
Let’s navigate to the AWS console and search for Systems Manager.
Click the “Parameter Store” in the left panel.
You can register your own environment variables here. To create one, click “Create parameter” on the top right corner.
Enter the environment variable name SECRET_NICKNAME
and select SecureString if you want to store it as a secret information.
Then, enter the value in the box and create.
Now you can see that our env variable is created in the parameter store.
6. Grant access to Parameter Store in IAM
To use the AWS Systems Manager Parameter Store in your ECS service, you must have the ECS task execution role and reference it in your task definition.
Notice that in the task definition we created in the previous article, you can find that the “Task execution role” is referencing ecsTaskExecutionRole
.
Now let’s navigate to IAM service from the console and click “Roles” in the left panel.
Click the ecsTaskExecutionRole
.
Then select “Add permissions” in Permissions policies panel and select “Create inline policy”.
Select JSON
and paste the following.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"secretsmanager:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"arn:aws:ssm:<your region>:<your aws account id>:parameter/<parameter name>"
]
}
]
}
Modify the following three.
<your region>
<your aws account id>
<parameter name>
- this would beSECRET_NICKNAME
that we have defined in the Parameter Store.
After you create a permission policy, you can see that it’s not attached to ecsTaskExecutionRole
(I already had one)
7. Create a new task definition revision
Now, navigate back to ECS service and select “Task definitions” in the left panel.
Click the task definition and select “Create new vision -> Create new revision” in the top-right corner.
Scroll little bit and you’ll find “Environment variables - optional” section. Enter the key (env variable name), select “ValueFrom”, and enter arn:aws:ssm:<your region>:<your aws account id>:parameter/SECRET_NICKNAME
in the “Value” field.
Scroll to the bottom and click “Create”
You can see that the new task definition revision has been created.
8. Update service
Go to the Clusters and select the cluster you created.
Then, click the service in “Services” panel.
Now we need to update our service with the newly created task definition which contains the environment variable referencing the Parameter Store.
Click “Update service” in the top-right corner.
Then, select “Force new deployment”.
You can see that the new task definition is now available. So click revision 2 (LATEST)
.
Now, scroll to the bottom and click “Update”.
Select “Deployments and events” panel on the top, and you’ll see that the updated service is in progress for a new deployment.
After a moment, you can see that the new deployment is successful!
Let’s open the browser and see if our server is updated. Make sure you enter the DNS name shown in the load balancer.
Congratulations! Now you’re able to pass any environment variable using the AWS Parameter Store in your own project.