टेराफॉर्म - गिनती के साथ नेस्टेड छोरों का उपयोग करें


19

मैं टेराफॉर्म में नेस्टेड लूप का उपयोग करने की कोशिश कर रहा हूं। मेरे पास दो सूची चर हैं list_of_allowed_accountsऔर list_of_images, सूची पर पुनरावृति करने list_of_imagesऔर फिर सूची में पुन: व्यवस्थित करने के लिए देख रहे हैं list_of_allowed_accounts

यहाँ मेरा टेराफ़ॉर्म कोड है।

variable "list_of_allowed_accounts" {
  type    = "list"
  default = ["111111111", "2222222"]
}

variable "list_of_images" {
  type    = "list"
  default = ["alpine", "java", "jenkins"]
}

data "template_file" "ecr_policy_allowed_accounts" {
  template = "${file("${path.module}/ecr_policy.tpl")}"

  vars {
    count = "${length(var.list_of_allowed_accounts)}"
    account_id = "${element(var.list_of_allowed_accounts, count.index)}"
  }
}

resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
  count = "${length(var.list_of_images)}"
  repository = "${element(aws_ecr_repository.images.*.id, count.index)}"
  count = "${length(var.list_of_allowed_accounts)}"
  policy = "${data.template_file.ecr_policy_allowed_accounts.rendered}"
}

यह एक बैश के बराबर है जो मैं करने की कोशिश कर रहा हूं।

for image in alpine java jenkins
do 
  for account_id in 111111111 2222222
  do 
    // call template here using variable 'account_id' and 'image'
  done
done

जवाबों:


34

Terraform के पास इस तरह के नेस्टेड पुनरावृत्ति के लिए प्रत्यक्ष समर्थन नहीं है, लेकिन हम इसे कुछ अंकगणित के साथ नकली कर सकते हैं।

variable "list_of_allowed_accounts" {
  type = "list"
  default = ["1111", "2222"]
}

variable "list_of_images" {
  type = "list"
  default = ["alpine", "java", "jenkins"]
}

data "template_file" "ecr_policy_allowed_accounts" {
  count = "${length(var.list_of_allowed_accounts) * length(var.list_of_images)}"

  template = "${file("${path.module}/ecr_policy.tpl")}"

  vars {
    account_id = "${var.list_of_allowed_accounts[count.index / length(var.list_of_images)]}"
    image      = "${var.list_of_images[count.index % length(var.list_of_images)]}"
  }
}

resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
  count = "${data.template_file.ecr_policy_allowed_accounts.count}"

  repository = "${var.list_of_images[count.index % length(var.list_of_images)]}"
  policy = "${data.template_file.ecr_policy_allowed_accounts.*.rendered[count.index]}"
}

जब से हम खाते और छवि के प्रत्येक संयोजन के लिए एक नीति टेम्पलेट बनाना चाहते हैं, countपर template_fileडेटा ब्लॉक दो को आपस है। फिर हम count.indexप्रत्येक सूची में अलग-अलग सूचकांकों से वापस आने के लिए डिवीजन और मोडुलो ऑपरेशन का उपयोग कर सकते हैं ।

चूँकि मेरे पास आपके पॉलिसी टेम्प्लेट की एक प्रति नहीं थी, इसलिए मैंने केवल एक प्लेसहोल्डर का उपयोग किया था; इस विन्यास ने इस प्रकार निम्नलिखित योजना दी:

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.0
    policy:     "policy allowing 1111 to access alpine"
    repository: "alpine"

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.1
    policy:     "policy allowing 1111 to access java"
    repository: "java"

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.2
    policy:     "policy allowing 1111 to access jenkins"
    repository: "jenkins"

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.3
    policy:     "policy allowing 2222 to access alpine"
    repository: "alpine"

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.4
    policy:     "policy allowing 2222 to access java"
    repository: "java"

+ aws_ecr_respository_policy.repo_policy_allowed_accounts.5
    policy:     "policy allowing 2222 to access jenkins"
    repository: "jenkins"

प्रत्येक पॉलिसी का उदाहरण सभी संयोजन को कवर करते हुए खाता आईडी और छवि की एक अलग जोड़ी पर लागू होता है।


2
यदि आप कॉन्फ़िगरेशन का विस्तार करना चाहते हैं, तो आपको परेशानी होगी, जैसे कि आपके संसाधनों को अलग-अलग अनुक्रमित करने के लिए एक नया खाता या / और एक छवि जोड़ें, हालांकि यदि उन्हें हटाना और फिर से बनाना एक समस्या नहीं है तो यह ठीक काम करता है।
बैलाज

1
@ justin-grote के पास उनके जवाब में एक बिंदु है: टेराफ़ॉर्म 0.12 में आपको कहीं भी विभाजित करने के लिए फ़्लोर फ़ंक्शन का उपयोग करने की आवश्यकता होगी, अन्यथा आपको आंशिक अनुक्रमणिकाओं के बारे में एक त्रुटि मिलेगी। account_id = var.list_of_allowed_accounts[floor(count.index / length(var.list_of_images))]
क्रिस्चटफेर

7

यहाँ जवाब काम करते हैं (मैंने उन्हें शुरू में इस्तेमाल किया था), लेकिन मुझे लगता है कि मेरे पास टेराफॉर्म के सेटप्रोडक्ट फ़ंक्शन का उपयोग करके एक बेहतर समाधान है। मैंने इंटरवेब के चारों ओर इसके कई उदाहरण नहीं देखे हैं, लेकिन सेटप्रोडक्ट दो सेट (या अधिक महत्वपूर्ण रूप से, दो सूचियां) लेता है और इनपुट के हर क्रमपरिवर्तन के साथ सेट की सूची तैयार करता है। मेरे मामले में मैं एसएसएम पैरामीटर बना रहा हूं:

