Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
410 changes: 410 additions & 0 deletions cmd/check.go

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions cmd/infraspec/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"errors"
"fmt"
"os"

Expand All @@ -9,6 +10,12 @@ import (

func main() {
if err := cmd.RootCmd.Execute(); err != nil {
// Check if this is an ExitError (silent exit with code)
var exitErr cmd.ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.Code)
}

fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
Expand Down
77 changes: 77 additions & 0 deletions examples/gatekeeper/.github/workflows/infraspec-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Terraform Security Check

on:
pull_request:
paths:
- '**.tf'
- '**.tfvars'

jobs:
infraspec-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install InfraSpec
run: |
# Download latest release
curl -sSL https://github.com/robmorgan/infraspec/releases/latest/download/infraspec-linux-amd64 -o infraspec
chmod +x infraspec
sudo mv infraspec /usr/local/bin/

- name: Run InfraSpec Check
id: check
run: |
# Run checks and capture output
infraspec check ./terraform --format json > results.json || true

# Extract violation count
VIOLATIONS=$(jq '.summary.violations.total' results.json)
ERRORS=$(jq '.summary.violations.errors' results.json)

echo "violations=$VIOLATIONS" >> $GITHUB_OUTPUT
echo "errors=$ERRORS" >> $GITHUB_OUTPUT

# Show text output
infraspec check ./terraform || true

- name: Comment on PR
if: steps.check.outputs.violations > 0
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('results.json'));

let body = '## InfraSpec Security Check\n\n';

if (results.passed) {
body += '✅ All security checks passed!\n\n';
} else {
body += '❌ Security violations found\n\n';
body += `**${results.summary.violations.total}** violations (${results.summary.violations.errors} errors, ${results.summary.violations.warnings} warnings)\n\n`;

body += '### Violations\n\n';
for (const v of results.violations) {
const emoji = v.severity === 'error' ? '🔴' : v.severity === 'warning' ? '🟡' : '🔵';
body += `${emoji} **${v.rule_id}**: ${v.rule_name}\n`;
body += ` - Resource: \`${v.resource_type}.${v.resource_name}\`\n`;
body += ` - File: \`${v.file}:${v.line}\`\n`;
body += ` - ${v.message}\n\n`;
}
}

body += `\n---\n_Generated by [InfraSpec Gatekeeper](https://github.com/robmorgan/infraspec)_`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});

- name: Fail if errors
if: steps.check.outputs.errors > 0
run: |
echo "Found ${{ steps.check.outputs.errors }} error-level violations"
exit 1
43 changes: 43 additions & 0 deletions examples/gatekeeper/.infraspec.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# InfraSpec Configuration
# This file configures InfraSpec Gatekeeper for this repository

config {
min_severity = "warning" # Report warnings and errors
format = "text" # Output format (text, json)
strict = false # Don't treat unknowns as violations
# no_builtin = false # Use built-in rules
}

# You can also define rules directly in this file
# These rules apply to all Terraform files in the repository

rule "REPO_001" {
name = "All S3 buckets must have tags"
description = "Repository policy: all S3 buckets must have at least one tag"
severity = "warning"
resource_type = "aws_s3_bucket"

condition {
check {
attribute = "tags"
operator = "exists"
}
}

message = "S3 bucket '{{.resource_name}}' has no tags defined"

remediation = <<-EOT
Add tags to your S3 bucket:

resource "aws_s3_bucket" "example" {
bucket = "my-bucket"

tags = {
Name = "my-bucket"
Environment = "production"
}
}
EOT

tags = ["tagging", "repository-policy"]
}
Loading