Open5

Terraformを使ってGoogle Cloud Runにコンテナをデプロイするまでの手順

korallekoralle

*.tfを書いていく準備

1. Neovimに*.tfをTerrafromのファイルとして認識させる

↓をNeovimの設定のどこかに書いておけばOK

vim.cmd("autocmd BufNewFile,BufRead *.tf set filetype=terraform")

2. Lspとしてterraform-lsを使う

terraform-lspterraform-lsのどっちをLSPとして使う?っていう話があるけど、

  1. terraform-lspは2022/05でメンテが止まっている(2023/03/04観測時点)
  2. terraform-lsはHashiCorp公式がメンテしている

という理由からterraform-lsを選択。
まぁそもそもあんまり機能の違いがわかっていないという話もあり...

保存時の自動Formatをnull-lsを経由したterraform fmtを使ってやりたいので、
terraform-ls側のFormatは無効化しつつこういう設定にした

require("mason-lspconfig").setup_handlers({
    function()
      require("lspconfig").terraformls.setup({
        on_attach = function()
            client.server_capabilities.document_formatting = false
            client.server_capabilities.document_range_formatting = false
        end
        capabilities = require("cmp_nvim_lsp").default_capabilities(),
        filetypes = {
          "terraform",
          "tf",
        },
      })
    end,
  })
end

3. tfsecをインストールする

null-ls側に設定するterraformのbuiltinを調べていたら、tfsecを発見した。

https://github.com/aquasecurity/tfsec

tfsec uses static analysis of your terraform code to spot potential misconfigurations.
tfsecは、terraformのコードを静的解析して、潜在的な設定ミスを発見します。

良さそう

Features
☁️ Checks for misconfigurations across all major (and some minor) cloud providers
⛔ Hundreds of built-in rules
🪆 Scans modules (local and remote)
➕ Evaluates HCL expressions as well as literal values
↪️ Evaluates Terraform functions e.g. concat()
🔗 Evaluates relationships between Terraform resources
🧰 Compatible with the Terraform CDK
🙅 Applies (and embellishes) user-defined Rego policies
📃 Supports multiple output formats: lovely (default), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
🛠️ Configurable (via CLI flags and/or config file)
⚡ Very fast, capable of quickly scanning huge repositories
🔌 Plugins for popular IDEs available (JetBrains, VSCode and Vim)
🏡 Community-driven - come and chat with us on Slack!

うーん読めば読むほど入れ得っぽい。

Macを使っているので、Homebrewで一発。

brew install tfsec

4. null-lsに設定を追加

この内容をNeovimのどっかで読み込む

-- lua/null-ls/init.lua
local nls = require("null-ls")
local lspconfig = require("lspconfig")

local completion = nls.builtins.completion
local diagnostics = nls.builtins.diagnostics
local formatting = nls.builtins.formatting
local code_actions = nls.builtins.code_actions

-- コード保存時の自動フォーマットを有効化
local function sync_formatting_on_save(client, buffer_number)
  if client.supports_method("textDocument/formatting") then
    vim.api.nvim_clear_autocmds({ group = augroup, buffer = buffer_number })
    vim.api.nvim_create_autocmd("BufWritePre", {
      group = augroup,
      buffer = buffer_number,
      callback = function()
        vim.lsp.buf.format(nil, 3000)
      end,
    })
  end
end

nls.setup({
  diagnostics.terraform_validate,
  diagnostics.tfsec,
  formatting.terraform_fmt,
  on_attach = function(client, buffer_number)
    sync_formatting_on_save(client, buffer_number)
  end,
  capabilities = require("cmp_nvim_lsp").default_capabilities(),
})

結果

いい感じ!

korallekoralle

Google Cloud Storage(GCS)でtfstateを管理する準備

↓を見ながらやる

https://cloud.google.com/docs/terraform/resource-management/store-state

GCSにtfstate管理用のBucketを作る

これは手動でやる。Console上でポチポチすればOK。

Terraform Backendの情報をmain.tfに追記

結果こうなるはず
(バケット、USリージョンで作っちゃった...)

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.51.0"
    }
  }

  backend "gcs" {
    bucket = "<bucket-name>"
    prefix = "terraform/state"
  }
}

provider "google" {
  credentials = file("<credentials-json-file-name>")

  project = "<project-name>"
  region  = "asia-northeast1"
}