Kanji
・ Cloud engineer / freelance ・ Born in 1993 ・ Born in Ehime Prefecture / Lives in Shibuya-ku, Tokyo ・ AWS history 5 years Profile details
Table of Contents
If you need to define a custom Data Source, use the External Data Source.
For example, since CodePipeline does not have a compatible Data Source, you can use a shell script to get information.
Here is an example shell script:
#!/bin/bash eval "$(jq -r '@sh "codepipeline_name_prefix=\(.codepipeline_name_prefix)"')" pipelines=$(\ aws codepipeline \ list-pipelines \ --query "pipelines[?starts_with(name, '"${codepipeline_name_prefix}"')].name" \ --region ap-northeast-1 \ --output json ) # Key point result=$(cat << EOS { "names": $(echo "${pipelines}" | jq '@json') } EOS ) jq -n "$result"
# Key point
| jq '@json'
# Before the change result=$(cat << EOS { "names": $(echo "${pipelines}") } EOS ) # Resulting variable { "names": [ "test-pipeline01", "test-pipeline02", "test-pipeline03", "test-pipeline04", "test-pipeline05" ] }
% terraform plan data.external.aws_codepipelines: Reading... ╷ │ Error: Unexpected External Program Results │ │ with data.external.aws_codepipelines, │ on test.tf line 2, in data "external" "aws_codepipelines": │ 2: program = ["bash", "${path.module}/ListCodePipelineNames.sh"] │ │ The data source received unexpected results after executing the program. │ │ Program output must be a JSON encoded map of string keys and string values. │ │ If the error is unclear, the output can be viewed by enabling Terraform's logging at TRACE level. │ Terraform documentation on logging: https://www.terraform.io/internals/debugging │ │ Program: /bin/bash │ Result Error: json: cannot unmarshal array into Go value of type string
# After the change result=$(cat << EOS { "names": $(echo "${pipelines}" | jq '@json') } EOS ) # Resulting variable { "names": "[\"test-pipeline01\",\"test-pipeline02\",\"test-pipeline03\",\"test-pipeline04\",\"test-pipeline05\"]" }
data "external" "aws_codepipelines" { program = ["bash", "${path.module}/scripts/ListCodePipelineNames.sh"] query = { codepipeline_name_prefix = "test-pipeline0" } } # Key point output "aws_codepipelines_names" { value = jsondecode(data.external.aws_codepipelines.result["names"]) }
Create a scripts directory in the same directory as your Terraform template and reference the ListCodePipelineNames.sh script.
scripts
ListCodePipelineNames.sh
The query block allows you to specify codepipeline_name_prefix as an argument, so you can filter pipeline names by prefix. If you specify codepipeline_name_prefix , refer to only the pipeline name starting with the specified character string.
query
codepipeline_name_prefix
The key point is the output section. Use Terraform’s jsondecode() function to decode the string in the names key from the External Data Source output back into an array.
jsondecode()
names
In practice, you can use this pattern to reference other resources as well: convert arrays to strings in your script, then decode them in Terraform for further processing.