Terraform,从null_resource,local-exec和AWS CLI获取输出

big*_*7bb 8 amazon-web-services aws-cli amazon-cognito terraform

我正在使用Terraform在AWS中自动提供Cognito Identity Pools.AWS提供商尚不支持Cognito,所以我一直在使用null_resource和local-exec来调用AWS CLI.

我有以下资源:

resource "null_resource" "create-identitypool" {
    provisioner "local-exec" {
        command = "aws cognito-identity create-identity-pool --identity-pool-name terraform_identitypool --no-allow-unauthenticated-identities --developer-provider-name login.terraform.myapp"
    }
}
Run Code Online (Sandbox Code Playgroud)

它给出了以下输出:

null_resource.create-identitypool (local-exec): {
null_resource.create-identitypool (local-exec):     "IdentityPoolId": "eu-west-1:22549ad3-1611-......",
null_resource.create-identitypool (local-exec):     "AllowUnauthenticatedIdentities": false,
null_resource.create-identitypool (local-exec):     "DeveloperProviderName": "login.terraform.myapp",
null_resource.create-identitypool (local-exec):     "IdentityPoolName": "terraform_identitypool"
null_resource.create-identitypool (local-exec): }
null_resource.create-identitypool: Creation complete
Run Code Online (Sandbox Code Playgroud)

下一步是将一些我已经创建的角色添加到身份池:

resource "null_resource" "attach-policies-identitypool" {
    provisioner "local-exec" {
        command = "aws cognito-identity set-identity-pool-roles --identity-pool-id ${null_resource.create-identitypool.IdentityPoolId} --roles authenticated=authroleXXX,unauthenticated=unauthroleXXX"
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我无法提取IdentityPoolId,$ {null_resource.create-identitypool.IdentityPoolId},以便在第二个资源中使用.我理解null_resource没有输出属性,所以如何从命令行输出中获取此JSON对象.我还想使用tirggers并运行aws cognito-identity list-identity-pools和可能的delete-identity-pool来使这一切都可重复,我也需要输出.

有任何想法吗?如果我在其他地方错过了这些信息,我会道歉.我也在Terraform邮件列表上问了这个问题,但我想我会尝试更广泛的受众.

蒂姆,谢谢

Pau*_*yng 6

Terraform 0.8中有一个新的数据源,external它允许您运行外部命令并提取输出。请参阅data.external

数据源应用于检索Cognito数据,而不是执行数据。由于这是Terraform数据源,因此不应有任何副作用。


Unb*_*ess 6

为此可以使用外部数据源

下面是一个完整的示例。


假设您想要运行 AWS CLI 命令来检索有关某个 EC2 实例的信息(这仅用于演示目的),例如 AMI ID 和密钥名称。

首先,创建一个 bash 脚本 ( get_instance_details.sh) 来获取并返回所需的信息:

#!/bin/bash
INSTANCE_ID=$1

INSTANCE_DETAILS=$(aws ec2 describe-instances --instance-id $INSTANCE_ID)
AMI_ID=$(echo $INSTANCE_DETAILS | jq -r '.Reservations[].Instances[].ImageId')
KEY_NAME=$(echo $INSTANCE_DETAILS | jq -r '.Reservations[].Instances[].KeyName')

jq -n --arg ami_id "$AMI_ID" --arg key_name "$KEY_NAME" '{"ami_id":$ami_id,"key_name":$key_name}'
Run Code Online (Sandbox Code Playgroud)

然后,创建一个data运行脚本的源:

data "external" "get_instance_details" {
  program = ["bash", "get_instance_details.sh","${aws_instance.my_instance.id}"]
}
Run Code Online (Sandbox Code Playgroud)

terraform console然后您可以使用(之后)检查结果terraform apply

> data.external.get_instance_details.result.ami_id
"ami-..."
> data.external.get_instance_details.result.key_name
"my-ec2-key..."
Run Code Online (Sandbox Code Playgroud)

显然,您可以使用这些标识符作为其他资源的属性。


Mam*_*mun 5

保罗的回答是正确的。然而,外部数据只有在 shell 脚本以 JSON 格式发送回数据时才起作用,这需要更多的工作。

因此,Matti Paksula 为此制作了一个模块。(https://github.com/matti/terraform-shell-resource)。

使用该模块,我们可以获得任何 shell 脚本本地执行调用的 stdout、stderr 和退出状态。

这是一个 main.tf 文件示例。您可以以任何方式修改它,以运行您想要的任何命令,包括您问题中的命令。

#  Defining a variable , we will feed to the shell script
variable "location" { default = "us-central1-f" }


# Calling Matti's Module
module "shell_execute" {
  source  = "github.com/matti/terraform-shell-resource"
  command = "./scripts/setenv.sh"
}


# Creating a shell script on the fly
resource "local_file" "setenvvars" {
  filename = "./scripts/setenv.sh"
  content  = <<-EOT
    #!/bin/bash
    export LOCATION=${var.modinput_location}
    echo LOCATION $LOCATION
  EOT
}

#  Now, we get back the output of the script
output "shell_stdout" {
  value = module.shell_execute.stdout
}

#  Now, we get back if there are any errors
output "shell_stderr" {
  value = module.shell_execute.stderr
}

#  Now, we get back exit status of the script
output "shell_exitstatus" {
  value = module.shell_execute.exitstatus
}
Run Code Online (Sandbox Code Playgroud)

  • shell_execute 在 linux_amd64 上适用于 v1.0.5 (2认同)
  • 请注意安全隐患 - `terraform-shell-resource` 模块使用临时文件来捕获输出。 (2认同)