TerraformDepends_on与模块

时间:2019-10-07 18:30:00

标签: azure terraform

我是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"
  ]

2 个答案:

答案 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的输出来表达,那么我建议您最好采用这种方法,因为它会导致更易于配置跟随。但是在少数情况下,资源之间的关系无法建模为数据流,您也可以使用输出和变量在模块之间传播明确的依赖关系。