【AWS】terraformで書いたコードをCheckovでセキュリティチェックしよう
前回は、AWSの自分のアカウントをterraformに連携する方法を解説してきましたが、今回は、terraformにコードを書いて、Checkovでセキュリティチェックする手順を解説します。
Terraformを使ったインフラ構築は、コードとしての管理と自動化が進む一方で、セキュリティの懸念も増しています。AWS環境に最適な構成を維持しつつ、リスクを未然に防ぐ方法を学び、堅牢なインフラを構築しましょう。
ハンズオンの流れを解説
今回は、上の構成図のAWSリソースをterraformで構築し、そのコードをCheckovでセキュリティチェックします。具体的に作成する主なリソースはVPCと2台のEC2とELBです。
- terraformでコードを記述しAWSリソースの構築
- Checkovでセキュリティチェック
- チェック結果を確認する
この3ステップでセキュリティチェックを行います。
terraformでAWSインフラを構築
まずは、terraformでコードを記述し、リソースを構築します。terraformとローカルPCの連携方法や基本的な使い方については、前回の記事をご確認ください。
まずは、今回作成するAWSは大きく分けてVPCとEC2とELBであるため、backend.tfファイルがあるフォルダと同フォルダ内に下記3つのファイルを作成します。(前回の記事で作成したファイルは削除してください。)
- vpc.tf
- ec2.tf
- elb.tf
そして、vpc.tfをVSCodeで開き、下記コードを記述します。
# VPCの作成 resource “aws_vpc” “OpsToday-vpc” { cidr_block = “10.0.0.0/16” tags = { Name = “OpsToday-vpc” } } # サブネットの作成 resource “aws_subnet” “OpsToday-private_subnet1” { vpc_id = aws_vpc.OpsToday-vpc.id cidr_block = “10.0.1.0/24” availability_zone = “ap-northeast-1a” map_public_ip_on_launch = false tags = { Name = “OpsToday-private-subnet-1” } } resource “aws_subnet” “OpsToday-private_subnet2” { vpc_id = aws_vpc.OpsToday-vpc.id cidr_block = “10.0.2.0/24” availability_zone = “ap-northeast-1c” map_public_ip_on_launch = false tags = { Name = “OpsToday-private-subnet-2” } } # セキュリティグループの作成 (EC2用) resource “aws_security_group” “OpsToday-ec2_sg” { vpc_id = aws_vpc.OpsToday-vpc.id ingress { from_port = 22 to_port = 22 protocol = “tcp” cidr_blocks = [“0.0.0.0/0”] } egress { from_port = 0 to_port = 0 protocol = “-1” cidr_blocks = [“0.0.0.0/0”] } tags = { Name = “OpsToday-ec2-sg” } } |
同様に、ec2.tfファイルをVSCodeで開き下記のコードを入力します。
# EC2インスタンスの作成 resource “aws_instance” “OpsToday-ec2_instance1” { ami = “ami-0ef29ab52ff72213b” instance_type = “t2.micro” subnet_id = aws_subnet.OpsToday-private_subnet1.id security_groups = [aws_security_group.OpsToday-ec2_sg.name] tags = { Name = “OpsToday-ec2-instance-1” } } resource “aws_instance” “OpsToday-ec2_instance2” { ami = “ami-0ef29ab52ff72213b” instance_type = “t2.micro” subnet_id = aws_subnet.OpsToday-private_subnet2.id security_groups = [aws_security_group.OpsToday-ec2_sg.name] tags = { Name = “OpsToday-ec2-instance-2” } } |
最後に、elb.tfファイルもVSCodeで開いて下記コードを入力します。
# ELBの作成 resource “aws_lb” “OpsToday-elb” { name = “OpsToday-elb” internal = true load_balancer_type = “application” security_groups = [aws_security_group.OpsToday-ec2_sg.id] subnets = [aws_subnet.OpsToday-private_subnet1.id, aws_subnet.OpsToday-private_subnet2.id] tags = { Name = “OpsToday-elb” } } # ターゲットグループの作成 resource “aws_lb_target_group” “OpsToday-target_group” { name = “OpsToday-tg” port = 80 protocol = “HTTP” vpc_id = aws_vpc.OpsToday-vpc.id health_check { enabled = true interval = 30 path = “/” timeout = 5 healthy_threshold = 5 unhealthy_threshold = 2 } } # ターゲットグループへのターゲットの登録 resource “aws_lb_target_group_attachment” “OpsToday-target1” { target_group_arn = aws_lb_target_group.OpsToday-target_group.arn target_id = aws_instance.OpsToday-ec2_instance1.id port = 80 } resource “aws_lb_target_group_attachment” “OpsToday-target2” { target_group_arn = aws_lb_target_group.OpsToday-target_group.arn target_id = aws_instance.OpsToday-ec2_instance2.id port = 80 } # リスナーの設定 resource “aws_lb_listener” “OpsToday-elb_listener” { load_balancer_arn = aws_lb.OpsToday-elb.arn port = 80 protocol = “HTTP” default_action { type = “forward” target_group_arn = aws_lb_target_group.OpsToday-target_group.arn } } |
ここまで入力できたら、ターミナルで下記コマンドを入力します。
terarfrom plan |
planを実行し、エラーが出なければ、
terarfrom apply |
を実行し、リソースを構築します。
Checkovでセキュリティチェック
リソースの構築ができたら、Checkovでセキュリティチェックを行います。
セキュリティチェックのためには、ターミナルで下記コマンドを実行します。
checkov -d . |
このコマンドは、セキュリティツール「Checkov」を使って、Terraform コードのセキュリティチェックを実行するためのコマンドです。「-d .」の部分はオプションで、チェックするディレクトリを指定します。ドットは、カレントディレクトリを意味しています。
下記の画像のような出力がされていればチェック成功です。
上記画像内の赤枠部分について詳しく解説します。
「Passed checks」は、チェック対象のリソースがセキュリティポリシーに適合しており、問題がないことを示しています。
「Failed checks」は、セキュリティポリシーに違反している設定や構成が見つかったことを示します。15件のチェックが失敗しているため、AWSリソースがセキュリティ基準を満たしていない状態です。
「Skipped checks」は、スキップされたチェック項目を意味します。checkovでは明示的にあるリソースのセキュリティチェックを実施しないという指定が可能です。今回は指定していないため0件となっています。
チェック結果を確認する
checkovのチェック結果は、Passed、Failed、Skippedの順に上から出力されています。今回は、Failedとなっている「CKV_AWS_126」のチェック項目を確認します。
下記、画像内の2行目を見ると、作成したEC2インスタンス1について問題があると表示されています。Guideに表示されているURLを開きエラーの詳細を確認してみましょう。
URLを開くとAWS EC2 インスタンスの詳細監視が無効とのエラーが表示されました。ここで重要度やサブタイプ等も確認できます。
下にスクロールすると、エラーの説明や修正方法についても確認できます。今回は、説明を省きますが、自身でコードを修正してみましょう。修正後は、コードを再度セキュリティチェックし、「CKV_AWS_126」がPassedになるか確認してください。
Checkovのセキュリティチェックをスキップする方法
Checkovを使用する中で、誤検知や、一時的な例外など、様々な理由で特定のチェックをスキップしたいケースが発生します。そのような場合のスキップ方法を解説します。
今回解説するのは、チェック項目、CKV_AWS_126:AWS EC2 インスタンスの詳細監視が無効になっています。のチェックをスキップさせる方法です。
# EC2インスタンスの作成 resource “aws_instance” “OpsToday-ec2_instance1” { # checkov:skip=CKV_AWS_126:EC2インスタンスの詳細監視が無効になっています ami = “ami-0ef29ab52ff72213b” instance_type = “t2.micro” subnet_id = aws_subnet.OpsToday-private_subnet1.id security_groups = [aws_security_group.OpsToday-ec2_sg.name] tags = { Name = “OpsToday-ec2-instance-1” } } |
ec3.tfファイルの3行目に「# checkov:skip=CKV_AWS_126」のコメントを追加します。 「EC2インスタンスの詳細監視が無効になっています」の部分は、スキップする理由を記述しています。スキップの内容を後から見返したり、チームメンバーがコードを見て分かりやすいように記載しておきましょう。
まとめ
今回の記事では、2部にわたってterraformのコードをcheckovでセキュリティチェックする方法を解説しました。
インフラのコード化が進む中で、コードレベルでセキュリティを担保する重要性はますます高まっています。Checkovのようなツールを導入することで、潜在的なリスクを早期に検出し、堅牢で安全な環境を構築することが可能です。
ぜひ、今回紹介した手順を参考に、日々のインフラ運用や開発プロセスにセキュリティチェックを組み込んでみてください。小さな積み重ねが、大きなセキュリティインシデントを未然に防ぐ力になります。今後も、効率的かつ安全なインフラ運用を目指して、ツールや手法を活用していきましょう!