将复杂的YAML转换为.tf

时间:2018-11-29 14:49:44

标签: kubernetes yaml terraform

我有以下相对复杂的YAML:

apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: ${aws_iam_role.tf-eks-node.arn}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes

我现在想将其转换为Terraform-Kubernetes兼容的资源,该资源仅由字符串,列表和映射组成。我该怎么做呢? 我找到了一个使用连字符表示列表的LimitRange here外观示例:

resource "kubernetes_limit_range" "example" {
    metadata {
        name = "terraform-example"
    }
    spec {
        limit {
            type = "Pod"
            max {
                cpu = "200m"
                memory = "1024M"
            }
        }
        limit {
            type = "PersistentVolumeClaim"
            min {
                storage = "24M"
            }
        }
        limit {
            type = "Container"
            default {
                cpu = "50m"
                memory = "24M"
            }
        }
    }
}

我目前对mapRoles块的尝试如下:

mapRole { rolearn = "${aws_iam_role.tf-eks-node.arn}"
      username = "system:node:{{EC2PrivateDNSName}}"
      groups = ["system:bootstrappers","system:nodes"]}

这是不正确的,因为mapRoles是一个列表(因为连字符所显示的单数元素是一个list元素);但是如果它是一个列表,并且连字符后面的所有内容都是list元素,那么列表标题是什么?

使用答案中提到的想法,我试图将元数据块预先放在数据块中:

data "template_file" "map_roles" {
  template = <<EOF
- rolearn: ${var.arn}
  username: system:node:{{EC2PrivateDNSName}}
  groups:
    - system:bootstrappers
    - system:nodes
EOF

  vars {
    arn = "${var.kube-arn}"
  }
}

resource "kubernetes_config_map" "aws_auth" {
  metadata {
    name = "aws-auth"
    namespace = "kube-system"
  }
  data {
    mapRoles = "${data.template_file.map_roles.template}"
  } 
}

4 个答案:

答案 0 :(得分:1)

因此,当您在YAML中使用它时:

data:
  mapRoles: |

这意味着|之后的所有内容都是一个字符串,即mapRoles的值。我不太确定那是你想要的。如果需要列表列表,则需要这样的内容:

data:
  mapRoles:
  - rolearn: ${aws_iam_role.tf-eks-node.arn}
  - username: system:node:{{EC2PrivateDNSName}}
  - groups:
    - system:bootstrappers
    - system:nodes

这将转化为HCL:

"data" = {
  "mapRoles" = {
    "rolearn" = "${aws_iam_role.tf-eks-node.arn}"
  }

  "mapRoles" = {
    "username" = "system:node:{{EC2PrivateDNSName}}"
  }

  "mapRoles" = {
    "groups" = ["system:bootstrappers", "system:nodes"]
  }
}

答案 1 :(得分:1)

第一步是找到与您要查找的Terraform资源类型匹配的资源。 Terraform Kubernetes provider历来有些稀疏,但现在确实包含诸如Deployments和ConfigMaps之类的基本对象。 (但不是DaemonSets。)

正如@Rico在其答案中指出的那样,ConfigMap的SIGILL只是从字符串名称到字符串值的映射,您的示例使用YAML多行字符串语法。 HCL具有与shell here-documents类似的语法。要进行插值,您还需要通过template进行插值。因此,您应该可以将其翻译为:

data:

答案 2 :(得分:0)

设法对David Maze的答案进行了一些更改:

resource "kubernetes_config_map" "aws_auth" {
  metadata {
    name = "aws-auth"
    namespace = "kube-system"
  }
  data {
    mapRoles = <<EOF
- rolearn: ${var.kube-arn}
  username: system:node:{{EC2PrivateDNSName}}
  groups:
    - system:bootstrappers
    - system:nodes
EOF
  } 
}

我缺少将|-输入放入EOF块的想法。 Terraform可以直接在该块中解析变量输入,因此我什至不需要数据块就可以首先设置模板。

答案 3 :(得分:0)

作为任何希望遍历变量(使用新的for语法)的人的参考,我成功设置了以下aws-auth configmap对象:

resource "kubernetes_config_map" "aws-auth" {
  metadata {
    name = "aws-auth"
    namespace = "kube-system"
  }

  data = {
    mapRoles = local.config_map_aws_auth
  }
}

locals {
  config_map_aws_auth = yamlencode(
  concat([
    {
      "rolearn": aws_iam_role.nodes-assume-role.arn,
      "username": "system:node:{{EC2PrivateDNSName}}",
      "groups": [
        "system:bootstrappers",
        "system:nodes"
      ]
    }
  ],
  [
    for team in var.teams :
    {
      "rolearn": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/${team}-readonly",
      "username": "${team}_readonly",
      "groups": [
        "view"
      ]
    }
  ])
  )
}