snyk / driftctl

Detect, track and alert on infrastructure drift
Apache License 2.0
2.47k stars 159 forks source link

Support inline policy for aws_iam_role #1567

Open moadibfr opened 2 years ago

moadibfr commented 2 years ago

Description From what I understand with provider 4.x terraform added the possibility to define inline policy for aws_iam_role (and possibly other resources ?). We do not support this so driftctl will report the corresponding aws_iam_role_policy found in the environment as unmanaged. We probably need a new middleware to transform these inline_policy into aws_iam_role_policy

Example

provider "aws" {
    region  = "us-east-1"
}
terraform {
    required_providers {
        aws = {
            version = "4.11.0"
        }
    }
}

resource "aws_iam_role" "driftctl_runner" {
    name        = "DriftCtlRunner"
    description = "Detect infrastructure drift by reading state of account resources"

    assume_role_policy = jsonencode(
        {
            Version = "2012-10-17"
            Statement = [
                {
                    Action = "sts:AssumeRole"
                    Effect = "Allow"
                    Principal = {
                        Service = "ec2.amazonaws.com"
                    }
                }
            ]
        }
    )

    inline_policy {
        name = "ReadResources"
        policy = jsonencode(
            {
                Version = "2012-10-17",
                Statement = [
                    {
                        Effect = "Allow"
                        Action = [
                            "apigateway:GET",
                            "application-autoscaling:DescribeScalableTargets",
                            "application-autoscaling:DescribeScalingPolicies",
                            "application-autoscaling:DescribeScheduledActions",
                            "autoscaling:DescribeLaunchConfigurations",
                            "cloudformation:DescribeStacks",
                            "cloudformation:GetTemplate",
                            "cloudfront:GetDistribution",
                            "cloudfront:ListDistributions",
                            "cloudfront:ListTagsForResource",
                            "dynamodb:DescribeContinuousBackups",
                            "dynamodb:DescribeGlobalTable",
                            "dynamodb:DescribeTable",
                            "dynamodb:DescribeTableReplicaAutoScaling",
                            "dynamodb:DescribeTimeToLive",
                            "dynamodb:ListTables",
                            "dynamodb:ListTagsOfResource",
                            "ec2:DescribeAccountAttributes",
                            "ec2:DescribeAddresses",
                            "ec2:DescribeImages",
                            "ec2:DescribeInstanceAttribute",
                            "ec2:DescribeInstanceCreditSpecifications",
                            "ec2:DescribeInstances",
                            "ec2:DescribeInternetGateways",
                            "ec2:DescribeKeyPairs",
                            "ec2:DescribeLaunchTemplates",
                            "ec2:DescribeNatGateways",
                            "ec2:DescribeNetworkAcls",
                            "ec2:DescribeRouteTables",
                            "ec2:DescribeSecurityGroups",
                            "ec2:DescribeSnapshots",
                            "ec2:DescribeSubnets",
                            "ec2:DescribeTags",
                            "ec2:DescribeVolumes",
                            "ec2:DescribeVpcAttribute",
                            "ec2:DescribeVpcClassicLink",
                            "ec2:DescribeVpcClassicLinkDnsSupport",
                            "ec2:DescribeVpcs",
                            "ec2:GetEbsEncryptionByDefault",
                            "ecr:DescribeRepositories",
                            "ecr:GetRepositoryPolicy",
                            "ecr:ListTagsForResource",
                            "elasticache:DescribeCacheClusters",
                            "elasticloadbalancing:DescribeListeners",
                            "elasticloadbalancing:DescribeLoadBalancers",
                            "iam:GetPolicy",
                            "iam:GetPolicyVersion",
                            "iam:GetRole",
                            "iam:GetRolePolicy",
                            "iam:GetUser",
                            "iam:GetUserPolicy",
                            "iam:ListAccessKeys",
                            "iam:ListAttachedGroupPolicies",
                            "iam:ListAttachedRolePolicies",
                            "iam:ListAttachedUserPolicies",
                            "iam:ListGroupPolicies",
                            "iam:ListGroups",
                            "iam:ListPolicies",
                            "iam:ListRolePolicies",
                            "iam:ListRoles",
                            "iam:ListUserPolicies",
                            "iam:ListUsers",
                            "kms:DescribeKey",
                            "kms:GetKeyPolicy",
                            "kms:GetKeyRotationStatus",
                            "kms:ListAliases",
                            "kms:ListKeys",
                            "kms:ListResourceTags",
                            "lambda:GetEventSourceMapping",
                            "lambda:GetFunction",
                            "lambda:GetFunctionCodeSigningConfig",
                            "lambda:ListEventSourceMappings",
                            "lambda:ListFunctions",
                            "lambda:ListVersionsByFunction",
                            "rds:DescribeDBClusters",
                            "rds:DescribeDBInstances",
                            "rds:DescribeDBSubnetGroups",
                            "rds:DescribeGlobalClusters",
                            "rds:ListTagsForResource",
                            "route53:GetHealthCheck",
                            "route53:GetHostedZone",
                            "route53:ListHealthChecks",
                            "route53:ListHostedZones",
                            "route53:ListResourceRecordSets",
                            "route53:ListTagsForResource",
                            "s3:GetAccelerateConfiguration",
                            "s3:GetAnalyticsConfiguration",
                            "s3:GetBucketAcl",
                            "s3:GetBucketCORS",
                            "s3:GetBucketLocation",
                            "s3:GetBucketLogging",
                            "s3:GetBucketNotification",
                            "s3:GetBucketObjectLockConfiguration",
                            "s3:GetBucketPolicy",
                            "s3:GetBucketPublicAccessBlock",
                            "s3:GetBucketRequestPayment",
                            "s3:GetBucketTagging",
                            "s3:GetBucketVersioning",
                            "s3:GetBucketWebsite",
                            "s3:GetEncryptionConfiguration",
                            "s3:GetInventoryConfiguration",
                            "s3:GetLifecycleConfiguration",
                            "s3:GetMetricsConfiguration",
                            "s3:GetReplicationConfiguration",
                            "s3:ListAllMyBuckets",
                            "s3:ListBucket",
                            "sns:GetSubscriptionAttributes",
                            "sns:GetTopicAttributes",
                            "sns:ListSubscriptions",
                            "sns:ListSubscriptionsByTopic",
                            "sns:ListTagsForResource",
                            "sns:ListTopics",
                            "sqs:GetQueueAttributes",
                            "sqs:ListQueueTags",
                            "sqs:ListQueues",
                        ]
                        Resource = "*"
                    },
                ]
            }
        )
    }

    inline_policy {
        name = "ReadTerraformState"
        policy = jsonencode(
            {
                Version = "2012-10-17",
                Statement = [
                    {
                        Effect   = "Allow"
                        Action   = "s3:GetObject"
                        Resource = "${aws_s3_bucket.buucketttestmartin.arn}/*"
                    },
                ]
            }
        )
    }

    managed_policy_arns = []
}

