如果map变量不是空对象,则在模块调用中使用可选参数

时间:2018-06-29 11:01:52

标签: terraform

我有以下创建私有存储桶的模块。当我在模块调用中定义非空logging参数时,我只想使用日志记录:

variable "tags" {
  description = "A mapping of tags to assign to the bucket."
  type        = "map"
  default     = {}
}

variable "logging" {
  description = "A mapping of logging to assign to the bucket."
  type        = "map"
  default     = {}
}

resource "aws_s3_bucket" "private_bucket" {
  bucket  = "${var.bucket}"
  acl     = "private"
  policy  = "${data.aws_iam_policy_document.policy.json}"
  tags    = "${var.tags}"
  # logging = "${var.logging}"
  logging = "${length(keys(var.logging)) > 0 ? var.logging : null}"

  # ...

  # This block is replaced by the argument
  /* logging {
    target_bucket = "${var.logging_bucket}"
    target_prefix = "s3/${local.bucket_id}/"
  } */

  # ...
}

但是这不起作用。我这样调用模块:

module "private_bucket" {
  source = "modules/private-bucket"
  bucket = "${local.private_bucket_name}"

  tags {
    Name        = "Serverless stack private bucket"
    Environment = "${local.stage}"
  }
}

为什么不在Terraform中实现顶级if-else?有没有其他方法可以使用条件条件(而不只是值)来初始化模块/资源中的变量?

编辑:

这是我要实现的伪代码:

resource "aws_s3_bucket" "private_bucket" {
  bucket  = "${var.bucket}"
  acl     = "private"
  policy  = "${data.aws_iam_policy_document.policy.json}"
  tags    = "${var.tags}"

  # if var.logging is not an empty object,
  # then initialize logging with the object
  if (var.logging != {}) {
    logging = "${var.logging}"
  }

  # ...
}

3 个答案:

答案 0 :(得分:2)

您不能在then或else部分中使用地图。我认为Terraform 0.12可能更灵活。

我在Azure上进行了同样的操作,最终在locals {}部分中使用了合并功能,并且var.tags默认为{}:

tags    = "${merge(data.azurerm_resource_group.env.tags, var.tags)}"

然后我对资源块使用${local.tags}

答案 1 :(得分:1)

您可以从0.12版本开始使用(我不确定之前是否可能在此之前实现),实现该伪代码想要实现的方式可以通过缓慢的terraform hcl脚本实现

taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(N); // N = number of threads
taskScheduler.afterPropertiesSet();

stompClient = new WebSocketStompClient(new StandardWebSocketClient());
stompClient.setTaskScheduler(taskScheduler);
stompClient.setMessageConverter(new MappingJackson2MessageConverter()); 

WebSocketHttpHeaders handshakeHeaders = new WebSocketHttpHeaders(); // you can add additional headers here for Tomcat

// Here's the main piece other libraries were missing:
// The following request will perform both, handshake and connection
// hence it gets both sets of headers (for Tomcat and for Stomp)
ListenableFuture<StompSession> future = stompClient.connect(
            url,
            handshakeHeaders,
            new StompHeaders(),
            new CustomStompSessionHandlerAdapter(this)); // called from class that also was implementing CustomStompSessionHandlerAdapter, but this could be separate class as well.

这归因于动态工作方式。

https://www.terraform.io/docs/configuration/expressions.html#dynamic-blocks上检查动态文档中的Terraform

答案 2 :(得分:1)

如果需要在循环中进行检查,并且正在使用Terraform 0.12+,则可以按以下步骤进行操作。换句话说,现在检查 private void Cell_KeyDown(object sender, KeyEventArgs e) { DataGridCell cell = sender as DataGridCell; if (e.Key == Key.Enter) { TextBox box = cell.Content as TextBox; string strEnteredText = box.Text; } } (从Terraform 0.12开始)。

length(keys(...))