在像New Relic这样的监控工具中使用Terraform

基本上,這是關於思考方式的筆記。這個內容是根據我過去在NRUG上做的演講所整理的,可以說是下面演講的再現文章。

 

这篇文章是为什么样的人而写的?

想要使用Terraform,但是使用者的技能水平各不相同,但是希望通过IaC将代码模块化。特别是在代码创建者和代码执行者之间的技能水平有差异的情况下。

简介和背景

很多人想要通过代码来管理基础架构环境,比如AWS、Google Cloud和Azure等。即使环境发生故障,只要有数据和代码,环境就可以轻松恢复,所以我们希望尽可能通过代码来进行管理。

然而,如果使用Terraform来管理代码,最新执行环境的信息将由tfstate文件进行管理,处理该文件相对来说有些棘手。具体而言,即使在对原始Terraform代码进行修改的情况下,如果环境与代码无法很好地适配,Terraform代码将出错并无法执行。

一旦发生这种情况,你将面临到同时查看tfstate文件、Terraform代码和当前配置,以进行调试的苦行。如果是从头开始编写代码的人,他们可能会基本明白意图。然而,对于初次接触Terraform代码和tfstate文件的人来说,调试是相当困难的,如果他们只是具有“Terraform?那是什么好吃的东西?”水平的知识,首先需要学习Terraform是什么,而且如果处于运营岗位的话,无法不说这是非常低效的。

为什么要讲这样的话呢,因为我实际运营的环境正处在这种状态。当然,如果要进行设置的标准化,不仅高级人员,低级人员也需要以相同的质量完成设置。但是明显可以看到,如果存在tfstate文件,实现这一点将变得困难,因此首先需要考虑如何解决这个问题。

我在下一章会告诉你们我是如何解决这个问题的。

你是如何解决这个任务的?

首先,当遇到问题时,我们首先考虑解决该问题的方法。在这种情况下,我们查阅了Teraform的规格、文档以及New Relic的文档,以寻找解决方案的方法,并调查了不同方法的优缺点。

手法特徴メリットデメリットTerraformHashiCorp社が提供するIaCツール・ドキュメントがしっかり
・AWSやGoogleCloudなど他のIaCでも知識転用できる・Terraform側で機能拡張されないと、技術的に出来ないこともあるNerdGraph・一般的なGraphQLに基づいてコードが書ける
・必要最低限のクエリ項目で設定や更新ができる・NewRelic GraphiQLというサポートツールがあり、簡単にクエリの作成・実行できる・クエリ内容の詳細についてドキュメントが少なかったり英語しかないREST APIREST(Representational State Transfer)の原則に基づいて設計されたAPIのこと・昔からあるため、困ってもネット検索などで情報にたどり着きやすい
・REST API Explorerで利用可能なAPIの一覧が確認できる・後方互換の位置付けのため、新規学習する場合の推奨はNerdGraph

由于在设定New Relic之前的假设条件下创建了表格,因此与一般讨论有所不同。

在处理这次事情时,我们首先考虑了使用New Relic的哪种方法。我们决定选择使用Terraform作为工具,因为相比使用较难的NerdGraph和Rest API,使用Terraform的门槛较低。

在这之后,我们遇到了如何管理的难题。正如前面所述,tfstate文件的管理对于仅仅是操作员的维护人员来说门槛太高了,尽管对于代码创建者来说可能还可以。考虑到操作的情况,我们也思考了哪种运营模式更适合。

運用パターンユースケース案件毎に環境や設定内容に大きくバラつきがあるが、コードメンテナンスできるスキルの人がいて、障害発生時にコードから環境復旧できることにメリットがある・AWSなど、再構築が必要な可能性があるインフラ基盤
・リソースの定義はコードの中に全て埋め込みコード自体をメンテナンスする・New Relicなど、再構築の可能性を無視できる監視基盤
・リソースの定義はある程度コードの中に埋め込み、変更箇所はパラメータなどを使って埋め合わせする案件毎の環境や設定内容は多少のバラつきはあるものの、コードメンテナンスできない人でも自動設定の恩恵を受けられ、コードを使いまわすことで設定ミスを軽減することにメリットがある

