自定义地形模块

Custom terraform module

我尝试创建一个自定义模块来在使用输出时加密我们的访问密钥和秘密访问密钥。因此,当构建运行时,它会尝试在使用 kms 加密后打印出访问密钥。

但目前当我们使用此模块创建多个用户时,它只是打印第一个用户的访问密钥和其他用户的密钥。

有人请建议我应该如何解决这个问题。使用 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"])
}

我测试了这个模块,我正在尝试创建两个用户,test1,test2 ..这是输出,它是两个用户的相同访问密钥和秘密密钥

地形

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=

我在尝试重现代码时重构了很多代码...
终于搞定了。

我觉得可疑的是你的 > encrypted_access_key 稍后再读回来,我们可以将它加载到 var 中并在没有中间文件的情况下使用它,这就是我所做的。


模块

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}'


主要

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
}


输出

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=="
}

我在 Ubuntu 18.04.4 上进行了本地测试:

Terraform v0.12.24
+ provider.aws v2.54.0
+ provider.external v1.2.0

完整代码如下:
https://github.com/heldersepu/hs-scripts/tree/master/TerraForm/encrypt_output