Snyk IaCでTerraform管理外のリソースを検出してみた

snyk iac describeコマンドでは、静的解析以外にも、Terraformで管理されていないリソースも検出可能です。
2022.08.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_

今回は、snyk iac describeコマンドを利用して、Terraformで作っていないリソースを検出してみようと思います。

Snyk IaC describeコマンドとは

snyk iac describeでは次の2つを検出できるコマンドです。Terraformのtfstate内のリソースとクラウドプロバイダーの実際のリソースを比較して検出するため、CloudFormationで書かれたファイルには使えません。

  1. ドリフト(現在の状態とtfstateとの差異を検出)
  2. 該当リソースが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

# 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_)でした!