In this article, I'm going to guide you how to save the project secure tokens in Github Secrets and deploy them into AWS Secrets Manager using Terraform and Github Actions workflow.
Using sensitive information, such as api key, password, secure tokens in a real project is very common. For example, you are working on a backend web server that needs to interacts with database. You must have database user/password configured programmatically no matter which programming language you select. These secure tokens are normally persisted in a secret management tool, and injected into environment variables when the server is up.
Secrets management tools help companies securely store, transmit, and manage sensitive digital authentication credentials such as passwords, SSH keys, API keys, database passwords, certificates like TLS/SSL certificates or private certificates, tokens, encryption keys, privileged credentials, and other secrets.
Some companies use third-party tools, such as AWS Secrets Manager, Azure Key Vault, and HashiCorp Vault, etc. Some CICD tools also provide secret management features to allow your pipeline retrieves these secrets easily before deployment. Jenkins has Credentials and Github Actions has Secrets.
What I implemented:
- Create a Terraform project that defines a
aws_secretsmanager_secret
resource using AWS official provider. - Create an
Environment
nameddev
and add secrets and variables in the environment. - Create a Github Actions workflow to deploy Terraform resources to AWS account.
Find the demo source code from https://github.com/camillehe1992/aws-terraform-examples/tree/main/secret-manager
Project Structure
The project source code structure as follows.
.
├── Makefile # a markfile for terraform commands
├── README.md
├── main.tf # define the specs of secretsmanager module
├── modules
│ └── secretsmanager # secretsmanager module
│ ├── locals.tf
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
├── outputs.tf # outputs of terraform
├── terraform.tfvars # variables of terraform
├── variables.tf # variables definition of terraform
└── versions.tf # terraform backend configuration and provider versions
Define a variable named database_password
in variables.tf
.
variable "database_password" {
type = string
description = "The password of database"
}
Define a Terraform module named secretsmanager
and create a bucket of secrets.
Modules are containers for multiple resources that are used together.
module "secrets" {
source = "./modules/secretsmanager"
env = var.env
nickname = var.nickname
tags = var.tags
secret_specs = {
database_password = {
description = "A sample secure. e.g password"
secret_string = var.database_password
}
}
}
Create Environment and Secrets
Create an environment named dev
in Github Settings, and add secrets and variables in it as follows.
Github Actions Workflow
Define an environment variable name DATABASE_PASSWORD
in env
block in Github Actions workflow file and inject the environment variable DATABASE_PASSWORD
dynamically when running command terraform plan
via parameter -var
.
env:
# Secret tokens injected into Terraform infra
DATABASE_PASSWORD: "${{ secrets.TF_VAR_DATABASE_PASSWORD }}"
...
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Terraform Plan</span>
<span class="na">if</span><span class="pi">:</span> <span class="s">${{ inputs.destroy }} == </span><span class="kc">false</span>
<span class="na">id</span><span class="pi">:</span> <span class="s">tf-plan</span>
<span class="na">working-directory</span><span class="pi">:</span> <span class="s">${{ env.WORKING_DIRECTORY }}</span>
<span class="na">run</span><span class="pi">:</span> <span class="pi">|</span>
<span class="s">export exitcode=0</span>
<span class="s">terraform plan -var-file $(pwd)/tf_$ENVIRONMENT.tfvars \</span>
<span class="s">-var="database_password=$DATABASE_PASSWORD" \</span>
<span class="s">-detailed-exitcode -no-color -out tfplan || export exitcode=$?</span>
Trigger Deployment Manually
- Choose the target environment to deploy. Currently only dev is available.
- Check
True to destroy
checkbox if you want to destory the resources. - Check
True to force
checkbox if you want to apply refresh the secure tokens. Useful when there is no change in Terraform infra, but there is a variables or secrets update in Github Settings.
Done. I'm always appreciating your comments and advice.
Top comments (1)
Hi @camillehe1992
I have setup everything like above in my .NET 8 application.
Below is my variable declaration in my tf:
variable "param_Api_Service_Password" {
type = string
description = "Parameter write API Service Password"
sensitive = true
default = "********"
}
I have set default value as "********".
In my AWS secrets manager, Git secret values are not getting picked up and this default value is stored in the secret. Could you please suggest what could be wrong?