DevOps Security Strategy Design

Designs a comprehensive DevOps security strategy for specified infrastructure, including secret management, IAM configuration, and network security best practices.

How to use

Provide details about your infrastructure in the {{args}} placeholder. The AI will then design a comprehensive DevOps security strategy, covering secret management, IAM configuration, and network security, with examples using AWS and HashiCorp Vault.

Prompt

Design DevOps Security Strategy

Please design a comprehensive security strategy for the following infrastructure:

{{args}}

DevOps Security Framework

1. Secret Management

AWS Secrets Manager

# secrets/secrets-manager.tf
resource "aws_secretsmanager_secret" "db_credentials" {
  name        = "${var.project_name}/db/credentials"
  description = "Database credentials"
  
  recovery_window_in_days = 30
  
  rotation_rules {
    automatically_after_days = 30
  }
}

resource "aws_secretsmanager_secret_version" "db_credentials" {
  secret_id = aws_secretsmanager_secret.db_credentials.id
  
  secret_string = jsonencode({
    username = "admin"
    password = random_password.db_password.result
    host     = aws_db_instance.main.endpoint
    port     = 5432
    database = var.project_name
  })
}

resource "aws_secretsmanager_secret_rotation" "db_credentials" {
  secret_id = aws_secretsmanager_secret.db_credentials.id
  
  rotation_lambda_arn = aws_lambda_function.secret_rotation.arn
  
  rotation_rules {
    automatically_after_days = 30
  }
}

HashiCorp Vault

# kubernetes/vault-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vault-secrets
  namespace: production
type: Opaque
stringData:
  VAULT_ADDR: "https://vault.example.com"
  VAULT_ROLE_ID: "${vault_role_id}"
  VAULT_SECRET_ID: "${vault_secret_id}"
---
# vault-policy.hcl
path "secret/data/myapp/*" {
  capabilities = ["read", "write", "delete"]
}

path "secret/metadata/myapp/*" {
  capabilities = ["list", "read"]
}

2. IAM Configuration

IAM Roles

# iam/roles.tf
resource "aws_iam_role" "app_role" {
  name = "${var.project_name}-app-role-${var.environment}"
  
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_policy" "s3_readonly" {
  name = "${var.project_name}-s3-readonly-${var.environment}"
  
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "s3:GetObject",
          "s3:GetObjectVersion",
          "s3:ListBucket"
        ]
        Effect = "Allow"
        Resource = [
          aws_s3_bucket.app_data.arn,
          "${aws_s3_bucket.app_data.arn}/*"
        ]
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "s3_readonly" {
  role       = aws_iam_role.app_role.name
  policy_arn = aws_iam_policy.s3_readonly.arn
}

resource "aws_iam_role_policy_attachment" "cloudwatch_full" {
  role       = aws_iam_role.app_role.name
  policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}

# EKS Service Account
resource "aws_iam_role" "eks_app_role" {
  name = "${var.project_name}-eks-app-role-${var.environment}"
  
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRoleWithWebIdentity"
        Effect = "Allow"
        Principal = {
          Federated = aws_iam_openid_connect_provider.eks.arn
        }
        Condition = {
          StringEquals = {
            "${local.eks_oidc_domain}:sub" : "system:serviceaccount:production:app-sa"
          }
        }
      }
    ]
  })
}

3. Network Security

Security Groups

# security/security-groups.tf
resource "aws_security_group" "app" {
  name        = "${var.project_name}-app-sg-${var.environment}"
  description = "Application security group"
  vpc_id      = aws_vpc.main.id
  
  # Only allow traffic from ALB
  ingress {
    from_port       = 3000
    to_port         = 3000
    protocol        = "tcp"
    security_groups = [aws_security_group.alb.id]
  }
  
  # Allow outbound only to specific destinations
  egress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = [aws_vpc.main.cidr_block]
  }
  
  # Deny all other traffic
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

4. Container Security

Security Context

# kubernetes/security-context.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
        privileged: false
        seccompProfile:
          type: RuntimeDefault
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 512Mi

5. Image Scanning

Trivy in CI/CD

# .github/workflows/security-scan.yml
name: Security Scan

on:
  push:
    branches: [main]
  pull_request:

jobs:
  trivy-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          scan-ref: '.'
          format: 'sarif'
          output: 'trivy-results.sarif'
      
      - name: Upload Trivy results
        uses: github/codeql-action/upload-sarif@v2
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'

6. Vulnerability Scanning

AWS Inspector

# security/inspector.tf
resource "aws_inspector_assessment_target" "main" {
  name = "${var.project_name}-assessment-${var.environment}"
  
  resource_group_arn = aws_inspector_resource_group.main.arn
}

resource "aws_inspector_resource_group" "main" {
  name = "${var.project_name}-resource-group-${var.environment}"
  
  tag {
    key   = "Environment"
    value = var.environment
  }
}

