简体   繁体   中英

Passing Variables into a customer terraform module

I am trying to build a module in terraform that can be passed a variable map from a workspace file and lookup the variables to build an AWS CodePipeline. For those not aware, CodePipeline has a series of stages, and inside those stages are actions. My module needs to handle building a pipeline wiht any supported number of stages and actions within those stages.

Below is a part of the module I've wirtten concerned with the creation of the pipeline itself:

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             = lookup(action.value, "name", null)
          owner            = lookup(action.value, "owner", null)
          version          = lookup(action.value, "version", null)
          category         = lookup(action.value, "category", null)
          provider         = lookup(action.value, "provider", null)
          input_artifacts  = lookup(action.value, "input_artifacts", null)
          output_artifacts = lookup(action.value, "output_artifacts", null)
          configuration    = {
            BranchName           = lookup(action.value, "BranchName", null)
            PollForSourceChanges = lookup(action.value, "PollForSourceChanges", null)
            RepositoryName       = lookup(action.value, "RepositoryName", null)
            ProjectName          = lookup(action.value, "ProjectName", null)
          }
          role_arn         = lookup(action.value, "role_arn", null)
          run_order        = lookup(action.value, "run_order", null)
          region           = lookup(action.value, "region", null)
        }
      }
    }
  }

  tags = merge(
    { "Name" = "${var.prefix}-${var.name}" },
    var.tags,
  )
}

And here is an excerpt from the workspace yaml, where I pass the variables for two stages, each with an associated action:

test_pipeline_prefix: "test"
test_pipeline_name: "test-pipeline"
test_pipeline_description: "this is a POC pipeline"
test_pipeline_s3: "<<REDACTED ARN>>"
test_pipeline_codestar_arn: "<<REDACTED ARN>>"
test_pipeline_tags: [""]

test_pipeline_stages: [{
  name: "Source",
  action: [{
    name                   = "Source",
    category               = "Source",
    owner                  = "AWS"
    version                = "1",
    provider               = "CodeStarSourceConnection",
    output_artifacts       = "source_output",
    BranchName             = "main",
    PollForSourceChanges   = "false",
    RepositoryName         = "<<REDACTED REPO>>",
    region                 = "eu-west-2",
    run_order              = 1
  }]
},
{
  name: "Plan",
  action: [{
    name                   = "Plan",
    category               = "Build",
    owner                  = "AWS"
    version                = "1",
    provider               = "CodeBuild",
    input_artifacts        = "source_output",
    output_artifacts       = "build_output",
    ProjectName            = "pipeline-plan",
    run_order              = 2
  }]
}]

Finally I call it with:

module "codepipeline" {
  source         = "./modules/codepipeline"
  s3             = local.vars.test_pipeline_s3
  description    = local.vars.test_pipeline_description
  prefix         = local.vars.test_pipeline_prefix
  name           = local.vars.test_pipeline_name
  stages         = local.vars.test_pipeline_stages
  codestar_arn   = local.vars.test_pipeline_codestar_arn

  tags = {
    Environment = local.vars.env
    Terraform = "true"
  }
}

What I am hoping for it to do, is loop through the stages and actions in the "test_pipeline_stages" variable supplied, and loop through to create a stage for the Source, with an action configured to connect to the preexsiting CodeStar connection, and another stage called "Plan" that runs the CodeBuild job as it's action.

The result I'm actually getting is:

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.0.action.0.owner" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.0.action.0.provider" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.0.action.0.category" is required, but no definition was
│ found.

│ Error: Missing required argument
│ 
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.0.action.0.version" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.1.action.0.version" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.1.action.0.category" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.1.action.0.owner" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 1, in resource "aws_codepipeline" "this":
│    1: resource "aws_codepipeline" "this" {
│ 
│ The argument "stage.1.action.0.provider" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 2, in resource "aws_codepipeline" "this":
│    2:   name     = "${var.prefix}-${var.name}"
│ 
│ The argument "stage.0.action.0.name" is required, but no definition was
│ found.

│ Error: Missing required argument
│   with module.codepipeline.aws_codepipeline.this,
│   on modules/codepipeline/main.tf line 2, in resource "aws_codepipeline" "this":
│    2:   name     = "${var.prefix}-${var.name}"
│ 
│ The argument "stage.1.action.0.name" is required, but no definition was
│ found.

This suggest to me that its not indexing the variables prporly but I can't really figure the best way to proceed. Anyone got any ideas?

Thanks to responders so far - the actual fix I'll detail below, but all responses up to this point have helped me get there. I also agree that supplying null values as a fallback is not sensible; I'll look to review that.

The actual issue was simply that my workspace yaml as posted above is... not valid yaml. Once I replaced it with the below, the module began to read out the values correctly.

test_pipeline_stages: [{
  name: "Source",
  action: [{
    ActionName: "Source",
    ActionCategory: "Source",
    ActionOwner: "AWS",
    ActionVersion: "1",
    ActionProvider: "CodeStarSourceConnection",
    output_artifacts: ["source_output"],
    BranchName: "main",
    PollForSourceChanges: "false",
    RepositoryName: "REDACTED",
    ConnectionArn: "REDACTED",
    region: "eu-west-2",
    run_order: 1
  }]
},
{
  name: "Plan",
  action: [{
    ActionName: "Plan",
    ActionCategory: "Build",
    ActionOwner: "AWS",
    ActionVersion: "1",
    ActionProvider: "CodeBuild",
    input_artifacts: ["source_output"],
    output_artifacts: ["build_output"],
    ProjectName: "pipeline-plan",
    test_pipeline_ans_tags: "",
    run_order: 2
  }]
}]

owner="AWS" 后缺少逗号,请将逗号放入工作区文件中。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM