Terraform动态创建CodePipeline阶段遇两类错误求助
我已修复stages变量问题,terraform plan执行成功,但执行terraform apply时出现新错误:
creating CodePipeline (dev-mgt-mytest-cp): ValidationException: 2
validation errors detected: Value at
'pipeline.stages.1.member.actions.1.member.configuration' failed to
satisfy constraint: Map value must satisfy constraint: [Member must
have length less than or equal to 50000, Member must have length
greater than or equal to 1]; Value at
'pipeline.stages.2.member.actions.1.member.configuration' failed to
satisfy constraint: Map value must satisfy constraint: [Member must
have length less than or equal to 50000, Member must have a length
greater than or equal to 1]
我手动创建无动态阶段的同类型Pipeline可正常运行,不确定是否为Terraform限制,寻求帮助。同时已更新可用变量代码供参考。
================================================================
我首次尝试用Terraform创建动态CodePipeline阶段,参考网络资料编写代码后,传递stages变量时出现错误:
The given value is not suitable for the module.test_code.var.stages
declared at │ ../dynamic_pipeline/variables.tf:60,1-18: all list
elements must have the same │ type.
第一部分
核心需求是向Pipeline传递动态阶段,解决该问题后将添加新的动态变量。以下是动态模块、模块的variables.tf、测试代码及变量配置:
dynamic_pipeline.tf
resource "aws_codepipeline" "cp_plan_pipeline" { name = "${local.cp_name}-cp" role_arn = var.cp_run_role artifact_store { type = var.cp_artifact_type location = var.cp_artifact_bucketname } dynamic "stage" { for_each = [for s in var.stages : { name = s.name action = s.action } if(lookup(s, "enabled", true))] content { name = stage.value.name dynamic "action" { for_each = stage.value.action content { name = action.value["name"] owner = action.value["owner"] version = action.value["version"] category = action.value["category"] provider = action.value["provider"] run_order = lookup(action.value, "run_order", null) namespace = lookup(action.value, "namespace", null) region = lookup(action.value, "region", data.aws_region.current.name) input_artifacts = lookup(action.value, "input_artifacts", []) output_artifacts = lookup(action.value, "output_artifacts", []) configuration = { RepositoryName = lookup(action.value, "repository_name", null) ProjectName = lookup(action.value, "ProjectName", null) BranchName = lookup(action.value, "branch_name", null) PollForSourceChanges = lookup(action.value, "poll_for_sourcechanges", null) OutputArtifactFormat = lookup(action.value, "ouput_format", null) } } } } } }
variables.tf
#--------------------------------------------------------------------------------------------------- # General #--------------------------------------------------------------------------------------------------- variable "region" { type = string description = "The AWS Region to be used when deploying region-specific resources (Default: us-east-1)" default = "us-east-1" } #--------------------------------------------------------------------------------------------------- # CODEPIPELINE VARIABLES #--------------------------------------------------------------------------------------------------- variable "cp_name" { type = string description = "The name of the codepipline" } variable "cp_repo_name" { type = string description = "Then name of the repo that will be used as a source repo to trigger builds" } variable "cp_branch_name" { type = string description = "The branch of the repo that will be watched and used to trigger deployment" default = "development" } variable "cp_artifact_bucketname" { type = string description = "name of the artifact bucket where articacts are stored." default = "Codepipeline-artifacts-s3" } variable "cp_run_role" { type = string description = "S3 artifact bucket name." } variable "cp_artifact_type" { type = string description = "" default = "S3" } variable "cp_poll_sources" { description = "Trigger that lets codepipeline know that it needs to trigger build on change" type = bool default = false } variable "cp_ouput_format" { type = string description = "Output artifacts format that is used to save the outputs" default = "CODE_ZIP" } variable "stages" { type = list(object({ name = string action = list(object({ name = string owner = string version = string category = string provider = string run_order = number namespace = string region = string input_artifacts = list(string) output_artifacts = list(string) repository_name = string ProjectName = string branch_name = string poll_for_sourcechanges = bool output_format = string })) })) description = "This list describes each stage of the build" } #--------------------------------------------------------------------------------------------------- # ENVIORNMENT VARIABLES #--------------------------------------------------------------------------------------------------- variable "env" { type = string description = "The environment to deploy resources (dev | test | prod | sbx)" default = "dev" } variable "tenant" { type = string description = "The Service Tenant in which the IaC is being deployed to" default = "dummytenant" } variable "project" { type = string description = "The Project Name or Acronym. (Note: You should consider setting this in your Enviornment Variables.)" } #--------------------------------------------------------------------------------------------------- # Parameter Store Variables #--------------------------------------------------------------------------------------------------- variable "bucketlocation" { type = string description = "location within the S3 bucket where the State file resides" }
第二部分
以上为Pipeline核心代码,以下是测试用模块代码,也是触发初始错误的地方:
main.tf
module test_code { source = "../dynamic_pipeline" cp_name = "dynamic-actions" project = "my_project" bucketlocation = var.backend_bucket_target_name cp_run_role = "arn:aws:iam::xxxxxxxxx:role/cp-deploy-service-role" cp_repo_name = var.repo stages = [{ name = "part 1" action = [{ name = "Source" owner = "AWS" version = "1" category = "Source" provider = "CodeCommit" run_order = 1 repository_name = "my_target_repo" branch_name = "main" poll_for_sourcechanges = true output_artifacts = ["CodeWorkspace"] ouput_format = var.cp_ouput_format }] }, { name = "part 2" action = [{ run_order = 1 name = "Combine_Binaries" owner = "AWS" version = "1" category = "Build" provider = "CodeBuild" namespace = "BIN" input_artifacts = ["CodeWorkspace"] output_artifacts = ["CodeSource"] ProjectName = "test_runner" }] }] }
测试代码对应的变量文件:
variables.tf
#--------------------------------------------------------------------------------------------------- # CODEPIPELINE VARIABLES #--------------------------------------------------------------------------------------------------- variable "cp_branch_name" { type = string description = "The branch of the repo that will be watched and used to trigger deployment" default = "development" } variable "cp_poll_sources" { description = "Trigger that lets codepipeline know that it needs to trigger build on change" type = bool default = false } variable "cp_ouput_format" { type = string description = "Output artifacts format that is used to save the outputs. Values can be CODEBUILD_CLONE_REF or CODE_ZIP" default = "CODE_ZIP" } variable "backend_bucket_target_name" { type = string description = "The folder name where the state file is stored for the pipeline" default = "dynamic-test-pl" } variable "repo" { type = string description = "name of the repo the pipeine is managing" default = "my_target_repo" }
我首次接触Terraform的列表和映射用法,确定初始错误与变量传递方式有关,希望得到排查指导与解决方案。
内容的提问来源于stack exchange,提问作者Maxamis4

