github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/internal/adapters/terraform/aws/iam/roles_test.go (about) 1 package iam 2 3 import ( 4 "sort" 5 "testing" 6 7 "github.com/aquasecurity/defsec/pkg/providers/aws/iam" 8 defsecTypes "github.com/aquasecurity/defsec/pkg/types" 9 10 "github.com/aquasecurity/trivy-iac/internal/adapters/terraform/tftestutil" 11 "github.com/aquasecurity/trivy-iac/test/testutil" 12 ) 13 14 func Test_adaptRoles(t *testing.T) { 15 tests := []struct { 16 name string 17 terraform string 18 expected []iam.Role 19 }{ 20 { 21 name: "policy", 22 terraform: ` 23 resource "aws_iam_role_policy" "test_policy" { 24 name = "test_policy" 25 role = aws_iam_role.test_role.id 26 policy = data.aws_iam_policy_document.policy.json 27 } 28 29 resource "aws_iam_role" "test_role" { 30 name = "test_role" 31 assume_role_policy = jsonencode({ 32 Version = "2012-10-17" 33 Statement = [ 34 { 35 Action = "sts:AssumeRole" 36 Effect = "Allow" 37 Sid = "" 38 Principal = { 39 Service = "s3.amazonaws.com" 40 } 41 }, 42 ] 43 }) 44 } 45 46 data "aws_iam_policy_document" "policy" { 47 version = "2012-10-17" 48 statement { 49 effect = "Allow" 50 actions = ["ec2:Describe*"] 51 resources = ["*"] 52 } 53 } 54 `, 55 expected: []iam.Role{ 56 { 57 Metadata: defsecTypes.NewTestMetadata(), 58 Name: defsecTypes.String("test_role", defsecTypes.NewTestMetadata()), 59 Policies: []iam.Policy{ 60 { 61 Metadata: defsecTypes.NewTestMetadata(), 62 Name: defsecTypes.String("test_policy", defsecTypes.NewTestMetadata()), 63 Document: defaultPolicyDocuemnt(true), 64 }, 65 }, 66 }, 67 }, 68 }, 69 { 70 name: "policy attachment", 71 terraform: ` 72 resource "aws_iam_role" "role" { 73 name = "test-role" 74 assume_role_policy = data.aws_iam_policy_document.assume_role.json 75 } 76 77 data "aws_iam_policy_document" "policy" { 78 version = "2012-10-17" 79 statement { 80 effect = "Allow" 81 actions = ["ec2:Describe*"] 82 resources = ["*"] 83 } 84 } 85 86 resource "aws_iam_policy" "policy" { 87 name = "test-policy" 88 description = "A test policy" 89 policy = data.aws_iam_policy_document.policy.json 90 } 91 92 resource "aws_iam_role_policy_attachment" "test-attach" { 93 role = aws_iam_role.role.name 94 policy_arn = aws_iam_policy.policy.arn 95 } 96 `, 97 expected: []iam.Role{ 98 { 99 Metadata: defsecTypes.NewTestMetadata(), 100 Name: defsecTypes.String("test-role", defsecTypes.NewTestMetadata()), 101 Policies: []iam.Policy{ 102 { 103 Metadata: defsecTypes.NewTestMetadata(), 104 Name: defsecTypes.String("test-policy", defsecTypes.NewTestMetadata()), 105 Document: defaultPolicyDocuemnt(true), 106 }, 107 }, 108 }, 109 }, 110 }, 111 { 112 name: "inline policy", 113 terraform: ` 114 resource "aws_iam_role" "example" { 115 name = "test-role" 116 117 inline_policy { 118 name = "my_inline_policy" 119 120 policy = jsonencode({ 121 Version = "2012-10-17" 122 Statement = [ 123 { 124 Action = ["ec2:Describe*"] 125 Effect = "Allow" 126 Resource = "*" 127 }, 128 ] 129 }) 130 } 131 } 132 `, 133 expected: []iam.Role{ 134 { 135 Metadata: defsecTypes.NewTestMetadata(), 136 Name: defsecTypes.String("test-role", defsecTypes.NewTestMetadata()), 137 Policies: []iam.Policy{ 138 { 139 Metadata: defsecTypes.NewTestMetadata(), 140 Name: defsecTypes.String("my_inline_policy", defsecTypes.NewTestMetadata()), 141 Document: defaultPolicyDocuemnt(false), 142 }, 143 }, 144 }, 145 }, 146 }, 147 { 148 name: "with for_each", 149 terraform: ` 150 locals { 151 roles = toset(["test-role1", "test-role2"]) 152 } 153 154 resource "aws_iam_role" "this" { 155 for_each = local.roles 156 name = each.key 157 assume_role_policy = "{}" 158 } 159 160 data "aws_iam_policy_document" "this" { 161 for_each = local.roles 162 version = "2012-10-17" 163 statement { 164 effect = "Allow" 165 actions = ["ec2:Describe*"] 166 resources = ["*"] 167 } 168 } 169 170 resource "aws_iam_policy" "this" { 171 for_each = local.roles 172 name = format("%s-policy", each.key) 173 description = "A test policy" 174 policy = data.aws_iam_policy_document.this.json 175 } 176 177 resource "aws_iam_role_policy_attachment" "this" { 178 for_each = local.roles 179 role = aws_iam_role.this[each.key].name 180 policy_arn = aws_iam_policy.this[each.key].arn 181 } 182 `, 183 expected: []iam.Role{ 184 { 185 Metadata: defsecTypes.NewTestMetadata(), 186 Name: defsecTypes.String("test-role1", defsecTypes.NewTestMetadata()), 187 Policies: []iam.Policy{ 188 { 189 Metadata: defsecTypes.NewTestMetadata(), 190 Name: defsecTypes.String("test-role1-policy", defsecTypes.NewTestMetadata()), 191 Document: defaultPolicyDocuemnt(true), 192 }, 193 }, 194 }, 195 { 196 Metadata: defsecTypes.NewTestMetadata(), 197 Name: defsecTypes.String("test-role2", defsecTypes.NewTestMetadata()), 198 Policies: []iam.Policy{ 199 { 200 Metadata: defsecTypes.NewTestMetadata(), 201 Name: defsecTypes.String("test-role2-policy", defsecTypes.NewTestMetadata()), 202 Document: defaultPolicyDocuemnt(true), 203 }, 204 }, 205 }, 206 }, 207 }, 208 } 209 210 for _, test := range tests { 211 t.Run(test.name, func(t *testing.T) { 212 modules := tftestutil.CreateModulesFromSource(t, test.terraform, ".tf") 213 adapted := adaptRoles(modules) 214 sort.Slice(adapted, func(i, j int) bool { 215 return adapted[i].Name.Value() < adapted[j].Name.Value() 216 }) 217 testutil.AssertDefsecEqual(t, test.expected, adapted) 218 }) 219 } 220 }