You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求编写AWS环境校验Bash脚本(含PASS/FAIL判定)

AWS资源自动校验Bash脚本实现

输入文件格式

支持CSV或JSON两种格式,用于指定要校验的AWS账号、区域和资源筛选标签:

CSV示例

account_id,region,tag_key,tag_value,expected_ec2_type,expected_vpc_cidr
123456789012,us-east-1,Environment,Production,t3.medium,10.0.0.0/16
987654321098,eu-west-1,Project,MyApp,t3.small,192.168.0.0/16

JSON示例

[
  {
    "account_id": "123456789012",
    "region": "us-east-1",
    "tag_key": "Environment",
    "tag_value": "Production",
    "expected_ec2_type": "t3.medium",
    "expected_vpc_cidr": "10.0.0.0/16"
  }
]

核心校验脚本

#!/bin/bash
set -eo pipefail

# 配置预期校验规则(可根据需求修改)
EXPECTED_EC2_TERMINATION_PROTECTION="enabled"
EXPECTED_VPC_DNS_HOSTNAMES="enabled"
EXPECTED_S3_DEFAULT_ENCRYPTION="AES256"
EXPECTED_RDS_ENGINE_VERSION="8.0.mysql_aurora.3.03.2"
EXPECTED_REDIS_ENGINE_VERSION="7.0"

# 输出文件初始化
OUTPUT_FILE="aws-resource-validation-results.csv"
echo "timestamp,account_id,region,resource_type,resource_id,check_item,status,details" > $OUTPUT_FILE

# 日志函数
log_result() {
    local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
    echo "$timestamp,$1,$2,$3,$4,$5,$6,$7" >> $OUTPUT_FILE
}

# 切换AWS账号(假设使用STS AssumeRole,需提前配置权限)
switch_account() {
    local account_id=$1
    local region=$2
    # 替换为你的角色ARN模板
    local role_arn="arn:aws:iam::${account_id}:role/ResourceValidationRole"
    local session_name="validation-session-$(date +%s)"
    
    # 获取临时凭证
    local creds=$(aws sts assume-role --role-arn $role_arn --role-session-name $session_name --output json)
    export AWS_ACCESS_KEY_ID=$(echo $creds | jq -r '.Credentials.AccessKeyId')
    export AWS_SECRET_ACCESS_KEY=$(echo $creds | jq -r '.Credentials.SecretAccessKey')
    export AWS_SESSION_TOKEN=$(echo $creds | jq -r '.Credentials.SessionToken')
    export AWS_DEFAULT_REGION=$region
}

# 校验EC2实例
check_ec2() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4
    local expected_type=$5

    # 获取符合标签的EC2实例
    local instances=$(aws ec2 describe-instances --filters "Name=tag:$tag_key,Values=$tag_value" --output json)
    
    echo $instances | jq -r '.Reservations[].Instances[] | .InstanceId + "," + .InstanceType + "," + (.DisableApiTermination | tostring) + "," + .PrivateIpAddress' | while IFS=, read -r instance_id instance_type termination_protection private_ip; do
        # 校验实例类型
        if [ "$instance_type" = "$expected_type" ]; then
            log_result $account_id $region "EC2" $instance_id "Instance Type" "PASS" "Expected: $expected_type, Actual: $instance_type"
        else
            log_result $account_id $region "EC2" $instance_id "Instance Type" "FAIL" "Expected: $expected_type, Actual: $instance_type"
        fi

        # 校验终止保护
        if [ "$termination_protection" = "$EXPECTED_EC2_TERMINATION_PROTECTION" ]; then
            log_result $account_id $region "EC2" $instance_id "Termination Protection" "PASS" "Expected: $EXPECTED_EC2_TERMINATION_PROTECTION, Actual: $termination_protection"
        else
            log_result $account_id $region "EC2" $instance_id "Termination Protection" "FAIL" "Expected: $EXPECTED_EC2_TERMINATION_PROTECTION, Actual: $termination_protection"
        fi

        # 校验私有IP(可根据实际规则调整)
        log_result $account_id $region "EC2" $instance_id "Private IP" "PASS" "IP: $private_ip"
    done
}