resource "aws_inspector_assessment_template" "main" {
  name          = "${var.project_name}-template-${var.environment}"
  duration      = 3600
  rules_package_arns = [
    "arn:aws:inspector:us-east-1:315206903105:rulespackage/0-X9KSLQJD",
    "arn:aws:inspector:us-east-1:315206903105:rulespackage/0-L6YSr4iZ",
  ]
  target = aws_inspector_assessment_target.main.arn
}

7. Compliance as Code

OPA Gatekeeper

# kubernetes/gatekeeper-constraints.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPAllowPrivilegeEscalationContainer
metadata:
  name: psp-allow-privilege-escalation-container
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPRunAsRoot
metadata:
  name: psp-run-as-root
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  parameters:
    exemptImages:
      - "trusted-image:latest"

8. Encryption Configuration

KMS Keys

# security/kms.tf
resource "aws_kms_key" "app_key" {
  description             = "KMS key for ${var.project_name}"
  key_usage              = "ENCRYPT_DECRYPT"
  customer_master_key_spec = "SYMMETRIC_DEFAULT"
  
  enable_key_rotation = true
  
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid = "Enable IAM policies for key management"
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${var.account_id}:root"
        }
        Action = "kms:*"
        Resource = "*"
      },
      {
        Sid = "Allow app role to use key for encryption"
        Effect = "Allow"
        Principal = {
          AWS = aws_iam_role.app_role.arn
        }
        Action = [
          "kms:Encrypt",
          "kms:Decrypt",
          "kms:GenerateDataKey*"
        ]
        Resource = "*"
      }
    ]
  })
}

resource "aws_kms_alias" "app_key_alias" {
  name          = "alias/${var.project_name}-key-${var.environment}"
  target_key_id = aws_kms_key.app_key.key_id
}

9. Audit Logging

CloudTrail

# security/cloudtrail.tf
resource "aws_cloudtrail" "main" {
  name           = "${var.project_name}-trail-${var.environment}"
  s3_bucket_name = aws_s3_bucket.cloudtrail.id
  s3_key_prefix  = "audit-logs/"
  
  include_global_service_events = true
  is_multi_region_trail         = var.environment == "prod"
  
  enable_log_file_validation = true
  
  event_selector {
    read_write_type = "All"
    include_management_events = true
    
    data_resource {
      type   = "AWS::S3::Object"
      values = ["arn:aws:s3:::${var.bucket_name}/*"]
    }
  }
  
  tags = {
    Name        = "${var.project_name}-cloudtrail"
    Environment = var.environment
  }
}

resource "aws_s3_bucket" "cloudtrail" {
  bucket = "${var.project_name}-cloudtrail-${var.environment}"
  
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        kms_master_key_id = aws_kms_key.cloudtrail_key.arn
        sse_algorithm     = "aws:kms"
      }
    }
  }
  
  lifecycle_rule {
    enabled = true
    transition {
      days          = 90
      storage_class = "STANDARD_IA"
    }
    transition {
      days          = 365
      storage_class = "GLACIER"
    }
  }
  
  versioning {
    enabled = true
  }
}

10. WAF Configuration

AWS WAF

# security/waf.tf
resource "aws_wafv2_web_acl" "main" {
  name        = "${var.project_name}-waf-${var.environment}"
  description = "WAF for ${var.project_name}"
  scope       = "REGIONAL"
  
  default_action {
    allow {}
  }
  
  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 1
    
    statement {
      managed_rule_group_statement {
        vendor_name = "AWS"
        name        = "CommonRuleSet"
      }
    }
    
    override_action {
      none {}
    }
    
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name              = "CommonRuleSet"
    }
  }
  
  rule {
    name     = "RateLimit100"
    priority = 2
    
    statement {
      rate_based_statement {
        limit              = 100
        aggregate_key_type = "IP"
      }
    }
    
    action {
      block {
        custom_response {
          response_code = 429
          response_body_content = "{\"error\":\"Too many requests\"}"
        }
      }
    }
    
    visibility_config {
      sampled_requests_enabled = true
      cloudwatch_metrics_enabled = true
      metric_name              = "RateLimit"
    }
  }
  
  visibility_config {
    sampled_requests_enabled = true
    cloudwatch_metrics_enabled = true
    metric_name              = "WebACL"
  }
}

resource "aws_wafv2_web_acl_association" "main" {
  resource_arn = aws_lb.main.arn
  web_acl_arn  = aws_wafv2_web_acl.main.arn
}

11. Output Format

Provide:

  1. Secret Management: Secure handling of credentials
  2. IAM Configuration: Least privilege access
  3. Network Security: Firewall rules and segmentation
  4. Container Security: Pod security policies
  5. Image Scanning: Vulnerability detection
  6. Encryption: At-rest and in-transit encryption
  7. Audit Logging: Comprehensive logging
  8. WAF: Web application firewall rules
  9. Compliance: Policy enforcement
  10. Incident Response: Security procedures

Generate a complete, production-ready security strategy for DevOps.