resource "aws_s3_bucket" "buucketttestmartin" {
    bucket = "buucketttestmartin"
}

will create a state looking like

{
  "version": 4,
  "terraform_version": "0.15.5",
  "serial": 118,
  "lineage": "2587700f-4037-8fdb-866a-dfa7d4f613a2",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_iam_role",
      "name": "driftctl_runner",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "arn": "arn:aws:iam::526954929923:role/DriftCtlRunner",
            "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}",
            "create_date": "2022-07-20T16:16:40Z",
            "description": "Detect infrastructure drift by reading state of account resources",
            "force_detach_policies": false,
            "id": "DriftCtlRunner",
            "inline_policy": [
              {
                "name": "ReadResources",
                "policy": "{\"Statement\":[{\"Action\":[\"apigateway:GET\",\"application-autoscaling:DescribeScalableTargets\",\"application-autoscaling:DescribeScalingPolicies\",\"application-autoscaling:DescribeScheduledActions\",\"autoscaling:DescribeLaunchConfigurations\",\"cloudformation:DescribeStacks\",\"cloudformation:GetTemplate\",\"cloudfront:GetDistribution\",\"cloudfront:ListDistributions\",\"cloudfront:ListTagsForResource\",\"dynamodb:DescribeContinuousBackups\",\"dynamodb:DescribeGlobalTable\",\"dynamodb:DescribeTable\",\"dynamodb:DescribeTableReplicaAutoScaling\",\"dynamodb:DescribeTimeToLive\",\"dynamodb:ListTables\",\"dynamodb:ListTagsOfResource\",\"ec2:DescribeAccountAttributes\",\"ec2:DescribeAddresses\",\"ec2:DescribeImages\",\"ec2:DescribeInstanceAttribute\",\"ec2:DescribeInstanceCreditSpecifications\",\"ec2:DescribeInstances\",\"ec2:DescribeInternetGateways\",\"ec2:DescribeKeyPairs\",\"ec2:DescribeLaunchTemplates\",\"ec2:DescribeNatGateways\",\"ec2:DescribeNetworkAcls\",\"ec2:DescribeRouteTables\",\"ec2:DescribeSecurityGroups\",\"ec2:DescribeSnapshots\",\"ec2:DescribeSubnets\",\"ec2:DescribeTags\",\"ec2:DescribeVolumes\",\"ec2:DescribeVpcAttribute\",\"ec2:DescribeVpcClassicLink\",\"ec2:DescribeVpcClassicLinkDnsSupport\",\"ec2:DescribeVpcs\",\"ec2:GetEbsEncryptionByDefault\",\"ecr:DescribeRepositories\",\"ecr:GetRepositoryPolicy\",\"ecr:ListTagsForResource\",\"elasticache:DescribeCacheClusters\",\"elasticloadbalancing:DescribeListeners\",\"elasticloadbalancing:DescribeLoadBalancers\",\"iam:GetPolicy\",\"iam:GetPolicyVersion\",\"iam:GetRole\",\"iam:GetRolePolicy\",\"iam:GetUser\",\"iam:GetUserPolicy\",\"iam:ListAccessKeys\",\"iam:ListAttachedGroupPolicies\",\"iam:ListAttachedRolePolicies\",\"iam:ListAttachedUserPolicies\",\"iam:ListGroupPolicies\",\"iam:ListGroups\",\"iam:ListPolicies\",\"iam:ListRolePolicies\",\"iam:ListRoles\",\"iam:ListUserPolicies\",\"iam:ListUsers\",\"kms:DescribeKey\",\"kms:GetKeyPolicy\",\"kms:GetKeyRotationStatus\",\"kms:ListAliases\",\"kms:ListKeys\",\"kms:ListResourceTags\",\"lambda:GetEventSourceMapping\",\"lambda:GetFunction\",\"lambda:GetFunctionCodeSigningConfig\",\"lambda:ListEventSourceMappings\",\"lambda:ListFunctions\",\"lambda:ListVersionsByFunction\",\"rds:DescribeDBClusters\",\"rds:DescribeDBInstances\",\"rds:DescribeDBSubnetGroups\",\"rds:DescribeGlobalClusters\",\"rds:ListTagsForResource\",\"route53:GetHealthCheck\",\"route53:GetHostedZone\",\"route53:ListHealthChecks\",\"route53:ListHostedZones\",\"route53:ListResourceRecordSets\",\"route53:ListTagsForResource\",\"s3:GetAccelerateConfiguration\",\"s3:GetAnalyticsConfiguration\",\"s3:GetBucketAcl\",\"s3:GetBucketCORS\",\"s3:GetBucketLocation\",\"s3:GetBucketLogging\",\"s3:GetBucketNotification\",\"s3:GetBucketObjectLockConfiguration\",\"s3:GetBucketPolicy\",\"s3:GetBucketPublicAccessBlock\",\"s3:GetBucketRequestPayment\",\"s3:GetBucketTagging\",\"s3:GetBucketVersioning\",\"s3:GetBucketWebsite\",\"s3:GetEncryptionConfiguration\",\"s3:GetInventoryConfiguration\",\"s3:GetLifecycleConfiguration\",\"s3:GetMetricsConfiguration\",\"s3:GetReplicationConfiguration\",\"s3:ListAllMyBuckets\",\"s3:ListBucket\",\"sns:GetSubscriptionAttributes\",\"sns:GetTopicAttributes\",\"sns:ListSubscriptions\",\"sns:ListSubscriptionsByTopic\",\"sns:ListTagsForResource\",\"sns:ListTopics\",\"sqs:GetQueueAttributes\",\"sqs:ListQueueTags\",\"sqs:ListQueues\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}],\"Version\":\"2012-10-17\"}"
              },
              {
                "name": "ReadTerraformState",
                "policy": "{\"Statement\":[{\"Action\":\"s3:GetObject\",\"Effect\":\"Allow\",\"Resource\":\"arn:aws:s3:::buucketttestmartin/*\"}],\"Version\":\"2012-10-17\"}"
              }
            ],
            "managed_policy_arns": [],
            "max_session_duration": 3600,
            "name": "DriftCtlRunner",
            "name_prefix": "",
            "path": "/",
            "permissions_boundary": null,
            "tags": {},
            "tags_all": {},
            "unique_id": "AROAXVMHWD4BRNKX2MPIP"
          },
          "sensitive_attributes": [],
          "private": "bnVsbA==",
          "dependencies": [
            "aws_s3_bucket.buucketttestmartin"
          ]
        }
      ]
    },
    {
      "mode": "managed",
      "type": "aws_s3_bucket",
      "name": "buucketttestmartin",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "acceleration_status": "",
            "acl": null,
            "arn": "arn:aws:s3:::buucketttestmartin",
            "bucket": "buucketttestmartin",
            "bucket_domain_name": "buucketttestmartin.s3.amazonaws.com",
            "bucket_prefix": null,
            "bucket_regional_domain_name": "buucketttestmartin.s3.amazonaws.com",
            "cors_rule": [],
            "force_destroy": false,
            "grant": [
              {
                "id": "2e255b8610865d5ec2910b37430de894ee2b2c3b60be868ca00359f99c79d7be",
                "permissions": [
                  "FULL_CONTROL"
                ],
                "type": "CanonicalUser",
                "uri": ""
              }
            ],
            "hosted_zone_id": "Z3AQBSTGFYJSTF",
            "id": "buucketttestmartin",
            "lifecycle_rule": [],
            "logging": [],
            "object_lock_configuration": [],
            "object_lock_enabled": false,
            "policy": "",
            "region": "us-east-1",
            "replication_configuration": [],
            "request_payer": "BucketOwner",
            "server_side_encryption_configuration": [],
            "tags": {},
            "tags_all": {},
            "versioning": [
              {
                "enabled": false,
                "mfa_delete": false
              }
            ],
            "website": [],
            "website_domain": null,
            "website_endpoint": null
          },
          "sensitive_attributes": [],
          "private": "bnVsbA=="
        }
      ]
    }
  ]
}
moadibfr commented 2 years ago

this was reported as a bug in #1556