Skip to content

Commit 100cf11

Browse files
authored
Add aws_iam_role_deprecated_policy_attributes rule (#833)
* Fix rule template typo * Add aws_iam_role_deprecated_policy_attributes rule The warning messages have been copied verbatim from the upstream documentation of the `aws_iam_role` resource.
1 parent d2bb483 commit 100cf11

6 files changed

+257
-0
lines changed

docs/rules/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ These rules enforce best practices and naming conventions:
7171
|[aws_iam_policy_attachment_exclusive_attachment](aws_iam_policy_attachment_exclusive_attachment.md)|Consider alternative resources to `aws_iam_policy_attachment`||
7272
|[aws_iam_policy_document_gov_friendly_arns](aws_iam_policy_document_gov_friendly_arns.md)|Ensure `iam_policy_document` data sources do not contain `arn:aws:` ARN's||
7373
|[aws_iam_policy_gov_friendly_arns](aws_iam_policy_gov_friendly_arns.md)|Ensure `iam_policy` resources do not contain `arn:aws:` ARN's||
74+
|[aws_iam_role_deprecated_policy_attributes](aws_iam_role_deprecated_policy_attributes.md)|Disallow using deprecated policy attributes of `aws_iam_role`||
7475
|[aws_iam_role_policy_gov_friendly_arns](aws_iam_role_policy_gov_friendly_arns.md)|Ensure `iam_role_policy` resources do not contain `arn:aws:` ARN's||
7576
|[aws_lambda_function_deprecated_runtime](aws_lambda_function_deprecated_runtime.md)|Disallow deprecated runtimes for Lambda Function||
7677
|[aws_resource_missing_tags](aws_resource_missing_tags.md)|Require specific tags for all AWS resource types that support them||

docs/rules/README.md.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ These rules enforce best practices and naming conventions:
7171
|[aws_iam_policy_attachment_exclusive_attachment](aws_iam_policy_attachment_exclusive_attachment.md)|Consider alternative resources to `aws_iam_policy_attachment`||
7272
|[aws_iam_policy_document_gov_friendly_arns](aws_iam_policy_document_gov_friendly_arns.md)|Ensure `iam_policy_document` data sources do not contain `arn:aws:` ARN's||
7373
|[aws_iam_policy_gov_friendly_arns](aws_iam_policy_gov_friendly_arns.md)|Ensure `iam_policy` resources do not contain `arn:aws:` ARN's||
74+
|[aws_iam_role_deprecated_policy_attributes](aws_iam_role_deprecated_policy_attributes.md)|Disallow using deprecated policy attributes of `aws_iam_role`||
7475
|[aws_iam_role_policy_gov_friendly_arns](aws_iam_role_policy_gov_friendly_arns.md)|Ensure `iam_role_policy` resources do not contain `arn:aws:` ARN's||
7576
|[aws_lambda_function_deprecated_runtime](aws_lambda_function_deprecated_runtime.md)|Disallow deprecated runtimes for Lambda Function|✔|
7677
|[aws_resource_missing_tags](aws_resource_missing_tags.md)|Require specific tags for all AWS resource types that support them||
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# aws_iam_role_deprecated_policy_attributes
2+
3+
Disallow `inline_policy` configuration blocks and `managed_policy_arns` argument of the `aws_iam_role` resource.
4+
5+
## Example
6+
7+
```hcl
8+
resource "aws_iam_role" "example" {
9+
name = "example"
10+
assume_role_policy = data.aws_iam_policy_document.instance_assume_role_policy.json # (not shown)
11+
12+
inline_policy {
13+
name = "my_inline_policy"
14+
15+
policy = jsonencode({
16+
Version = "2012-10-17"
17+
Statement = [
18+
{
19+
Action = ["ec2:Describe*"]
20+
Effect = "Allow"
21+
Resource = "*"
22+
},
23+
]
24+
})
25+
}
26+
27+
inline_policy {
28+
name = "policy-8675309"
29+
policy = data.aws_iam_policy_document.inline_policy.json # (not shown)
30+
}
31+
32+
managed_policy_arns = []
33+
}
34+
```
35+
36+
```
37+
$ tflint
38+
39+
3 issue(s) found:
40+
41+
Warning: The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead. If Terraform should exclusively manage all inline policy associations (the current behavior of this argument), use the aws_iam_role_policies_exclusive resource as well. (aws_iam_role_deprecated_policy_attributes)
42+
43+
on test.tf line 5:
44+
5: inline_policy {
45+
46+
Warning: The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead. If Terraform should exclusively manage all inline policy associations (the current behavior of this argument), use the aws_iam_role_policies_exclusive resource as well. (aws_iam_role_deprecated_policy_attributes)
47+
48+
on test.tf line 20:
49+
20: inline_policy {
50+
51+
Warning: The managed_policy_arns argument is deprecated. Use the aws_iam_role_policy_attachment resource instead. If Terraform should exclusively manage all managed policy attachments (the current behavior of this argument), use the aws_iam_role_policy_attachments_exclusive resource as well. (aws_iam_role_deprecated_policy_attributes)
52+
53+
on test.tf line 25:
54+
25: managed_policy_arns = []
55+
```
56+
57+
## Why
58+
59+
The `inline_policy` and `managed_policy_arns` arguments are both deprecated since late 2024.
60+
61+
## How To Fix
62+
63+
For managing a role's inline policy, use the [aws_iam_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) resource instead.
64+
For attaching managed policies to a role, use the [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) resource.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package rules
2+
3+
import (
4+
"github.com/terraform-linters/tflint-plugin-sdk/hclext"
5+
"github.com/terraform-linters/tflint-plugin-sdk/tflint"
6+
"github.com/terraform-linters/tflint-ruleset-aws/project"
7+
)
8+
9+
// AwsIAMRoleDeprecatedPolicyAttributesRule checks that neither `inline_policy` or `managed_policy_arns` are used in an `aws_iam_role`
10+
type AwsIAMRoleDeprecatedPolicyAttributesRule struct {
11+
tflint.DefaultRule
12+
13+
resourceType string
14+
}
15+
16+
// NewAwsIAMRoleDeprecatedPolicyAttributesRule returns new rule with default attributes
17+
func NewAwsIAMRoleDeprecatedPolicyAttributesRule() *AwsIAMRoleDeprecatedPolicyAttributesRule {
18+
return &AwsIAMRoleDeprecatedPolicyAttributesRule{
19+
resourceType: "aws_iam_role",
20+
}
21+
}
22+
23+
// Name returns the rule name
24+
func (r *AwsIAMRoleDeprecatedPolicyAttributesRule) Name() string {
25+
return "aws_iam_role_deprecated_policy_attributes"
26+
}
27+
28+
// Enabled returns whether the rule is enabled by default
29+
func (r *AwsIAMRoleDeprecatedPolicyAttributesRule) Enabled() bool {
30+
// `inline_policy` and `managed_policy_arns` were deprecated in 5.68.0 and 5.72.0 respectively
31+
// At time of writing, this is quite recent, so don't automatically enable the rule.
32+
return false
33+
}
34+
35+
// Severity returns the rule severity
36+
func (r *AwsIAMRoleDeprecatedPolicyAttributesRule) Severity() tflint.Severity {
37+
return tflint.WARNING
38+
}
39+
40+
// Link returns the rule reference link
41+
func (r *AwsIAMRoleDeprecatedPolicyAttributesRule) Link() string {
42+
return project.ReferenceLink(r.Name())
43+
}
44+
45+
// Check checks that aws_iam_role resources don't have any `inline_policy` blocks or the `managed_policy_arns` attribute
46+
func (r *AwsIAMRoleDeprecatedPolicyAttributesRule) Check(runner tflint.Runner) error {
47+
resources, err := runner.GetResourceContent(r.resourceType, &hclext.BodySchema{
48+
Blocks: []hclext.BlockSchema{
49+
{
50+
Type: "inline_policy",
51+
},
52+
},
53+
Attributes: []hclext.AttributeSchema{
54+
{
55+
Name: "managed_policy_arns",
56+
},
57+
},
58+
}, nil)
59+
if err != nil {
60+
return err
61+
}
62+
63+
for _, resource := range resources.Blocks {
64+
attribute, exists := resource.Body.Attributes["managed_policy_arns"]
65+
66+
if exists {
67+
if err := runner.EmitIssue(r, "The managed_policy_arns argument is deprecated. Use the aws_iam_role_policy_attachment resource instead. If Terraform should exclusively manage all managed policy attachments (the current behavior of this argument), use the aws_iam_role_policy_attachments_exclusive resource as well.", attribute.Range); err != nil {
68+
return err
69+
}
70+
}
71+
72+
for _, rule := range resource.Body.Blocks {
73+
if rule.Type != "inline_policy" {
74+
continue
75+
}
76+
77+
if err := runner.EmitIssue(r, "The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead. If Terraform should exclusively manage all inline policy associations (the current behavior of this argument), use the aws_iam_role_policies_exclusive resource as well.", rule.DefRange); err != nil {
78+
return err
79+
}
80+
}
81+
}
82+
83+
return nil
84+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package rules
2+
3+
import (
4+
"testing"
5+
6+
hcl "github.com/hashicorp/hcl/v2"
7+
"github.com/terraform-linters/tflint-plugin-sdk/helper"
8+
)
9+
10+
func Test_AwsIAMRoleDeprecatedPolicyAttributes(t *testing.T) {
11+
cases := []struct {
12+
Name string
13+
Content string
14+
Expected helper.Issues
15+
}{
16+
{
17+
Name: "inline_policies",
18+
Content: `
19+
resource "aws_iam_role" "example" {
20+
name = "yak_role"
21+
assume_role_policy = data.aws_iam_policy_document.instance_assume_role_policy.json # (not shown)
22+
23+
inline_policy {
24+
name = "my_inline_policy"
25+
26+
policy = jsonencode({
27+
Version = "2012-10-17"
28+
Statement = [
29+
{
30+
Action = ["ec2:Describe*"]
31+
Effect = "Allow"
32+
Resource = "*"
33+
},
34+
]
35+
})
36+
}
37+
38+
inline_policy {
39+
name = "policy-8675309"
40+
policy = data.aws_iam_policy_document.inline_policy.json
41+
}
42+
}
43+
44+
data "aws_iam_policy_document" "inline_policy" {
45+
statement {
46+
actions = ["ec2:DescribeAccountAttributes"]
47+
resources = ["*"]
48+
}
49+
}
50+
`,
51+
Expected: helper.Issues{
52+
{
53+
Rule: NewAwsIAMRoleDeprecatedPolicyAttributesRule(),
54+
Message: "The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead. If Terraform should exclusively manage all inline policy associations (the current behavior of this argument), use the aws_iam_role_policies_exclusive resource as well.",
55+
Range: hcl.Range{
56+
Filename: "resource.tf",
57+
Start: hcl.Pos{Line: 6, Column: 3},
58+
End: hcl.Pos{Line: 6, Column: 16},
59+
},
60+
},
61+
{
62+
Rule: NewAwsIAMRoleDeprecatedPolicyAttributesRule(),
63+
Message: "The inline_policy argument is deprecated. Use the aws_iam_role_policy resource instead. If Terraform should exclusively manage all inline policy associations (the current behavior of this argument), use the aws_iam_role_policies_exclusive resource as well.",
64+
Range: hcl.Range{
65+
Filename: "resource.tf",
66+
Start: hcl.Pos{Line: 21, Column: 3},
67+
End: hcl.Pos{Line: 21, Column: 16},
68+
},
69+
},
70+
},
71+
},
72+
{
73+
Name: "managed_policy_arns",
74+
Content: `
75+
resource "aws_iam_role" "example" {
76+
name = "yak_role"
77+
assume_role_policy = data.aws_iam_policy_document.instance_assume_role_policy.json # (not shown)
78+
managed_policy_arns = []
79+
}
80+
`,
81+
Expected: helper.Issues{
82+
{
83+
Rule: NewAwsIAMRoleDeprecatedPolicyAttributesRule(),
84+
Message: "The managed_policy_arns argument is deprecated. Use the aws_iam_role_policy_attachment resource instead. If Terraform should exclusively manage all managed policy attachments (the current behavior of this argument), use the aws_iam_role_policy_attachments_exclusive resource as well.",
85+
Range: hcl.Range{
86+
Filename: "resource.tf",
87+
Start: hcl.Pos{Line: 5, Column: 3},
88+
End: hcl.Pos{Line: 5, Column: 27},
89+
},
90+
},
91+
},
92+
},
93+
}
94+
95+
rule := NewAwsIAMRoleDeprecatedPolicyAttributesRule()
96+
97+
for _, tc := range cases {
98+
runner := helper.TestRunner(t, map[string]string{"resource.tf": tc.Content})
99+
100+
if err := rule.Check(runner); err != nil {
101+
t.Fatalf("Unexpected error occurred: %s", err)
102+
}
103+
104+
helper.AssertIssues(t, tc.Expected, runner.Issues)
105+
}
106+
}

rules/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ var manualRules = []tflint.Rule{
4343
NewAwsProviderMissingDefaultTagsRule(),
4444
NewAwsSecurityGroupInlineRulesRule(),
4545
NewAwsSecurityGroupRuleDeprecatedRule(),
46+
NewAwsIAMRoleDeprecatedPolicyAttributesRule(),
4647
}
4748

4849
// Rules is a list of all rules

0 commit comments

Comments
 (0)