我是terraform的新手,我在模块结构上创建了自定义的Azure策略。
每个策略代表一个自定义模块。
我创建的模块之一是为创建的任何新天蓝色资源启用诊断日志。
但是,我需要一个存储帐户。 (在启用诊断设置之前,如何实现“ depends_on”?或其他任何方法?
我要先创建存储帐户,然后再创建诊断设置模块。
是在main.tf
(在其中调用所有其他模块)还是在资源(模块)内部?
感谢您的帮助!! :)
以下代码代表main.tf文件:
//calling the create storage account name
module "createstorageaccount" {
source = "./modules/module_create_storage_account"
depends_on = [
"module_enable_diagnostics_logs"
]
}
此代表创建存储帐户模块
resource "azurerm_resource_group" "management" {
name = "management-rg"
location = "West Europe"
}
resource "azurerm_storage_account" "test" {
name = "diagnostics${azurerm_resource_group.management.name}"
resource_group_name = "${azurerm_resource_group.management.name}"
location = "${azurerm_resource_group.management.location}"
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
environment = "diagnostics"
}
}
depends_on = [
"module_enable_diagnostics_logs"
]
答案 0 :(得分:10)
Terraform 13现在支持模块依赖性,当前处于发布候选阶段。
import React, { useState, useEffect } from "react";
import { Link, useHistory } from "react-router-dom";
function Register() {
const [values, setValues] = useState({});
const [errors, setErrors] = useState({});
const handleChange = (event) => {
event.persist();
setValues((values) => ({
...values,
[event.target.name]: event.target.value,
}));
};
useEffect(() => {
if (Object.keys(errors).length === 0) {
// RIDERECT TO THE /register-success ==============================
} else {
// alert("Errors found");
}
}, [errors]);
const validateForm = (values) => {
let allErrors = {};
if (!values.name) {
allErrors.name = "User name is required!";
}
if (!values.phonenumber) {
allErrors.phonenumber = "Phone number is required!";
}
if (!values.email) {
allErrors.email = "Email address is required!";
} else if (!/\S+@\S+\.\S+/.test(values.email)) {
allErrors.email = "Email address is invalid!";
}
if (!values.password) {
allErrors.password = "Please provide the password!";
}
if (!values.confirmpassword) {
allErrors.confirmpassword = "Please confirm the password is the same!";
}
return allErrors;
};
const handleSubmit = (event) => {
if (event) event.preventDefault();
setErrors(validateForm(values));
};
return (
<form onSubmit={handleSubmit}>
<div className="container login-container">
<div className="row">
<div className="col-md-6 login-form-2">
<h3>Register to post your ad</h3>
<div className="form-group">
<input
onChange={handleChange}
type="text"
className="form-control"
placeholder="Name *"
name="name"
value={values.name || ""}
/>
{errors.name && (
<div class="alert alert-danger" role="alert">
{errors.name}
</div>
)}
</div>
<div className="form-group">
<input
onChange={handleChange}
type="text"
name="phonenumber"
className="form-control"
placeholder="Phone Number *"
value={values.phonenumber || ""}
/>
{errors.phonenumber && (
<div class="alert alert-danger" role="alert">
{errors.phonenumber}
</div>
)}
</div>
<div className="form-group">
<input
onChange={handleChange}
type="text"
name="email"
className="form-control"
placeholder="Your Email *"
value={values.email || ""}
/>
{errors.email && (
<div class="alert alert-danger" role="alert">
{errors.email}
</div>
)}
</div>
<div className="form-group">
<input
onChange={handleChange}
type="password"
name="password"
className="form-control"
placeholder="Password *"
value={values.password || ""}
/>
{errors.password && (
<div class="alert alert-danger" role="alert">
{errors.password}
</div>
)}
</div>
<div className="form-group">
<input
onChange={handleChange}
type="password"
className="form-control"
placeholder="Confirm Password *"
name="confirmpassword"
value={values.confirmpassword || ""}
/>
{errors.confirmpassword && (
<div class="alert alert-danger" role="alert">
{errors.confirmpassword}
</div>
)}
</div>
<div className="form-group">
{/* <Link to="/register-success"> */}
<input type="submit" className="btnSubmit" value="Register" />
{/* </Link> */}
</div>
<div className="form-group btnForgetPwd">
By clicking "Register" you are agreeing to our{" "}
<Link target="_blank" to="/terms-and-conditions">
<a
style={{
color: "white",
textDecoration: "underline",
fontStyle: "italic",
}}
>
Terms and Conditions
</a>
</Link>
</div>
</div>
<div className="col-md-6 login-form-1">
<div className="login-logo">
<img src="https://image.ibb.co/n7oTvU/logo_white.png" alt="" />
</div>
{/* Register */}
<h3>Already a member? Login</h3>
<div className="form-group text-center pt-5">
<Link to="/login">
<input type="button" className="btnSubmit" value="Login" />
</Link>
</div>
</div>
</div>
</div>
</form>
);
}
export default Register;
答案 1 :(得分:0)
在大多数情况下,由于您的引用,必需的依赖项会自动出现。如果一种资源的配置直接或间接引用另一种资源,则Terraform会自动推断它们之间的依赖性,而无需显式的depends_on
。
之所以可行,是因为模块变量和输出也是依赖关系图中的节点:如果子模块资源引用了var.foo
,则它间接依赖于该变量的值所依赖的任何事物。
在罕见的情况下,自动依赖检测不足,您仍然可以利用以下事实:模块变量和输出是依赖图中的节点,以创建间接的显式依赖,如下所示:
variable "storage_account_depends_on" {
# the value doesn't matter; we're just using this variable
# to propagate dependencies.
type = any
default = []
}
resource "azurerm_storage_account" "test" {
name = "diagnostics${azurerm_resource_group.management.name}"
resource_group_name = "${azurerm_resource_group.management.name}"
location = "${azurerm_resource_group.management.location}"
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
environment = "diagnostics"
}
# This resource depends on whatever the variable
# depends on, indirectly. This is the same
# as using var.storage_account_depends_on in
# an expression above, but for situations where
# we don't actually need the value.
depends_on = [var.storage_account_depends_on]
}
调用此模块时,可以将storage_account_depends_on
设置为包含要确保在存储帐户之前创建的对象的任何表达式:
module "diagnostic_logs" {
source = "./modules/diagnostic_logs"
}
module "storage_account" {
source = "./modules/storage_account"
storage_account_depends_on = [module.diagnostic_logs.logging]
}
然后在diagnostic_logs
模块中,可以为logging
输出配置间接依赖关系,以完成模块之间的依赖关系链接:
output "logging" {
# Again, the value is not important because we're just
# using this for its dependencies.
value = {}
# Anything that refers to this output must wait until
# the actions for azurerm_monitor_diagnostic_setting.example
# to have completed first.
depends_on = [azurerm_monitor_diagnostic_setting.example]
}
如果您的关系可以通过传递实际的值来表示,例如通过包含id的输出来表达,那么我建议您最好采用这种方法,因为它会导致更易于配置跟随。但是在少数情况下,资源之间的关系无法建模为数据流,您也可以使用输出和变量在模块之间传播明确的依赖关系。