Help us understand the problem. What is going on with this article?

TerraformでKubernetesのリソース(ConfigMapやSecretなど)を管理する

More than 1 year has passed since last update.

TerraformはAWSなどのIaaS上でインフラを構築、管理するためのツールとしてよく使われてます。
一方、公式プラグインとしてKubernetesのリソースを管理するためのProviderが提供されており、これを使ってKubernetesのリソースを管理すると結構便利だったので紹介します。

kubectlでリソースを直接いじるのに比べると、

  • terraform planでDryRunできる
  • その際、もちろん既存のリソースとの差分を見ることができる
  • リソース同士の参照(Docker RegistryのSecretをPodから見るとか)をコード上で表現でき、参照が壊れてると実行前にエラーにできる
  • 変数や関数、モジュールを使用して定義を共通化できる
  • terraform destroyで全部なかったことにできる

あたりがメリットでしょうか。

では、以下Mac上にインストールしたminikubeにローカルのterraformからアクセスするというローカルに閉じた環境で、実際にKubernetesのリソースを管理する様をつらつらと書いていきます。

この記事で使用したterraformのプロジェクトは、以下にPushしているので併せてご参照ください。

https://github.com/literalice/terraform-kubernetes-demo

minikubeのインストールは超絶簡単なので、以下を参考にインストールしてみていただければと思います。

https://github.com/kubernetes/minikube

Kubernetes Providerの設定

terraformからKubernetesのクラスタを設定するために、本来は以下を参考に、apiserverのURLやユーザー名などの認証情報を設定する必要があります。

https://www.terraform.io/docs/providers/kubernetes/

ただ、minikube.kube/configに認証情報を書き込み、またterraformのKubernetes Providerはデフォルトで.kube/configを見るので、minikube環境にローカルからアクセスする場合は単に宣言だけで大丈夫です。

ここでは、terraform-kubernetes-demoというディレクトリを作成して、以下のファイルを作成することにします。

provider "kubernetes" {}

terraform initを実行することでKubernetes Providerがダウンロードされ、kubernetes-provider-demoディレクトリに設定されます。

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "kubernetes" (1.0.0)...

ConfigMapをTerraformで管理する

まず、ConfigMapを管理してみます。現時点のKubernetes Providerだと、このConfigMapとSecretの管理が一番便利に感じるところです。

tfファイルは、以下のようになります。

resource "kubernetes_config_map" "infra" {
  metadata {
    name = "infra-env"
  }

  data {
    db_host = "dbhost:5432"
    cache_host = "cache:6379"
  }
}

さて、上記ファイルを適当なファイル名で作成し、terraform planでDry Runしてみます。
すると、以下のように作成されようとしているConfigMapが表示されます。

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + kubernetes_config_map.infra
      id:                          <computed>
      data.%:                      "2"
      data.cache_host:             "cache:6379"
      data.db_host:                "dbhost:5432"
      metadata.#:                  "1"
      metadata.0.generation:       <computed>
      metadata.0.name:             "infra-env"
      metadata.0.namespace:        "default"
      metadata.0.resource_version: <computed>
      metadata.0.self_link:        <computed>
      metadata.0.uid:              <computed>


Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

実際に作成する前に内容を確認できるのがいいですね。

terraform applyとすると、実際にkubernetesクラスタにこのConfigMapが作成されます。

terraform apply

# kubernetes_config_map.infra: Creating...
#   data.%:                      "" => "2"
#   data.cache_host:             "" => "cache:6379"
#   data.db_host:                "" => "dbhost:5432"
#   metadata.#:                  "" => "1"
#   metadata.0.generation:       "" => "<computed>"
#   metadata.0.name:             "" => "infra-env"
#   metadata.0.namespace:        "" => "default"
#   metadata.0.resource_version: "" => "<computed>"
#   metadata.0.self_link:        "" => "<computed>"
#   metadata.0.uid:              "" => "<computed>"
# kubernetes_config_map.infra: Creation complete after # 0s (ID: default/infra-env)

# Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

kubectl describe cm infra-env

# Name:         infra-env
# Namespace:    default
# Labels:       <none>
# Annotations:  <none>

# Data
# ====
# cache_host:
# ----
# cache:6379
# db_host:
# ----
# dbhost:5432
# Events:  <none>

さらに、以下のようにConfigMapを変更してみます。

resource "kubernetes_config_map" "infra" {
  metadata {
    name = "infra-env"
  }

  data {
    db_host = "dbhost2:5432" # 変更する
    cache_host = "cache:6379"
  }
}

ここでterraform planを行うと、AWS Providerのような他Provider同様、差分が表示されます。

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  ~ kubernetes_config_map.infra
      data.db_host: "dbhost:5432" => "dbhost2:5432"


