Skip to content

Commit 651cedd

Browse files
committed
created project
Signed-off-by: Fred Myerscough <oniice@gmail.com>
0 parents  commit 651cedd

27 files changed

+2074
-0
lines changed

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: gomod
4+
directory: "/"
5+
schedule:
6+
interval: weekly
7+
open-pull-requests-limit: 10
8+
- package-ecosystem: "github-actions"
9+
directory: "/"
10+
schedule:
11+
interval: weekly

.github/workflows/build.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
schedule:
11+
- cron: "0 0 * * *"
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
test:
18+
name: ${{ matrix.os }}
19+
runs-on: ${{ matrix.os }}
20+
strategy:
21+
matrix:
22+
os: [ubuntu-latest, windows-latest]
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
26+
- name: Set up Go
27+
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
28+
with:
29+
go-version-file: 'go.mod'
30+
- name: Run tests
31+
run: make test
32+
- name: Run build
33+
run: make build

.github/workflows/release.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: release
2+
3+
on:
4+
push:
5+
branches:
6+
- '!*'
7+
tags:
8+
- v*.*.*
9+
10+
permissions:
11+
contents: write
12+
id-token: write
13+
attestations: write
14+
15+
jobs:
16+
goreleaser:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
21+
- name: Set up Go
22+
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
23+
with:
24+
go-version-file: 'go.mod'
25+
- name: Import GPG key
26+
id: import_gpg
27+
uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
28+
with:
29+
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
30+
passphrase: ${{ secrets.PASSPHRASE }}
31+
- name: Run GoReleaser
32+
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
33+
with:
34+
version: latest
35+
args: release
36+
env:
37+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
39+
- uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
40+
with:
41+
subject-path: 'dist/checksums.txt'

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# don't track built binary
2+
/tflint-ruleset-aws-meta