# 校验VPC及子网
check_vpc() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4
    local expected_cidr=$5

    # 获取符合标签的VPC
    local vpcs=$(aws ec2 describe-vpcs --filters "Name=tag:$tag_key,Values=$tag_value" --output json)
    
    echo $vpcs | jq -r '.Vpcs[] | .VpcId + "," + .CidrBlock + "," + (.EnableDnsHostnames | tostring)' | while IFS=, read -r vpc_id cidr dns_hostnames; do
        # 校验VPC CIDR
        if [ "$cidr" = "$expected_cidr" ]; then
            log_result $account_id $region "VPC" $vpc_id "CIDR Block" "PASS" "Expected: $expected_cidr, Actual: $cidr"
        else
            log_result $account_id $region "VPC" $vpc_id "CIDR Block" "FAIL" "Expected: $expected_cidr, Actual: $cidr"
        fi

        # 校验DNS主机名状态
        if [ "$dns_hostnames" = "$EXPECTED_VPC_DNS_HOSTNAMES" ]; then
            log_result $account_id $region "VPC" $vpc_id "DNS Hostnames" "PASS" "Expected: $EXPECTED_VPC_DNS_HOSTNAMES, Actual: $dns_hostnames"
        else
            log_result $account_id $region "VPC" $vpc_id "DNS Hostnames" "FAIL" "Expected: $EXPECTED_VPC_DNS_HOSTNAMES, Actual: $dns_hostnames"
        fi

        # 校验子网CIDR归属
        local subnets=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" --output json)
        echo $subnets | jq -r '.Subnets[] | .SubnetId + "," + .CidrBlock' | while IFS=, read -r subnet_id subnet_cidr; do
            if [[ $subnet_cidr == $expected_cidr* ]]; then
                log_result $account_id $region "Subnet" $subnet_id "CIDR Block" "PASS" "Subnet CIDR: $subnet_cidr (within VPC CIDR $expected_cidr)"
            else
                log_result $account_id $region "Subnet" $subnet_id "CIDR Block" "FAIL" "Subnet CIDR: $subnet_cidr (not within VPC CIDR $expected_cidr)"
            fi
        done
    done
}

# 校验S3存储桶
check_s3() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4

    # 获取符合标签的S3桶
    local buckets=$(aws s3api list-buckets --output json | jq -r '.Buckets[] | .Name')
    for bucket in $buckets; do
        # 检查桶标签
        local tags=$(aws s3api get-bucket-tagging --bucket $bucket --output json 2>/dev/null || echo '{"TagSet":[]}')
        local has_tag=$(echo $tags | jq -r --arg k "$tag_key" --arg v "$tag_value" '.TagSet[] | select(.Key == $k and .Value == $v) | .Key')
        if [ -z "$has_tag" ]; then
            continue
        fi

        # 校验桶名称前缀规则
        if [[ $bucket == "prod-"* ]]; then
            log_result $account_id $region "S3" $bucket "Bucket Name" "PASS" "Name: $bucket (matches prefix rule)"
        else
            log_result $account_id $region "S3" $bucket "Bucket Name" "FAIL" "Name: $bucket (does not match prefix rule)"
        fi

        # 校验默认加密
        local encryption=$(aws s3api get-bucket-encryption --bucket $bucket --output json 2>/dev/null || echo '{}')
        local encryption_type=$(echo $encryption | jq -r '.ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault.SSEAlgorithm' || echo "None")
        if [ "$encryption_type" = "$EXPECTED_S3_DEFAULT_ENCRYPTION" ]; then
            log_result $account_id $region "S3" $bucket "Default Encryption" "PASS" "Type: $encryption_type"
        else
            log_result $account_id $region "S3" $bucket "Default Encryption" "FAIL" "Expected: $EXPECTED_S3_DEFAULT_ENCRYPTION, Actual: $encryption_type"
        fi

        # 校验复制规则
        local replication=$(aws s3api get-bucket-replication --bucket $bucket --output json 2>/dev/null || echo '{}')
        local replication_enabled=$(echo $replication | jq -r '.ReplicationConfiguration.Rules[] | .Status' || echo "Disabled")
        if [ "$replication_enabled" = "Enabled" ]; then
            log_result $account_id $region "S3" $bucket "Replication Rule" "PASS" "Status: Enabled"
        else
            log_result $account_id $region "S3" $bucket "Replication Rule" "FAIL" "Status: $replication_enabled"
        fi
    done
}

# 校验RDS实例
check_rds() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4

    # 获取符合标签的RDS实例
    local rds_instances=$(aws rds describe-db-instances --filters "Name=tag:$tag_key,Values=$tag_value" --output json)
    
    echo $rds_instances | jq -r '.DBInstances[] | .DBInstanceIdentifier + "," + .DBInstanceArn + "," + .Endpoint.Address + "," + .EngineVersion + "," + .DBInstanceStatus' | while IFS=, read -r rds_id arn endpoint version status; do
        # 校验ARN格式
        if [[ $arn == "arn:aws:rds:$region:$account_id:db:"* ]]; then
            log_result $account_id $region "RDS" $rds_id "ARN Format" "PASS" "ARN: $arn"
        else
            log_result $account_id $region "RDS" $rds_id "ARN Format" "FAIL" "ARN: $arn (invalid format)"
        fi

        # 校验引擎版本
        if [ "$version" = "$EXPECTED_RDS_ENGINE_VERSION" ]; then
            log_result $account_id $region "RDS" $rds_id "Engine Version" "PASS" "Expected: $EXPECTED_RDS_ENGINE_VERSION, Actual: $version"
        else
            log_result $account_id $region "RDS" $rds_id "Engine Version" "FAIL" "Expected: $EXPECTED_RDS_ENGINE_VERSION, Actual: $version"
        fi

        # 校验主实例状态
        if [ "$status" = "available" ]; then
            log_result $account_id $region "RDS" $rds_id "Primary Instance Status" "PASS" "Status: $status"
        else
            log_result $account_id $region "RDS" $rds_id "Primary Instance Status" "FAIL" "Status: $status"
        fi
    done
}

