Reputation: 2011
I tried to create a custom module to encrypt our access and secret access keys when outputs are used. Thus when a build runs it tries to print the out the access key after encrypting it using kms.
But currently when we use this module to create multiple users, it's just printing the 1st user's access key and secret key for other users as well.
Someone please suggest me how i should fix this. Using terraform 0.12.18
variable "iam_username" {
description = "IAM username"
}
variable "path" {
description = "path for IAM user"
default = "/"
}
resource "aws_iam_user" "iam_user" {
name = var.iam_username
path = var.path
}
resource "aws_iam_access_key" "iam_keys" {
user = aws_iam_user.iam_user.name
}
data "external" "stdout" {
program = [
"bash",
"${path.module}/encrypt_credentials.sh"]
query = {
access_key = aws_iam_access_key.iam_keys.id
secret_key = aws_iam_access_key.iam_keys.secret
}
}
encrypt_credentials.sh
function encrypt() {
aws kms encrypt --key-id alias/xxxx --plaintext $ACCESS_KEY --output text --query CiphertextBlob --region us-east-1 > encrypted_access_key
aws kms encrypt --key-id alias/xxxx --plaintext $SECRET_KEY --output text --query CiphertextBlob --region us-east-1 > encrypted_secret_key
}
function output() {
access_key=$(cat encrypted_access_key )
secret_key=$(cat encrypted_secret_key)
jq -n \
--arg access_value "$access_key" \
--arg secret_value "$secret_key"\
'{"access_value":$access_value,"secret_value":$secret_value}'
}
encrypt
output
outputs.tf
output "aws_iam_access_key" {
value = chomp(data.external.stdout.result["access_value"])
}
output "aws_iam_secret_access_key" {
value = chomp(data.external.stdout.result["secret_value"])
}
I tested this module, I'm trying to create two users, test1, test2 ..here is the output, it as the same access key and secret key for both users
Terraform
module "test1user" {
source = "../../"
iam_username = "test1"
path = "/"
}
module "test2user" {
source = "../../"
iam_username = "test2"
path = "/"
}
outputs.tf
output "user1_access_key" {
value = module.test1user.aws_iam_access_key
}
output "user1_secret_key" {
value = module.test1user.aws_iam_secret_access_key
}
output "user2_access_key" {
value = module.test2user.aws_iam_access_key
}
output "user2_secret_key" {
value = module.test2user.aws_iam_secret_access_key
}
14:47:47 TestTerraformAwsNetworkExample 2020-07-22T18:47:47Z logger.go:66: user1_access_key = AQECAHj0ior/LD5LXMzmwFwEYlbqXWdHuCRWGQNeqhU6VNir+gAAAHIwcAYJKoZIhvcNAQcGoGMwYQIBADBcBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDDULiS2JecmxLYdv9QIBEIAvjB60Maw5IuryzukItn8awWXnqfUzUcnPJNq7mFHQ2MYRBtOqBJJo0zbPo1i+pgw=
14:47:47 TestTerraformAwsNetworkExample 2020-07-22T18:47:47Z logger.go:66: user1_secret_key = AQECAHj0ior/LD5LXMzmwFwEYlbqXWdHuCRWGQNeqhU6VNir+gAAAIcwgYQGCSqGSIb3DQEHBqB3MHUCAQAwcAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxyo66cMnxkOCrHjhoCARCAQzbpGYCzH6Ed+XvDFinBSbrK0LDk0YMXh39JCcztYwoJDFMbAtnWlS4cUyrmncf5paxE2oB7w2ujtpds/dBxUtsw6Lg=
14:47:47 TestTerraformAwsNetworkExample 2020-07-22T18:47:47Z logger.go:66: user2_access_key = AQECAHj0ior/LD5LXMzmwFwEYlbqXWdHuCRWGQNeqhU6VNir+gAAAHIwcAYJKoZIhvcNAQcGoGMwYQIBADBcBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDDULiS2JecmxLYdv9QIBEIAvjB60Maw5IuryzukItn8awWXnqfUzUcnPJNq7mFHQ2MYRBtOqBJJo0zbPo1i+pgw=
14:47:47 TestTerraformAwsNetworkExample 2020-07-22T18:47:47Z logger.go:66: user2_secret_key = AQECAHj0ior/LD5LXMzmwFwEYlbqXWdHuCRWGQNeqhU6VNir+gAAAIcwgYQGCSqGSIb3DQEHBqB3MHUCAQAwcAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxyo66cMnxkOCrHjhoCARCAQzbpGYCzH6Ed+XvDFinBSbrK0LDk0YMXh39JCcztYwoJDFMbAtnWlS4cUyrmncf5paxE2oB7w2ujtpds/dBxUtsw6Lg=
Upvotes: 0
Views: 336
Reputation: 17574
I refactored a lot of the code as I tried to reproduce it...
Finally got it working.
What I found suspicious was your > encrypted_access_key
to latter read it back, we can just load that into a var and consume it without the intermediary file, and that is what I did.
module
variable "name" {
type = string
}
resource "aws_iam_user" "iam_user" {
name = var.name
}
resource "aws_iam_access_key" "iam_keys" {
user = aws_iam_user.iam_user.name
}
data "external" "stdout" {
program = [ "bash", "${path.module}/encrypt.sh"]
query = {
id = aws_iam_access_key.iam_keys.id
se = aws_iam_access_key.iam_keys.secret
}
}
output "out" {
value = data.external.stdout.result
}
#!/bin/bash
eval "$(jq -r '@sh "ID=\(.id) SE=\(.se)"')"
access=$(aws kms encrypt --key-id alias/xxxx --plaintext $ID --output text --query CiphertextBlob --region us-east-1)
secret=$(aws kms encrypt --key-id alias/xxxx --plaintext $SE --output text --query CiphertextBlob --region us-east-1)
jq -n --arg a "$access" --arg s "$secret" '{"access_value":$a,"secret_value":$s}'
main
provider "aws" {
region = "us-east-1"
}
module "test1user" {
source = "./aws_user"
name = "test1"
}
output "user1_out" {
value = module.test1user.out
}
module "test2user" {
source = "./aws_user"
name = "test2"
}
output "user2_out" {
value = module.test2user.out
}
output
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Outputs:
user1_out = {
"access_value" = "AQICAHgxynd50R/zNmpbsZ8biySxfHUL9kNuyyylE5GSqkiK7wHYbkBH3jxR3zvkFLogYVAsAAAAcjBwBgkqhkiG9w0BBwagYzBhAgEAMFwGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMWhETOYT+qhL/IibfAgEQgC+kdJy7fJLZBW/AUk7YdjqDeAyymt6xBxeS1kBJIOWdVnwOujAkLG0wI+JAUqin8w=="
"secret_value" = "AQICAHgxynd50R/zNmpbsZ8biySxfHUL9kNuyyylE5GSqkiK7wFvozPjgGKbxj61aKEbxYUwAAAAhzCBhAYJKoZIhvcNAQcGoHcwdQIBADBwBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDJOwAiWgVWPtIzwURAIBEIBD7Q78YneG+/FMlkDTUnCkczf8TQBezQyMCI5cUx4qVX7iECvzx/5qAfKdy3tI4ViUGR5XV12WBvWIXj8iRN55D0jK4A=="
}
user2_out = {
"access_value" = "AQICAHgxynd50R/zNmpbsZ8biySxfHUL9kNuyyylE5GSqkiK7wFIms+isXNTAl6xWDiXcz1gAAAAcjBwBgkqhkiG9w0BBwagYzBhAgEAMFwGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMxiChWwPDGCdImUtXAgEQgC9vJfi6GaHXbqal/2nSc9FSkXEOPOsn7J+a5u8JiI2x6flBoeia9QMjVv9tOxpzYA=="
"secret_value" = "AQICAHgxynd50R/zNmpbsZ8biySxfHUL9kNuyyylE5GSqkiK7wFBLdzTFeCSk2Zv16sSHZ8bAAAAhzCBhAYJKoZIhvcNAQcGoHcwdQIBADBwBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDNGAphqIxZPthA+IkgIBEIBDAufp2xtAsfNctmnEa4grTb15MatDKJuqIB8qWCBaht563qp+RbL1aoZ8oxPYYtiU2LuHUnvbhHtWklvn2SkdSDN90w=="
}
I tested locally on Ubuntu 18.04.4 with:
Terraform v0.12.24
+ provider.aws v2.54.0
+ provider.external v1.2.0
Here is the entire code:
https://github.com/heldersepu/hs-scripts/tree/master/TerraForm/encrypt_output
Upvotes: 1