在以上的模板中,根据我们希望在不忽视下一次重建的可能性的情况下,采用一种不会使操作员执行困难操作并确保质量的方法来处理监视基础设施问题的目标,我们决定使用terraform的tfstate重新设置(state rm)命令。如果涉及到主要内容,tstate rm命令通常在资源的生命周期结束并在现有代码中被删除时使用,相关文档如下所示。

Terraform 状态的主要功能是跟踪配置中的资源实例地址以及它们所代表的远程对象之间的绑定关系。通常情况下,Terraform 会根据执行计划所产生的操作来自动更新状态,例如删除远程对象的绑定关系等。
通过使用 terraform state rm,您可以在不首先销毁现有的远程对象的情况下,删除其绑定关系。这在非常罕见的情况下使用,以确保在对象继续存在于远程系统中的同时,Terraform 实际上会“忘记”该对象。
引用自官方网站文档
https://developer.hashicorp.com/terraform/cli/commands/state/rm

在进行资源清除时使用该命令可能会有点棘手,因为它与通常的流程稍有不同,但具体取决于用途。总结本次目的和风险如下所示。

    • コードに付随するtfstateを使わずに常に新規の設定を流すこと

 

    • 何か問題が発生した場合は再度コードを流し直してリソースの再作成を行うこと

 

    現在の設定内容(state)を使いまわすことを捨てたとしても、運用上の影響が小さいこと

换句话说,选择使用一次性而不是持续保持设置是因为前者有更多的优点,特别是对于可能影响实际服务(如AWS或Google Cloud)的资源。我们可能不希望像上面那样使用一次性的方式。这是因为虽然可以仅对更新的资源进行设置,不直接影响现有环境,但更改现有资源会直接影响服务。然而,对于像New Relic的监测工具的条件和策略设置,又会如何呢?尽管对监测可能会有影响,但它不会直接影响服务,这也成为采用这种运作方式的原因之一。

另外,我們將按照以下的實際設定進行執行。

terraform init
  ↓
terraform plan
  ↓
terraform apply
  ↓
terraform state rm

样本设定

只要你把下面的内容视为一个例子,我们把发表资料进行了大幅删除并进行了本文改写,现在一起公开。

变量.tf

# コマンド実行時に指定する変数
variable "api_key" {
  type = string
  default = ""
}
variable "account_id" {
  type = string
  default = ""
}
variable "condition_name" {
  type = string
  default = ""
}
variable "policy_name" {
  type = string
  default = ""
}

主要.tf

# New Relicプロバイダー設定
terraform {
  required_version = "~> 1.0"
  required_providers {
    newrelic = {
      source  = "newrelic/newrelic"
      version = "~> 3.12.0"
    }
  }
}

provider "newrelic" {
    api_key    = var.api_key
    account_id = var.account_id
    region = "US"
}

# ポリシー設定
resource "newrelic_alert_policy" "NewRelicPolicy" {
  # Configration policy name
  name = var.policy_name
  # Incident preference
  incident_preference = "PER_POLICY"
}

# コンディション設定
resource "newrelic_nrql_alert_condition" "NewRelicCondition" {
  account_id = var.account_id
  policy_id = newrelic_alert_policy.NewRelicPolicy.id
  type = "static"
  name = var.condition_name
  enabled = true
  violation_time_limit_seconds = 259200
  nrql {
    query = "SELECT average(`host.cpuPercent`) FROM Metric FACET entity.guid, host.hostname"
  }
  critical {
    operator = "above"
    threshold = 85
    threshold_duration = 300
    threshold_occurrences = "all"
  }
  fill_option = "none"
  fill_value  = null,

  aggregation_window = 60
  aggregation_method = "event_flow"
  aggregation_delay = 120
}

最后

工具就是工具。如果能减轻使用者的负担,个人认为不需要过于拘泥于使用方式,不妨尝试不同的方法,就像不必局限在定规传统上一样。

希望这篇文章能对某人有所帮助。

消息

我在这个博客上写了很多关于AWS的信息。虽然我还没有确定Qiita的方向,但我打算在这边写一些完全不同于公司博客中无法写的技术内容,或者干脆写一些与技术无关的其他话题。如果可以的话,我希望您也能一起查看下面的博客。

 

广告
将在 10 秒后关闭
bannerAds