variable "list1" {
  type    = "list"
  default = ["outer1", "outer2"]
}

variable "list2" {
  type    = "list"
  default = ["inner1", "inner2", "inner3"]
}

locals {
  product = "${setproduct(var.list1, var.list2)}"
}

resource "aws_ssm_parameter" "params" {
  count     = "${length(var.list1) * length(var.list2)}"
  name      = "/${element(local.product, count.index)[0]}/${element(local.product, count.index)[1]}"
  type      = "String"
  value     = "somevalue"
  overwrite = false
  lifecycle { ignore_changes = ["value"] }
}

यह SSM नाम के पैरामीटर बनाता है:

/outer1/inner1
/outer1/inner2
/outer1/inner3
/outer2/inner1
/outer2/inner2
/outer2/inner3

मेरा कमज़ोर दिमाग़ इसे दूसरे जवाबों में मोडुलो जादू की तुलना में थोड़ा आसान बना सकता है!


मैं आपके समाधान की कोशिश करूँगा। मैं मानता हूं कि यह कहीं बेहतर है। लेकिन आप गिनती ${length(var.list1) * length(var.list2)}के ${length(local.product)}लिए उपयोग क्यों करते हैं ?
chriscatfr

मुझे इंतजार करना होगा जब तक कि मेरा ग्राहक v0.12 का उपयोग करना शुरू न करे :( कोई आश्चर्य नहीं कि आपको कई स्रोत क्यों नहीं मिले।
chriscatfr

कोई कारण नहीं, ${length(local.product)}शायद अधिक बनाता है। इसके अलावा, मैं निश्चित रूप setproduct()से 0.12 से पहले से मौजूद हूं , (लिंक किए गए पेज के शीर्ष पर संदेश उनके सभी 0.11 डॉक्स के लिए सिर्फ एक सामान्य चेतावनी है, मुझे लगता है?)
काइल

4

FYI करें यदि कोई भी Google से यहां आता है, यदि आप टेराफॉर्म 0.12 का उपयोग कर रहे हैं, तो आपको फर्श फ़ंक्शन का उपयोग करना होगा कहीं भी आप विभाजित करते हैं, अन्यथा आपको आंशिक अनुक्रमित के बारे में एक त्रुटि मिलेगी।

account_id = var.list_of_allowed_accounts [ मंजिल (count.index / लंबाई (var.list_of_images))]


काश, मैं गणित दृष्टिकोण की कोशिश करने से पहले इस रत्न को खोजने के लिए एसओ पृष्ठ के नीचे सभी तरह से पढ़ूं। यह है कि मैंने इसे मंजिल के साथ काम करने के लिए कैसे प्राप्त किया (काउंट। लिंड / 8)। पोस्ट करने का शुक्रिया।
बाइटजुनकी

@kyle के समाधान से 0.12 सेटप्रोडक्ट () के साथ आसान लगता है।
chriscatfr

यदि आप टेराफॉर्म ०.१२ पर हैं, तो क्यों न नए जोड़े गए for, for_eachऔर / या डायनेमिक नेस्टेड ब्लॉक लैंग्वेज कंस्ट्रक्शंस का इस्तेमाल कुछ कम उलझने के लिए किया जाए?
त्रिनित्रोनएक्स

0

मूल रूप से समस्या डेटा "टेम्पलेट_फाइल" में है, खाता_एड को उस तरह से सेट नहीं किया जा सकता है जैसा आपको लगता है कि यह होगा क्योंकि आपके मामले में गिनती सिर्फ एक और संस्करण है जो कभी भी वृद्धि / परिवर्तित नहीं होती है। बस कहने के बाद से मैं देख रहा हूं कि आपका सवाल क्या है।


0

मेरे पास @ मार्टिन एटकिन्स द्वारा प्रदान किए गए उत्तर पर टिप्पणी जोड़ने के लिए पर्याप्त प्रतिष्ठा बिंदु नहीं हैं , इसलिए मैं उनके उत्तर को थोड़े संशोधन के साथ पोस्ट कर रहा हूं, जो टेराफॉर्म मुद्दे के आसपास 20567 पर काम करता है

variable "list_of_allowed_accounts" {
  type = "list"
  default = ["1111", "2222"]
}

variable "list_of_images" {
  type = "list"
  default = ["alpine", "java", "jenkins"]
}

# workaround for TF issue https://github.com/hashicorp/terraform/issues/20567
locals {
  policy_count = "${length(var.list_of_allowed_accounts) * length(var.list_of_images)}"
}

data "template_file" "ecr_policy_allowed_accounts" {
  count = "${local.policy_count}"

  template = "${file("${path.module}/ecr_policy.tpl")}"

  vars {
    account_id = "${var.list_of_allowed_accounts[count.index / length(var.list_of_images)]}"
    image      = "${var.list_of_images[count.index % length(var.list_of_images)]}"
  }
}

resource "aws_ecr_repository_policy" "repo_policy_allowed_accounts" {
  count = "${local.policy_count}"

  repository = "${var.list_of_images[count.index % length(var.list_of_images)]}"
  policy = "${data.template_file.ecr_policy_allowed_accounts.*.rendered[count.index]}"
} 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.