我正在创建一个创建IAM角色的模块。消费者将提供类似的东西
role_cross_account_config = [{
account_ids = ["1111112222222","333332222222"]
external_id = "yesss"
require_mfa = true
},{
account_ids = ["845666666666"]
external_id = "dsaa"
require_mfa = false
},{
account_ids = ["7777788888888","6666444444444"]
external_id = "dsaa"
require_mfa = false
},{
account_ids = ["555564444444"]
external_id = "yesss"
require_mfa = true
},{
account_ids = ["3333399997777"]
external_id = null
require_mfa = true
},{
account_ids = ["64558888888","24331551111","77788644433"]
external_id = "yesss"
require_mfa = true
}]
我正在尝试将external_id
和require_mfa
的所有具有相同值的对象合并到所有account_ids
的对象中
所以我应该得到这样的东西
new_list = [{
account_ids = ["1111112222222","333332222222","555564444444","64558888888","24331551111","77788644433"]
external_id = "yesss"
require_mfa = true
},{
account_ids = ["845666666666","7777788888888","6666444444444"]
external_id = "dsaa"
require_mfa = false
},{
account_ids = ["3333399997777"]
external_id = null
require_mfa = true
}]
我能够做到这一点,但仅对于那些require_mfa
和external_id = null
具有相同值的人来说,那就是使用for循环和if else逻辑。我竭尽全力寻找解决办法,但到目前为止仍未提出任何解决方案
注意:
require_mfa
是布尔值external_id
是字符串external_id
可以具有任何值。意味着消费者可以使用他们选择的external_id
输入尽可能多的对象。我正在尝试合并所有对external_id和require_mfa共享相同值的对象。答案 0 :(得分:1)
我实际上能够找到解决方案,因此我将其发布,这样有一天可能会有益于某人。
首先,我不得不更改模块,以便它将为每个account_id
接受一个对象,而不是在每个对象中都有一个account_ids
的列表。像这样:
role_cross_account_config = [{
account_ids = "333332222222"
external_id = "yesss"
require_mfa = true
},{
account_ids = "333332222222"
external_id = "yesss"
require_mfa = true
},{
account_ids = "845666666666"
external_id = "dsaa"
require_mfa = false
},{
account_ids = "7777788888888"
external_id = "dsaa"
require_mfa = false
},{
account_ids = "6666444444444"
external_id = "dsaa"
require_mfa = false
},{
account_ids = "555564444444"
external_id = "yesss"
require_mfa = true
},{
account_ids = "3333399997777"
external_id = null
require_mfa = true
},{
account_ids = "64558888888"
external_id = "yesss"
require_mfa = true
},{
account_ids = "24331551111"
external_id = "yesss"
require_mfa = true
},{
account_ids = "77788644433"
external_id = "yesss"
require_mfa = true
}]
我使用局部变量来解决它。由于我试图按两个条件进行分组,并且其中一个条件是布尔值,因此,如果将列表分为两个不同的列表,一个用于布尔值true,一个用于布尔值false。然后,我处理每个列表,并使用"for"
和"if"
按第二个条件分组。我必须使用distinct,因为这样会导致重复很多。
NOTE:
这种方法在任何编程语言中都将被视为垃圾,因为它浪费时间和资源,但这是我在Terraform中仍然可以找到的唯一方法,因为它仍然是有限的语言。我相信随着Terraform的不断发展和发展,这种事情在不久的将来会变得容易得多。
locals {
list_no_mfa = [for s in var.role_cross_account_config :
{
external_id = s.external_id
require_mfa = s.require_mfa
account_ids = s.account_ids
}
if s.require_mfa != true]
no_mfa_same_id = distinct([for s in local.list_no_mfa :
{
external_id = s.external_id
require_mfa = s.require_mfa
account_ids = [for i in local.list_no_mfa : i.account_ids if i.external_id == s.external_id]
}
])
list_mfa = [for s in var.role_cross_account_config :
{
external_id = s.external_id
require_mfa = s.require_mfa
account_ids = s.account_ids
}
if s.require_mfa != false]
mfa_same_id = distinct([for s in local.list_mfa :
{
external_id = s.external_id
require_mfa = s.require_mfa
account_ids = [for i in local.list_mfa : i.account_ids if i.external_id == s.external_id]
}
])
combined_list = concat(local.no_mfa_same_id, local.mfa_same_id)
}
现在local.combined_list
是期望的结果。
答案 1 :(得分:0)
在回答问题之前要注意的一件事,您的键/值对被写为变量,因此您实际上无法像使用对象键值对那样访问它们。因此,话虽如此,如果将那些'='转换为':',则可以执行以下操作:
new_list = [{
account_ids: [],
external_id: "yesss",
require_mfa: true
},{
account_ids: [],
external_id: "dsaa",
require_mfa: false
},{
account_ids: [],
external_id: null,
require_mfa: false
}]
role_cross_account_config = [{
account_ids : ["1111112222222","333332222222"],
external_id : "yesss",
require_mfa : true
},{
account_ids : ["845666666666"],
external_id : "dsaa",
require_mfa : false
},{
account_ids : ["7777788888888","6666444444444"],
external_id : "dsaa",
require_mfa : false
},{
account_ids : ["555564444444"],
external_id : "yesss",
require_mfa : true
},{
account_ids : ["3333399997777"],
external_id : null,
require_mfa : true
},{
account_ids : ["64558888888","24331551111","77788644433"],
external_id : "yesss",
require_mfa : true
}]
for (let i = 0; i < role_cross_account_config.length; i++) {
if (role_cross_account_config[i]['external_id'] === 'yesss' && role_cross_account_config[i]['require_mfa'] === true) {
for (let j = 0; j < role_cross_account_config[i]['account_ids'].length; j++) {
new_list[0]['account_ids'].push(role_cross_account_config[i]['account_ids'][j])
}
}
}
console.log(new_list)
您可以使用else添加到'if'语句中,以查找其他组合,例如“ dsaa”和“ false”,“ dsaa”和“ true”。无论您要比较哪种组合。
答案 2 :(得分:-1)
现在,我了解您需要什么,我为您找到了解决方案。您将需要创建一个函数使其正常运行。我之前提到的相同问题仍然适用,您需要使它成为真正的对象键/值对,并带有':'而不是'='。
基本上,代码遍历对象数组'role_cross ...',并将“外部id”和“ require_mfa”与数组中的所有其他对象进行比较。如果找到两者的匹配项,则将这些值存储在称为“ checkedVal”的单独数组中。函数“ alreadyChecked”在迭代是否已检查组合(例如:yess和true)之前检查“ checkedVal”,如果已检查,则移至下一个要比较的对象。
一旦通过所有检查,它将在“ new_list”数组中使用预定义键创建一个新的“对象”。这样就可以很容易地将适当的值添加到数组中新创建的对象中。如果您有任何疑问,请告诉我。
我认为应该为您解决。这是代码:
let new_list = [{}]
let checkedVal = [['init1','init2']]
let nextNewEntry = 0
role_cross_account_config = [{
account_ids : ["1111112222222","333332222222"],
external_id : "yesss",
require_mfa : true
},{
account_ids : ["845666666666"],
external_id : "dsaa",
require_mfa : false
},{
account_ids : ["7777788888888","6666444444444"],
external_id : "dsaa",
require_mfa : false
},{
account_ids : ["555564444444"],
external_id : "yesss",
require_mfa : true
},{
account_ids : ["3333399997777"],
external_id : null,
require_mfa : true
},{
account_ids : ["64558888888","24331551111","77788644433"],
external_id : "yesss",
require_mfa : true
}]
function alreadyChecked(external, mfa) {
for (k=0; k < checkedVal.length; k++) {
if (checkedVal[k][0] === external && checkedVal[k][1] === mfa) {
console.log('Already checked this combination '+external+' '+mfa)
return true
} else if (k === checkedVal.length -1) {
console.log('Have not checked this yet '+external+' '+mfa)
return false
}
}
}
for (let i = 0; i < role_cross_account_config.length; i++) {
if (alreadyChecked(role_cross_account_config[i]['external_id'],role_cross_account_config[i]['require_mfa'])===false) {
console.log('moving forward with the iterations')
nextNewEntry++;
checkedVal[nextNewEntry-1] = []
checkedVal[nextNewEntry-1].push(role_cross_account_config[i]['external_id'],role_cross_account_config[i]['require_mfa'])
new_list[nextNewEntry-1] = {
account_ids: [],
external_id: '',
require_mfa: ''
}
for (let j = 0; j < role_cross_account_config.length; j++) {
if (role_cross_account_config[i]['external_id'] === role_cross_account_config[j]['external_id'] && role_cross_account_config[i]['require_mfa'] === role_cross_account_config[j]['require_mfa']) {
for (let h = 0; h < role_cross_account_config[j]['account_ids'].length; h++) {
new_list[nextNewEntry-1]['account_ids'].push(role_cross_account_config[j]['account_ids'][h]);
new_list[nextNewEntry-1]['external_id'] = role_cross_account_config[i]['external_id'];
new_list[nextNewEntry-1]['require_mfa'] = role_cross_account_config[i]['require_mfa'];
}
}
}
}
}
console.log(new_list)
console.log(checkedVal)