.goreleaser.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# This is an example goreleaser.yaml file with some sane defaults.
2+
# Make sure to check the documentation at http://goreleaser.com
3+
version: 2
4+
env:
5+
- CGO_ENABLED=0
6+
builds:
7+
- targets:
8+
- darwin_amd64
9+
- darwin_arm64
10+
- linux_386
11+
- linux_amd64
12+
- linux_arm
13+
- linux_arm64
14+
- windows_386
15+
- windows_amd64
16+
hooks:
17+
post:
18+
- mkdir -p ./dist/raw
19+
- cp "{{ .Path }}" "./dist/raw/{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
20+
archives:
21+
- id: zip
22+
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
23+
formats:
24+
- zip
25+
files:
26+
- none*
27+
checksum:
28+
name_template: 'checksums.txt'
29+
extra_files:
30+
- glob: ./dist/raw/*
31+
signs:
32+
- artifacts: checksum
33+
args: ["--batch", "-u", "{{ .Env.GPG_FINGERPRINT }}", "--output", "${signature}", "--detach-sign", "${artifact}"]
34+
release:
35+
github:

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 myerscode
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
default: build
2+
3+
test:
4+
go test ./...
5+
6+
build:
7+
go build
8+
9+
install: build
10+
mkdir -p ~/.tflint.d/plugins
11+
mv ./tflint-ruleset-aws-meta ~/.tflint.d/plugins

README.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# TFLint AWS Meta Ruleset
2+
3+
[![Build Status](https://github.com/myerscode/tflint-ruleset-aws-meta/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/myerscode/tflint-ruleset-aws-meta/actions)
4+
5+
A TFLint ruleset for AWS best practices, focusing on preventing hardcoded values and promoting flexible, maintainable Terraform code.
6+
7+
This ruleset helps enforce multi-region and multi-partition compatibility by detecting hardcoded AWS regions and partitions in your Terraform configurations. It provides comprehensive coverage across IAM policies, provider configurations, and all AWS resource types where hardcoded values prevent flexible deployments.
8+
9+
## Requirements
10+
11+
- TFLint v0.42+
12+
- Go v1.25
13+
14+
## Installation
15+
16+
TODO: This template repository does not contain release binaries, so this installation will not work. Please rewrite for your repository. See the "Building the plugin" section to get this template ruleset working.
17+
18+
You can install the plugin with `tflint --init`. Declare a config in `.tflint.hcl` as follows:
19+
20+
```hcl
21+
plugin "aws-multi" {
22+
enabled = true
23+
24+
version = "0.1.0"
25+
source = "github.com/myerscode/tflint-ruleset-aws-meta"
26+
}
27+
```
28+
29+
## Rules
30+
31+
|Name|Description|Severity|Enabled|Link|
32+
| --- | --- | --- | --- | --- |
33+
|aws_iam_role_policy_hardcoded_region|Validates that there are no hardcoded AWS regions in IAM role policy documents|WARNING|||
34+
|aws_iam_role_policy_hardcoded_partition|Validates that there are no hardcoded AWS partitions in IAM role policy documents|WARNING|||
35+
|aws_iam_policy_hardcoded_region|Validates that there are no hardcoded AWS regions in IAM policy documents|WARNING|||
36+
|aws_iam_policy_hardcoded_partition|Validates that there are no hardcoded AWS partitions in IAM policy documents|WARNING|||
37+
|aws_provider_hardcoded_region|Validates that there are no hardcoded AWS regions or credentials in provider configuration|WARNING|||
38+
39+
### Rule Details
40+
41+
#### aws_iam_role_policy_hardcoded_region
42+
43+
This rule checks `aws_iam_role_policy` resources for hardcoded AWS regions in policy documents. It examines both JSON policy strings and structured policy documents to detect:
44+
45+
- Hardcoded regions in ARNs within policy statements (e.g., `arn:aws:s3:::bucket/us-east-1/*`)
46+
- Direct region references in policy JSON
47+
48+
**Example violations:**
49+
```hcl
50+
resource "aws_iam_role_policy" "bad" {
51+
policy = jsonencode({
52+
Statement = [{
53+
Effect = "Allow"
54+
Action = "s3:GetObject"
55+
Resource = "arn:aws:s3:::bucket/us-east-1/*" # ❌ Hardcoded region
56+
}]
57+
})
58+
}
59+
```
60+
61+
**Recommended fix:**
62+
```hcl
63+
resource "aws_iam_role_policy" "good" {
64+
policy = jsonencode({
65+
Statement = [{
66+
Effect = "Allow"
67+
Action = "s3:GetObject"
68+
Resource = "arn:aws:s3:::bucket/${data.aws_region.current.name}/*" # ✅ Dynamic region
69+
}]
70+
})
71+
}
72+
```
73+
74+
#### aws_iam_role_policy_hardcoded_partition
75+
76+
This rule checks `aws_iam_role_policy` resources for hardcoded AWS partitions in policy documents. It detects:
77+
78+
- Hardcoded partitions in ARNs (e.g., `arn:aws:`, `arn:aws-cn:`, `arn:aws-us-gov:`)
79+
80+
**Example violations:**
81+
```hcl
82+
resource "aws_iam_role_policy" "bad" {
83+
policy = jsonencode({
84+
Statement = [{
85+
Effect = "Allow"
86+
Action = "s3:*"
87+
Resource = "arn:aws:s3:::bucket/*" # ❌ Hardcoded partition
88+
}]
89+
})
90+
}
91+
```
92+
93+
**Recommended fix:**
94+
```hcl
95+
resource "aws_iam_role_policy" "good" {
96+
policy = jsonencode({
97+
Statement = [{
98+
Effect = "Allow"
99+
Action = "s3:*"
100+
Resource = "arn:${data.aws_partition.current.partition}:s3:::bucket/*" # ✅ Dynamic partition
101+
}]
102+
})
103+
}
104+
```
105+
106+
#### aws_iam_policy_hardcoded_region
107+
108+
This rule checks `aws_iam_policy` resources for hardcoded AWS regions in policy documents. Similar to the role policy rule, it examines:
109+
110+
- Hardcoded regions in ARNs within policy statements
111+
- Direct region references in policy JSON
112+
113+
**Example violations:**
114+
```hcl
115+
resource "aws_iam_policy" "bad" {
116+
policy = jsonencode({
117+
Statement = [{
118+
Effect = "Allow"
119+
Action = "lambda:InvokeFunction"
120+
Resource = "arn:aws:lambda:eu-west-1:123456789012:function:*" # ❌ Hardcoded region
121+
}]
122+
})
123+
}
124+
```
125+
126+
**Recommended fix:**
127+
```hcl
128+
resource "aws_iam_policy" "good" {
129+
policy = jsonencode({
130+
Statement = [{
131+
Effect = "Allow"
132+
Action = "lambda:InvokeFunction"
133+
Resource = "arn:aws:lambda:${data.aws_region.current.name}:123456789012:function:*" # ✅ Dynamic region
134+
}]
135+
})
136+
}
137+
```
138+
139+
#### aws_iam_policy_hardcoded_partition
140+
141+
This rule checks `aws_iam_policy` resources for hardcoded AWS partitions in policy documents. It detects:
142+
143+
- Hardcoded partitions in ARNs within policy statements
144+
145+
**Example violations:**
146+
```hcl
147+
resource "aws_iam_policy" "bad" {
148+
policy = jsonencode({
149+
Statement = [{
150+
Effect = "Allow"
151+
Action = "sqs:*"
152+
Resource = "arn:aws-us-gov:sqs:*:*:*" # ❌ Hardcoded partition
153+
}]
154+
})
155+
}
156+
```
157+
158+
**Recommended fix:**
159+
```hcl
160+
resource "aws_iam_policy" "good" {
161+
policy = jsonencode({
162+
Statement = [{
163+
Effect = "Allow"
164+
Action = "sqs:*"
165+
Resource = "arn:${data.aws_partition.current.partition}:sqs:*:*:*" # ✅ Dynamic partition
166+
}]
167+
})
168+
}
169+
```
170+
171+
#### aws_provider_hardcoded_region
172+
173+
This rule checks AWS provider configurations for security and flexibility issues. It detects:
174+
175+
- Hardcoded regions in provider `region` attribute
176+
- Hardcoded AWS access keys and secret keys (security risk)
177+
- Hardcoded regions in `assume_role` ARNs
178+
179+
**Example violations:**
180+
```hcl
181+
provider "aws" {
182+
region = "us-east-1" # ❌ Hardcoded region
183+
}
184+
```
185+
186+
**Recommended fix:**
187+
```hcl
188+
provider "aws" {
189+
region = var.aws_region # ✅ Use variables
190+
}
191+
```
192+
193+

examples/failing/.tflint.hcl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
plugin "aws-multi" {
2+
enabled = true
3+
}
4+
5+
rule "aws_iam_role_policy_hardcoded_region" {
6+
enabled = true
7+
}
8+
9+
rule "aws_iam_role_policy_hardcoded_partition" {
10+
enabled = true
11+
}
12+
13+
rule "aws_iam_policy_hardcoded_region" {
14+
enabled = true
15+
}
16+
17+
rule "aws_iam_policy_hardcoded_partition" {
18+
enabled = true
19+
}
20+
21+
rule "aws_provider_hardcoded_region" {
22+
enabled = true
23+
}
24+
25+
rule "aws_hardcoded_region" {
26+
enabled = true
27+
}

0 commit comments

Comments
 (0)