【Azure】terraformで書いたコードをCheckovでセキュリティチェックしよう
前回は、Azureの自分のアカウントをterraformに連携する方法を解説してきましたが、今回の後編では、terraformにコードを書いて、Checkovでセキュリティチェックする手順を解説します。
Terraformを使ったインフラ構築は、コードとしての管理と自動化が進む一方で、セキュリティの懸念も増しています。Azure環境に最適な構成を維持しつつ、リスクを未然に防ぐ方法を学び、堅牢なインフラを構築しましょう。
流れを解説
今回は、上の構成案のAzureリソースをterraformで構築し、そのコードをCheckovでセキュリティチェックします。具体的に作成する主なリソースはVPCと2台のEC2とELBです。
- terraformでコードを記述しAzureリソースの構築
- Checkovでセキュリティチェック
- チェック結果を確認する
この3ステップでセキュリティチェックを行います。
terraformでAzureインフラを構築
まずは、terraformでコードを記述し、リソースを構築します。terraformとローカルPCの連携方法や基本的な使い方については、第1章をご確認ください。
まずは、今回作成するAzureは大きく分けてVPCとEC2とELBであるため、backend.tfファイルがあるフォルダと同フォルダ内に下記3つのファイルを作成します。(前回作成したファイルは削除してください。)
- azure-network.tf
- azure-vm.tf
- azure-lb.tf
そして、azure-network.tfをVSCodeで開き、下記コードを記述します。
# リソースグループの作成 resource “azurerm_resource_group” “terraform-test” { name = “azure-terraform-rg” location = “japaneast” } # 仮想ネットワークの作成 resource “azurerm_virtual_network” “terraform-test” { name = “terraform-test-vnet” address_space = [“10.0.0.0/16”] location = azurerm_resource_group.terraform-test.location resource_group_name = azurerm_resource_group.terraform-test.name } # プライベートサブネット1の作成 resource “azurerm_subnet” “subnet1” { name = “subnet1” resource_group_name = azurerm_resource_group.terraform-test.name virtual_network_name = azurerm_virtual_network.terraform-test.name address_prefixes = [“10.0.1.0/24”] } # プライベートサブネット2の作成 resource “azurerm_subnet” “subnet2” { name = “subnet2” resource_group_name = azurerm_resource_group.terraform-test.name virtual_network_name = azurerm_virtual_network.terraform-test.name address_prefixes = [“10.0.2.0/24”] } |
同様に、azure-vm.tfファイルをVSCodeで開き下記のコードを入力します。
# ネットワークインターフェース1の作成 resource “azurerm_network_interface” “terraform-test1” { name = “terraform-test-nic1” location = azurerm_resource_group.terraform-test.location resource_group_name = azurerm_resource_group.terraform-test.name ip_configuration { name = “internal” subnet_id = azurerm_subnet.subnet1.id private_ip_address_allocation = “Dynamic” } } # ネットワークインターフェース2の作成 resource “azurerm_network_interface” “terraform-test2” { name = “terraform-test-nic2” location = azurerm_resource_group.terraform-test.location resource_group_name = azurerm_resource_group.terraform-test.name ip_configuration { name = “internal” subnet_id = azurerm_subnet.subnet2.id private_ip_address_allocation = “Dynamic” } } # 仮想マシン1の作成 resource “azurerm_linux_virtual_machine” “vm1” { name = “terraform-test-vm1” location = azurerm_resource_group.terraform-test.location resource_group_name = azurerm_resource_group.terraform-test.name size = “Standard_B1s” admin_username = “adminuser” admin_password = “Password1234!” # ここは適切な値に置き換えてください network_interface_ids = [azurerm_network_interface.terraform-test1.id] disable_password_authentication = “false” os_disk { caching = “ReadWrite” storage_account_type = “Standard_LRS” } source_image_reference { publisher = “Canonical” offer = “UbuntuServer” sku = “18.04-LTS” version = “latest” } } # 仮想マシン2の作成 resource “azurerm_linux_virtual_machine” “vm2” { name = “terraform-test-vm2” location = azurerm_resource_group.terraform-test.location resource_group_name = azurerm_resource_group.terraform-test.name size = “Standard_B1s” admin_username = “adminuser” admin_password = “Password1234!” # ここは適切な値に置き換えてください network_interface_ids = [azurerm_network_interface.terraform-test2.id] disable_password_authentication = “false” os_disk { caching = “ReadWrite” storage_account_type = “Standard_LRS” } source_image_reference { publisher = “Canonical” offer = “UbuntuServer” sku = “18.04-LTS” version = “latest” } } |
最後に、azure-lb.tfファイルもVSCodeで開いて下記コードを入力します。
# パブリックIPアドレスの作成 (ロードバランサー用) resource “azurerm_public_ip” “opstoday-terraform-ip” { name = “opstoday-terraform-pip” location = azurerm_resource_group.OpsToday-terraform-rg.location resource_group_name = azurerm_resource_group.OpsToday-terraform-rg.name allocation_method = “Static” sku = “Standard” } # ロードバランサーの作成 resource “azurerm_lb” “OpsToday-terraform-lb” { name = “OpsToday-terraform-lb” location = azurerm_resource_group.OpsToday-terraform-rg.location resource_group_name = azurerm_resource_group.OpsToday-terraform-rg.name sku = “Standard” frontend_ip_configuration { name = “PublicIPAddress” public_ip_address_id = azurerm_public_ip.opstoday-terraform-ip.id } } # バックエンドプールの作成 resource “azurerm_lb_backend_address_pool” “OpsToday-terraform-bap” { name = “OpsToday-terraform-bap” loadbalancer_id = azurerm_lb.OpsToday-terraform-lb.id } # プローブの作成 resource “azurerm_lb_probe” “OpsToday-terraform-probe” { name = “OpsToday-terraform-probe” loadbalancer_id = azurerm_lb.OpsToday-terraform-lb.id protocol = “Tcp” port = 80 } # ロードバランサーのルールの作成 resource “azurerm_lb_rule” “OpsToday-terraform-lbrule” { name = “OpsToday-terraform-lbrule” loadbalancer_id = azurerm_lb.OpsToday-terraform-lb.id protocol = “Tcp” frontend_port = 80 backend_port = 80 frontend_ip_configuration_name = “PublicIPAddress” backend_address_pool_ids = [azurerm_lb_backend_address_pool.OpsToday-terraform-bap.id] probe_id = azurerm_lb_probe.OpsToday-terraform-probe.id } |
ここまで入力できたら、ターミナルで下記コマンドを入力します。
terarfrom plan |
planを入力し、エラーが出なければ、
terarfrom apply |
を実行することでリソースを構築できます。
Checkovでセキュリティチェック
リソースの構築ができたら、Checkovで作成した環境のセキュリティチェックを行います。
セキュリティチェックのためには、ターミナルで下記コマンドを実行します。
checkov -d . |
このコマンドは、セキュリティツール「Checkov」を使って、Terraform コードのセキュリティチェックを実行するためのコマンドです。「-d .」の部分はオプションで、チェックするディレクトリを指定します。ドットは、カレントディレクトリを意味しています。
下記の画像のような出力がされていればチェック成功です。
上記画像内の赤枠部分について詳しく解説します。
「Passed checks」は、チェック対象のリソースがセキュリティポリシーに適合しており、問題がないことを示しています。
「Failed checks」は、セキュリティポリシーに違反している設定や構成が見つかったことを示します。8件のチェックが失敗しているため、Google Cloudリソースがセキュリティ基準を満たしていない状態です。
「Skipped checks」は、スキップされたチェック項目を意味します。checkovでは明示的にあるリソースのセキュリティチェックを実施しないという指定が可能です。今回は指定していないため0件となっています。
チェック結果を確認する
checkovのチェック結果は、Passed、Failed、Skippedの順に上から出力されています。今回は、Failedの一番最後に表示されている「CKV_AZURE_1」のチェック項目を確認します。
下記、画像内の2行目と3行目を見るとazure-vm.tfの50-71行に記載している「vm2」に課題があると表示されています。Guideに表示されているURLを開きエラーの詳細を確認してみましょう。
URLを開くと「Azure 仮想マシン (Linux) が SSH キーを使用して認証されない」のエラーが表示されました。ここで重要度やサブタイプ等も確認できます。
下にスクロールすると、エラーの説明や修正方法についても確認できます。今回は、説明を省きますが、自身でコードを修正してみましょう。修正後は、コードを再度セキュリティチェックし、「CKV_AZURE_1」がPassedになるか確認してください。
Checkovのセキュリティチェックをスキップする方法
Checkovを使用する中で、誤検知や、一時的な例外など、様々な理由で特定のチェックをスキップしたいケースが発生します。そのような場合のスキップ方法を解説します。
今回解説するのは、チェック項目、「CKV_AZURE_1」のチェックをスキップさせる方法です。
# 仮想マシン2の作成 resource “azurerm_linux_virtual_machine” “opstoday-terraform-vm2” { # checkov:skip=CKV_AZURE_1:SSH キーを使用していない name = “opstoday-terraform-vm2” location = azurerm_resource_group.OpsToday-terraform-rg.location resource_group_name = azurerm_resource_group.OpsToday-terraform-rg.name size = “Standard_B1s” admin_username = “adminuser” admin_password = “Password1234!” # ここは適切な値に置き換えてください network_interface_ids = [azurerm_network_interface.opstoday-terraform-nic2.id] disable_password_authentication = “false” os_disk { caching = “ReadWrite” storage_account_type = “Standard_LRS” } source_image_reference { publisher = “Canonical” offer = “UbuntuServer” sku = “18.04-LTS” version = “latest” } |
azure-vm.tfファイルの3行目にコメントを追加します。
「#checkov:skip=CKV_CKV_AZURE_1」と入力するだけで、スキップが可能です。
「SSH キーを使用していない」の部分は、スキップする理由を記述しています。スキップの内容を後から見返したり、チームメンバーがコードを見て分かりやすいように記載しておきましょう。
まとめ
今回の記事では、AWS編、Google Cloud編に引き続き、前後編にわたってAzure編のterraformのコードをcheckovでセキュリティチェックする方法を解説しました。
terraformを使って、AzureでVMやネットワーク、ロードバランサーを作成する方法からCheckovでのセキュリティチェック方法やスキップする手順などクラウドのリソースを管理するうえで重要な内容を解説しています。インフラ管理担当者は、本記事の内容はしっかりと抑えておきましょう。