I have the following, relatively complicated piece of 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
I now want to translate this into a Terraform-Kubernetes compatible resource, which consists exclusively of String, Lists and Maps. How do I do this? I found an example of how a LimitRange would look here using hyphens to signify a list:
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"
}
}
}
}
My current try for the mapRoles block is as follows:
mapRole { rolearn = "${aws_iam_role.tf-eks-node.arn}"
username = "system:node:{{EC2PrivateDNSName}}"
groups = ["system:bootstrappers","system:nodes"]}
This is not correct because mapRoles is a list (because its singular element is a list element as demonstrated by the hyphen); but if it is a list, and everything after the hyphen is the list element, what is the list title?
using the idea mentioned in an answer, I tried to put the metadata block in a data-block beforehand:
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}"
}
}
Managed to make it work with some changes to David Maze's answer:
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
}
}
The idea of putting the |-input into an EOF-block is what I was missing. Terraform can resolve variable input directly in that block, so I didn't even need a data block to set the template up first.
So when you have this in YAML:
data:
mapRoles: |
it means that everything after the |
is a string that is the value of mapRoles
. I'm not really sure that's what you want. If you want lists of lists you would want something like this:
data:
mapRoles:
- rolearn: ${aws_iam_role.tf-eks-node.arn}
- username: system:node:{{EC2PrivateDNSName}}
- groups:
- system:bootstrappers
- system:nodes
This would translate into HCL to this:
"data" = {
"mapRoles" = {
"rolearn" = "${aws_iam_role.tf-eks-node.arn}"
}
"mapRoles" = {
"username" = "system:node:{{EC2PrivateDNSName}}"
}
"mapRoles" = {
"groups" = ["system:bootstrappers", "system:nodes"]
}
}
The first step is to find a Terraform resource type that matches what you're looking for. The Terraform Kubernetes provider has historically been a little sparse but now does include basic objects like Deployments and ConfigMaps. (Not DaemonSets, though.)
As @Rico notes in their answer, the data:
of a ConfigMap is just a map from string name to string value, and your example uses a YAML multi-line string syntax. HCL has a different syntax that looks like shell here-documents. To do the interpolation you also need to feed it through a template. So you should be able to translate this to:
data "template_file" "map_roles" {
template = <<EOF
- rolearn: ${arn}
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes
EOF
vars {
arn = ${aws_iam_role.tf-eks-node.arn}
}
}
resource "kubernetes_config_map" "aws_auth" {
metadata {
name = "aws-auth"
namespace = "kube-system"
}
data {
mapRoles = ${data.template_file.map_roles}
}
}