Snyk IaCでTerraform管理外のリソースを検出してみた
こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)
今回は、snyk iac describe
コマンドを利用して、Terraformで作っていないリソースを検出してみようと思います。
Snyk IaC describeコマンドとは
snyk iac describe
では次の2つを検出できるコマンドです。Terraformのtfstate内のリソースとクラウドプロバイダーの実際のリソースを比較して検出するため、CloudFormationで書かれたファイルには使えません。
- ドリフト(現在の状態とtfstateとの差異を検出)
- 該当リソースがIaC(Terraform)で管理されているかどうかを検出
今回は2つめの該当リソースがIaC(Terraform)で管理されているかどうかを検出してみようと思います。
1については以下のブログで取り上げているので、興味があればご覧いただけると嬉しいです。
やってみた
というわけで、今回は私のAWSアカウントがどれほどTerraformでの管理されているかを確認してみようと思います。実行環境にはtfstateファイルとAWS環境を閲覧する権限が必要です。
以後、Terraformで管理されているリソースをマネージドなリソース、管理されていないリソースをアンマネージドなリソースとして分別します。
マネージドなリソースの検知
「--only-managed または --drift」オプションを利用することで、Terraformで管理されているリソースの状態を把握できます。
次の例ではTerraformで管理されたリソースの中でドリフトが発生したリソースが表示されています。
また、「--from」オプションでワイルドカードを使用することで、指定したS3バケット内のtfstateファイルを全て検査対象に含めることもできます。
※複数指定する場合は、--from="tfstate+s3://tf-cm-takakuni/vpc1/terraform.tfstate,tfstate+s3://tf-cm-takakuni/vpc1/terraform.tfstate"でも指定できます。
takakuni.shinnosuke@my_env % snyk iac describe --only-managed --from="tfstate+s3://tf-cm-takakuni/*/*" Scanned states (9) Scan duration: 34s Provider version used to scan: 3.19.0. Use --tf-provider-version to use another version. Snyk Scanning Infrastructure As Code Discrepancies... Info: Resources under IaC, but different to terraform states. Resolve: Reapply IaC resources or update into terraform. Changed resources: 9 State: tfstate+s3://terraform-cm-takakuni/snyk_iac/terraform.tfstate [ Changed Resources: 1 ] Resource Type: aws_vpc ID: vpc-XXXXXXXXXXXXXXXX ~ arn: arn:aws:ec2:ap-northeast-1:622809842341:vpc/vpc-XXXXXXXXXXXXXXXX => arn:aws:ec2:ap-northeast-1::vpc/vpc-XXXXXXXXXXXXXXXX ~ enable_dns_hostnames: true => false ~ enable_dns_support: true => false State: tfstate+s3://tf-cm-takakuni/vpc_tokyo/terraform.tfstate [ Changed Resources: 8 ] Resource Type: aws_internet_gateway ID: igw-XXXXXXXXXXXXXXXX ~ arn: arn:aws:ec2:ap-northeast-1:622809842341:internet-gateway/igw-XXXXXXXXXXXXXXXX => arn:aws:ec2:ap-northeast-1::internet-gateway/igw-XXXXXXXXXXXXXXXX Resource Type: aws_route_table_association ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: ID: rtbassoc-XXXXXXXXXXXXXXXX - gateway_id: Resource Type: aws_vpc ID: vpc-XXXXXXXXXXXXXXXX ~ arn: arn:aws:ec2:ap-northeast-1:622809842341:vpc/vpc-XXXXXXXXXXXXXXXX => arn:aws:ec2:ap-northeast-1::vpc/vpc-XXXXXXXXXXXXXXXX Test Summary Managed Resources: 20 Changed Resources: 9 IaC Coverage: 100% Info: To reach full coverage, remove resources or move it to Terraform. Tip: Run --help to find out about commands and flags. Scanned with aws provider version 3.19.0. Use --tf-provider-version to update.
詳しい詳細は、再掲になりますが次のブログをご覧いただければと思います。
アンマネージドなリソースの検知
「--only-unmanaged」オプションを利用することで、Terraformで管理されているリソースの状態を把握できます。
あまりにも管理されていないので抜粋しましたが、Service: aws_ec2 [ Unmanaged Resources: 4 ]のように、リソースの種類ごとにリストアップされて出力されました。
普段Terraform信者として活動しているにも関わらず、IaC Coverageが11%なことに少しショッキングでした...
takakuni.shinnosuke@my_env % snyk iac describe --only-unmanaged --from="tfstate+s3://tf-cm-takakuni/*/*" Scanned states (9) Scan duration: 14s ⣷ Provider version used to scan: 3.19.0. Use --tf-provider-version to use another version. Snyk Scanning Infrastructure As Code Discrepancies... Info: Resources under IaC, but different to terraform states. Resolve: Reapply IaC resources or update into terraform. Unmanaged resources: 160 Service: aws_ec2 [ Unmanaged Resources: 4 ] Resource Type: aws_ebs_volume ID: vol-0a59d6fc9a9ce594b Resource Type: aws_instance ID: i-040e1922e74bcbc49 ################################ # 抜粋 ################################ Test Summary Managed Resources: 20 Unmanaged Resources: 160 IaC Coverage: 11% Info: To reach full coverage, remove resources or move it to Terraform. Tip: Run --help to find out about commands and flags. Scanned with aws provider version 3.19.0. Use --tf-provider-version to update.
検出を回避する
出力結果を確認するとAWSでマネージドに作成されたロールへのポリシーアタッチメントも検出されていました。
私個人としては、マネージドなロールに対してのポリシーアタッチメントまでTerraformで管理したいわけではないので検出を回避したいと思います。
Service: aws_iam [ Unmanaged Resources: 86 ] Resource Type: aws_iam_policy_attachment ID: AWSServiceRoleForAPIGateway-arn:aws:iam::aws:policy/aws-service-role/APIGatewayServiceRolePolicy ID: AWSServiceRoleForAWSCloud9-arn:aws:iam::aws:policy/aws-service-role/AWSCloud9ServiceRolePolicy ID: AWSServiceRoleForAccessAnalyzer-arn:aws:iam::aws:policy/aws-service-role/AccessAnalyzerServiceRolePolicy ID: AWSServiceRoleForAmazonGuardDuty-arn:aws:iam::aws:policy/aws-service-role/AmazonGuardDutyServiceRolePolicy ID: AWSServiceRoleForAmazonInspector2-arn:aws:iam::aws:policy/aws-service-role/AmazonInspector2ServiceRolePolicy ID: AWSServiceRoleForAmazonMacie-arn:aws:iam::aws:policy/aws-service-role/AmazonMacieServiceRolePolicy ID: AWSServiceRoleForAmazonSSM-arn:aws:iam::aws:policy/aws-service-role/AmazonSSMServiceRolePolicy ID: AWSServiceRoleForAuditManager-arn:aws:iam::aws:policy/aws-service-role/AWSAuditManagerServiceRolePolicy ID: AWSServiceRoleForBackup-arn:aws:iam::aws:policy/aws-service-role/AWSBackupServiceLinkedRolePolicyForBackup ID: AWSServiceRoleForClientVPN-arn:aws:iam::aws:policy/aws-service-role/ClientVPNServiceRolePolicy ID: AWSServiceRoleForCodeStarNotifications-arn:aws:iam::aws:policy/aws-service-role/AWSCodeStarNotificationsServiceRolePolicy ID: AWSServiceRoleForComputeOptimizer-arn:aws:iam::aws:policy/aws-service-role/ComputeOptimizerServiceRolePolicy ID: AWSServiceRoleForECS-arn:aws:iam::aws:policy/aws-service-role/AmazonECSServiceRolePolicy ID: AWSServiceRoleForElasticLoadBalancing-arn:aws:iam::aws:policy/aws-service-role/AWSElasticLoadBalancingServiceRolePolicy ID: AWSServiceRoleForGlobalAccelerator-arn:aws:iam::aws:policy/aws-service-role/AWSGlobalAcceleratorSLRPolicy ID: AWSServiceRoleForMigrationHub-arn:aws:iam::aws:policy/aws-service-role/MigrationHubServiceRolePolicy ID: AWSServiceRoleForMigrationHubRefactorSpaces-arn:aws:iam::aws:policy/aws-service-role/AWSMigrationHubRefactorSpacesServiceRolePolicy ID: AWSServiceRoleForNetworkFirewall-arn:aws:iam::aws:policy/aws-service-role/AWSNetworkFirewallServiceRolePolicy ID: AWSServiceRoleForNetworkManager-arn:aws:iam::aws:policy/aws-service-role/AWSNetworkManagerServiceRolePolicy ID: AWSServiceRoleForRDS-arn:aws:iam::aws:policy/aws-service-role/AmazonRDSServiceRolePolicy ID: AWSServiceRoleForRedshift-arn:aws:iam::aws:policy/aws-service-role/AmazonRedshiftServiceLinkedRolePolicy ID: AWSServiceRoleForRolesAnywhere-arn:aws:iam::aws:policy/aws-service-role/AWSRolesAnywhereServicePolicy ID: AWSServiceRoleForSecurityHub-arn:aws:iam::aws:policy/aws-service-role/AWSSecurityHubServiceRolePolicy ID: AWSServiceRoleForVPCTransitGateway-arn:aws:iam::aws:policy/aws-service-role/AWSVPCTransitGatewayServiceRolePolicy
検出を回避するには.snyk
ファイルを実行コマンドと同列フォルダに配置します。こちらもワイルドカードが使えるのでかなり融通が利きやすい印象でした。
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. version: v1.22.1 exclude: iac-drift: - aws_iam_policy_attachment.AWSServiceRoleFor*-arn:aws:iam::aws:policy/aws-service-role/*
実行の結果、Service: aws_iam [ Unmanaged Resources: 62 ]まで検出結果を抑えることができました。
詳しくは次のリファレンスをご覧ください。
HTML出力もできる
snyk iac describe
コマンドは、出力方法の1つにHTML形式をサポートしています。「--html-file-output
」オプションを指定することでHTMLファイル形式で結果を出力して確認できます。
「--all」オプションでAWSアカウント全体の管理状況を確認してみます。
snyk iac describe --all --from="tfstate+s3://tf-cm-takakuni/*/*" --html-file-output=results.html
出力されたHTMLファイルを確認すると、ほとんど黒塗りですが画像右にみえるリソースの種別ごとでリストアップされていることがわかります。監査などで提出する際に大変便利だと思いました。
まとめ
「Snyk IaCでTerraform管理外のリソースを検出してみた」でした!
Terraform信者の方、ぜひ自分のアカウントがどれほど管理できているか確認してみてください。Terraformで運用しているケースにもかなり刺さる使い方だと思いました。
この記事がどなたかの参考になれば幸いです。
以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!