# 校验Redis(ElastiCache)
check_redis() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4

    # 获取符合标签的Redis集群
    local redis_clusters=$(aws elasticache describe-cache-clusters --filters "Name=tag:$tag_key,Values=$tag_value" --show-cache-node-info --output json)
    
    echo $redis_clusters | jq -r '.CacheClusters[] | .CacheClusterId + "," + .EngineVersion + "," + .CacheNodeType + "," + (.NumCacheNodes | tostring)' | while IFS=, read -r redis_id version node_type node_count; do
        # 校验引擎版本
        if [[ $version == "$EXPECTED_REDIS_ENGINE_VERSION"* ]]; then
            log_result $account_id $region "Redis" $redis_id "Engine Version" "PASS" "Expected: $EXPECTED_REDIS_ENGINE_VERSION, Actual: $version"
        else
            log_result $account_id $region "Redis" $redis_id "Engine Version" "FAIL" "Expected: $EXPECTED_REDIS_ENGINE_VERSION, Actual: $version"
        fi

        # 校验节点类型
        if [ "$node_type" = "cache.t3.medium" ]; then
            log_result $account_id $region "Redis" $redis_id "Node Type" "PASS" "Type: $node_type"
        else
            log_result $account_id $region "Redis" $redis_id "Node Type" "FAIL" "Expected: cache.t3.medium, Actual: $node_type"
        fi

        # 校验节点数量
        if [ "$node_count" -ge 2 ]; then
            log_result $account_id $region "Redis" $redis_id "Node Count" "PASS" "Count: $node_count"
        else
            log_result $account_id $region "Redis" $redis_id "Node Count" "FAIL" "Expected: >=2, Actual: $node_count"
        fi
    done
}

# 校验ALB
check_alb() {
    local account_id=$1
    local region=$2
    local tag_key=$3
    local tag_value=$4

    # 获取符合标签的ALB
    local albs=$(aws elbv2 describe-load-balancers --filters "Name=tag:$tag_key,Values=$tag_value" --output json)
    
    echo $albs | jq -r '.LoadBalancers[] | .LoadBalancerArn + "," + .DNSName' | while IFS=, read -r alb_arn dns_name; do
        # 校验DNS名称格式
        if [[ $dns_name == *.elb.amazonaws.com ]]; then
            log_result $account_id $region "ALB" $alb_arn "DNS Name" "PASS" "DNS: $dns_name"
        else
            log_result $account_id $region "ALB" $alb_arn "DNS Name" "FAIL" "DNS: $dns_name (invalid format)"
        fi

        # 校验HTTPS监听器
        local listeners=$(aws elbv2 describe-listeners --load-balancer-arn $alb_arn --output json)
        local has_https=$(echo $listeners | jq -r '.Listeners[] | select(.Protocol == "HTTPS") | .Protocol')
        if [ -n "$has_https" ]; then
            log_result $account_id $region "ALB" $alb_arn "HTTPS Listener" "PASS" "HTTPS listener exists"
        else
            log_result $account_id $region "ALB" $alb_arn "HTTPS Listener" "FAIL" "HTTPS listener not found"
        fi
    done
}

# 解析输入文件并执行校验
process_input() {
    local input_file=$1
    if [[ $input_file == *.json ]]; then
        # 处理JSON输入
        jq -r '.[] | [.account_id, .region, .tag_key, .tag_value, .expected_ec2_type, .expected_vpc_cidr] | @csv' $input_file | while IFS=, read -r account_id region tag_key tag_value expected_ec2_type expected_vpc_cidr; do
            echo "Processing account $account_id in region $region..."
            switch_account $account_id $region
            check_ec2 $account_id $region $tag_key $tag_value $expected_ec2_type
            check_vpc $account_id $region $tag_key $tag_value $expected_vpc_cidr
            check_s3 $account_id $region $tag_key $tag_value
            check_rds $account_id $region $tag_key $tag_value
            check_redis $account_id $region $tag_key $tag_value
            check_alb $account_id $region $tag_key $tag_value
        done
    elif [[ $input_file == *.csv ]]; then
        # 处理CSV输入(跳过表头)
        tail -n +2 $input_file | while IFS=, read -r account_id region tag_key tag_value expected_ec2_type expected_vpc_cidr; do
            echo "Processing account $account_id in region $region..."
            switch_account $account_id $region
            check_ec2 $account_id $region $tag_key $tag_value $expected_ec2_type
            check_vpc $account_id $region $tag_key $tag_value $expected_vpc_cidr
            check_s3 $account_id $region $tag_key $tag_value
            check_rds $account_id $region $tag
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 00:05:46