Plan: 0 to add, 1 to change, 0 to destroy.

------------------------------------------------------------------------

このように、実際に変更される前に、どのようにConfigMapが変更されるのか確認できます。
差分OKであれば、 terraform apply で差分を適用します。

terraform apply

# kubernetes_config_map.infra: Refreshing state... (ID: default/infra-env)
# kubernetes_config_map.infra: Modifying... (ID: default/infra-env)
#   data.db_host: "dbhost:5432" => "dbhost2:5432"
# kubernetes_config_map.infra: Modifications complete # after 0s (ID: default/infra-env)

SecretをTerraformで管理する

ConfigMap同様、Secretもterraformで管理できます。kubectlで作るのに比べてbase64エンコードもしてくれたりで直感的にSecretを作成できます。

まず、tfファイルを作成します。

resource "kubernetes_secret" "basic_auth" {
  metadata {
    name = "basic-auth"
  }

  data {
    username = "admin"
    password = "Admin"
  }

  type = "kubernetes.io/basic-auth"
}

terraform applyを実行すると、上記内容でSecretが作られます。base64でエンコードする必要もありません。

kubernetes_secret.basic_auth: Creating...
  data.%:                      "" => "2"
  data.password:               "<sensitive>" => "<sensitive>"
  data.username:               "<sensitive>" => "<sensitive>"
  metadata.#:                  "" => "1"
  metadata.0.generation:       "" => "<computed>"
  metadata.0.name:             "" => "basic-auth"
  metadata.0.namespace:        "" => "default"
  metadata.0.resource_version: "" => "<computed>"
  metadata.0.self_link:        "" => "<computed>"
  metadata.0.uid:              "" => "<computed>"
  type:                        "" => "kubernetes.io/basic-auth"
kubernetes_secret.basic_auth: Creation complete after 0s (ID: default/basic-auth)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

では、少しこのtfファイルを変更してみます。ついでに、変数も使ってみます。

variable "basicPassword" {
}

resource "kubernetes_secret" "basic_auth" {
  metadata {
    name = "basic-auth"
  }

  data {
    username = "admin"
    password = "${var.basicPassword}"
  }

  type = "kubernetes.io/basic-auth"
}
TF_VAR_basicPassword=aaa terraform plan

# An execution plan has been generated and is shown below.
# Resource actions are indicated with the following symbols:
#   ~ update in-place

# Terraform will perform the following actions:

#   ~ kubernetes_secret.basic_auth
#       data.password: <sensitive> => <sensitive> (attribute changed)


# Plan: 0 to add, 1 to change, 0 to destroy.

このように、terraformであれば変数や参照、関数が利用できるので、構成を共有するのが楽そうですね。

Kubernetes ProviderのSecretリソースは、ファイルやテンプレートからSecretを作成することもできるので、Docker Registryの認証情報をKubernetesに設定するときなどに便利です。

https://www.terraform.io/docs/providers/kubernetes/r/secret.html

後片付け

terraform destroyで、上記で作成したリソースを全て削除できます。

terraform destroy


# kubernetes_config_map.infra: Refreshing state... (ID: default/infra-env)
# kubernetes_secret.basic_auth: Refreshing state... (ID: default/basic-auth)

# An execution plan has been generated and is shown below.
# Resource actions are indicated with the following symbols:
#   - destroy

# Terraform will perform the following actions:

#   - kubernetes_config_map.infra

#   - kubernetes_secret.basic_auth


# Plan: 0 to add, 0 to change, 2 to destroy.

# Do you really want to destroy?
#   Terraform will destroy all your managed infrastructure, as shown above.
#   There is no undo. Only 'yes' will be accepted to confirm.

#   Enter a value: yes

# kubernetes_config_map.infra: Destroying... (ID: default/infra-env)
# kubernetes_secret.basic_auth: Destroying... (ID: default/basic-auth)
# kubernetes_config_map.infra: Destruction complete after 0s
# kubernetes_secret.basic_auth: Destruction complete after 0s

# Destroy complete! Resources: 2 destroyed.

まとめ

Kubernetes Providerでは、その他にもServiceやPod、NamespaceやPVCなど、様々なリソースを管理できます(現時点ではPodはあってもDeploymentがないのが痛い)。

https://www.terraform.io/docs/providers/kubernetes/

terraformは差分が発生したことをコマンドのexit codeで知ることができたり、べき等性のあるコマンドでリソースを管理できたりとCIに組み込むのにとても便利な作りなので、インフラをJenkinsなどで管理しているのであれば一度Kubernetes Providerを試してみてはいかがでしょうか。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした