Terraform Secrets Management: Day 6
Securing Infrastructure: Exploring Terraform Secrets Management
Introduction
As technology shifts towards cloud and Infrastructure as Code (IaC), protecting data is the main priority of any environment. Various types of sensitive information like passwords, API keys, and service certificates are essential for running Terraform. Thus, the need for a robust secret management solution is critical. Managing secrets in Terraform entails securely handling such sensitive data.
Importance of Secrets in Terraform Provisioning
Secrets are essential in providing secure access to cloud providers.
Secrets help in setting up authentication through API keys, OAuth tokens, SSL
Secrets are required to access sensitive information like database, customer personal information, account statements etc.
Secrets are necessary for setting up network components.
Secrets are essential for integrating terraform and providing authentication and authorization to respective services with any of the cloud like AWS, Azure, Google Cloud etc. These credentials are in the form of access keys and secrets.
Way of Managing Secrets
Encrypting passwords or keys in config files to add extra security to sensitive data.
Using third-party software like Hashicorp Vault and AWS Secrets managers.
Using environment variables wherever possible.
Using secure remote backend.
Encrypt files with KMS, PGP or SOPS.
Using Terraform variable to define variables within your configuration files or in separate variable files.
Regular monitoring or auditing of the usage of secrets to detect any unauthorized access.
Masking sensitive values.
Setting up Hashicorp Vault on AWS
Creating the S3 Bucket for Vault Storage
To begin, we'll establish an S3 bucket to serve as storage for our Vault instance:
Access the S3 console through the AWS management console.
Click on the "Create bucket" button.
Provide a name for the bucket, leaving other settings unchanged.
Keep note of the bucket's ARN for future reference.
Retrieve the bucket ARN by selecting the bucket and navigating to Permissions → Bucket Policy.
Set up IAM roles and Policies
Create IAM Policy fo full access to S3 bucket
Go to the AWS Management Console and open the IAM (Identity and Access Management) service.
In the IAM dashboard, click on "Policies" in the left sidebar.
Click on the "Create policy" button.
Select "JSON" as the policy editor.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:*" ], "Resource": "*" } ] }
Select the review policy button.
Give any name to the policy and click on Create policy" button to create the policy.
Create IAM Role
Navigate to the "Roles" section in the side menu.
Click on the "Create role" button.
Choose "EC2" as the use case for this role.
Attach the previously created policy to the role.
Proceed to the next steps by clicking "Next" until you reach the Review step.
Provide a name and description for the role.
Finally, click on the "Create role" button to finish the process.
`Create IAM User
Navigate to the "Users" section in the side tab.
Click on "Add user."
Provide a name for the user.
Select "Programmatic access" for the access type.
Click "Next: Permissions."
Attach the S3 policy from the previous section to the user.
Proceed by clicking "Next" until you reach the Review step.
Review the information and then click "Create user."
On the next screen, save or download the user credentials.
Next, create another policy that will allow this IAM user to authenticate with the AWS SDK while using Vault. Navigate to the "Permissions" tab and click on "Add Permissions."
Select "Add existing policies directly."
Click "Create policy."
In the JSON tab, input the following policy definition
Click "Review Policy."
Provide your policy with a name and description.
Finally, click "Create policy."
Attach this policy to the new user you just created.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"iam:GetInstanceProfile",
"iam:GetUser",
"iam:GetRole"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"<USER_ARN>"
]
}
]
}
Setting up the ec2 instance
Go to the EC2 console from the AWS management console.
Select "Instances" from the tab on the right side.
Click on "Launch Instance."
Choose the AWS Linux 2 AMI (the topmost option).
Select an instance class. For this tutorial, we will use a nano size instance.
Click "Next: Configure Instance Details."
Under IAM role, select the IAM role created in the previous step.
Click "Next: Add Storage."
The defaults are suitable. Proceed by clicking "Next: Add Tags."
Provide your instance with a Name tag so you can identify it after launch.
Click "Next: Configure Security Group."
Create a new security group and add a new TCP rule with port range 8200. source as "My IP."
Click Review and Launch instance with new Key pair and Click on Launch button.
Installing Vault
- Install gpg
sudo apt update && sudo apt install gpg
Download the signing key to a new keyring
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
Verify the key's fingerprint.
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
Add the HashiCorp repo
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
Install Vault
sudo apt install vault
Start Vault
vault server -dev -dev-listen-address="0.0.0.0:8200"
Setting Access for User using Approle
Click on Approle > next > Enable Method.
Configure AppRole.
Configure Terraform to read from Vault
Launch vault using public IP of EC2 instance where we have created vault with password as token.
Configuration of Approle via CLI
- Enable vault approle
vault auth enable approle
- Create a Policy for terraform
vault policy write terraform - <<EOF
path "*" {
capabilities = ["list", "read"]
}
path "kv/data/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
EOF
Create approle
vault write auth/approle/role/terraform \ secret_id_ttl=10m \ token_num_uses=10 \ token_ttl=20m \ token_max_ttl=30m \ secret_id_num_uses=40 \ token_policies=terraform
Generate roleId
vault read auth/approle/role/terraform/role-id
Generate Secret ID
vault write -f auth/approle/role/terraform/secret-id
Now, secret id and role id are displayed on screen.
Use below script in main.tf in visual studio
provider "aws" { region = "us-east-1" } provider "vault" { address = "<>:8200" skip_child_token = true auth_login { path = "auth/approle/login" parameters = { role_id = "" #From above steps secret_id = "" #From above steps } } } data "vault_kv_secret_v2" "example" { mount = "kv" name = "test-secret" } resource "aws_instance" "my_instance" { ami = "ami-053b0d53c279acc90" instance_type = "t2.micro" }