ci(terraform): update bootstrap & landingzone pipelines and add validation/notification scripts
This commit is contained in:
parent
64cb67d4ba
commit
9ae1d2bf84
@ -46,17 +46,17 @@ jobs:
|
||||
|
||||
- name: Init
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform init -upgrade
|
||||
run: make init
|
||||
|
||||
- name: Plan
|
||||
if: env.DRY_RUN == 'true'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform plan -no-color
|
||||
run: make plan
|
||||
|
||||
- name: Apply
|
||||
if: env.DRY_RUN == 'false'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform apply -auto-approve
|
||||
run: make apply
|
||||
|
||||
- name: Save Outputs
|
||||
if: env.DRY_RUN == 'false'
|
||||
|
||||
@ -25,55 +25,21 @@ env:
|
||||
DEPLOY_ACTION: ${{ github.event.inputs.deploy_action || 'plan' }}
|
||||
DEPLOY_DRY_RUN: ${{ github.event.inputs.deploy_dry_run || 'true' }}
|
||||
|
||||
# -------------------------------
|
||||
# SMTP settings (明文可接受)
|
||||
# -------------------------------
|
||||
SMTP_HOST: smtp.qq.com
|
||||
SMTP_PORT: 465
|
||||
SMTP_FROM: "XControl Account <manbuzhe2009@qq.com>"
|
||||
SMTP_REPLY_TO: "no-reply@svc.plus"
|
||||
TO_EMAIL: "manbuzhe2009@qq.com"
|
||||
|
||||
jobs:
|
||||
# -------------------------------------------------------
|
||||
# 1. Bootstrap Stage (Matrix)
|
||||
# -------------------------------------------------------
|
||||
bootstrap:
|
||||
name: "Bootstrap: DynamoDB / S3 / IAM"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- bootstrap-dynamodb
|
||||
- bootstrap-s3
|
||||
- bootstrap-iam
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: hashicorp/setup-terraform@v3
|
||||
with:
|
||||
terraform_version: 1.9.5
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v4
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ secrets.AWS_REGION }}
|
||||
|
||||
- name: Terraform Init
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform init -upgrade
|
||||
|
||||
- name: Terraform Plan (bootstrap)
|
||||
if: env.DEPLOY_DRY_RUN == 'true'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform plan -no-color
|
||||
|
||||
- name: Terraform Apply (bootstrap)
|
||||
if: env.DEPLOY_DRY_RUN == 'false'
|
||||
working-directory: ${{ env.TF_WORKDIR }}/${{ matrix.target }}
|
||||
run: terraform apply -auto-approve
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 2. Landing Zone Baseline Stage
|
||||
# 1. Landing Zone Baseline Stage
|
||||
# -------------------------------------------------------
|
||||
landingzone:
|
||||
name: "Deploy LandingZone Baseline"
|
||||
needs: bootstrap
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@ -111,7 +77,7 @@ jobs:
|
||||
run: terraform apply -auto-approve
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 3. Validation Stage
|
||||
# 2. Validation Stage
|
||||
# -------------------------------------------------------
|
||||
validation:
|
||||
name: "Validate LandingZone Baseline"
|
||||
@ -129,7 +95,7 @@ jobs:
|
||||
${{ env.TF_WORKDIR }}/envs/dev-landingzone
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 4. Delivery / Notification Stage
|
||||
# 3. Delivery / Notification Stage
|
||||
# -------------------------------------------------------
|
||||
delivery:
|
||||
name: "Delivery: Notify Rollout"
|
||||
@ -140,7 +106,10 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Notify
|
||||
env:
|
||||
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }} # <-- 仅密码从 secret
|
||||
SMTP_USERNAME: "manbuzhe2009@qq.com"
|
||||
run: |
|
||||
echo "📣 Sending LandingZone rollout notification..."
|
||||
chmod +x scripts/notifications/notify-landingzone.sh
|
||||
scripts/notifications/notify-landingzone.sh
|
||||
./scripts/notifications/notify-landingzone.sh
|
||||
|
||||
76
scripts/notifications/notify-landingzone.sh
Normal file
76
scripts/notifications/notify-landingzone.sh
Normal file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# -----------------------------
|
||||
# SMTP CONFIG (from GH secrets)
|
||||
# -----------------------------
|
||||
SMTP_HOST="${SMTP_HOST:-smtp.qq.com}"
|
||||
SMTP_PORT="${SMTP_PORT:-465}"
|
||||
SMTP_USERNAME="${SMTP_USERNAME:-manbuzhe2009@qq.com}"
|
||||
SMTP_PASSWORD="${SMTP_PASSWORD:?SMTP_PASSWORD missing from GitHub secrets}"
|
||||
SMTP_FROM="${SMTP_FROM:-XControl Account <manbuzhe2009@qq.com>}"
|
||||
SMTP_REPLY_TO="${SMTP_REPLY_TO:-no-reply@svc.plus}"
|
||||
|
||||
TO_EMAIL="${TO_EMAIL:-manbuzhe2009@qq.com}"
|
||||
SUBJECT="AWS LandingZone Baseline Deployment Completed"
|
||||
|
||||
# -----------------------------
|
||||
# EMAIL BODY (HTML)
|
||||
# -----------------------------
|
||||
BODY_HTML=$(cat <<EOF
|
||||
<html>
|
||||
<body>
|
||||
<h2>🚀 AWS LandingZone Baseline Rollout Completed</h2>
|
||||
<p>The baseline deployment for <b>LandingZone Minimal</b> has successfully finished.</p>
|
||||
<p><b>Environment:</b> dev-landingzone<br/>
|
||||
<b>Workdir:</b> iac-template/terraform-standard</p>
|
||||
|
||||
<p>This includes:</p>
|
||||
<ul>
|
||||
<li>IAM Baseline Group</li>
|
||||
<li>Deny Root (Partial IAM enforcement)</li>
|
||||
<li>MFA Enforcement</li>
|
||||
<li>Disable Console Write</li>
|
||||
<li>Restrict RI/SP Purchases</li>
|
||||
</ul>
|
||||
|
||||
<p>Regards,<br/>XControl CI/CD</p>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
)
|
||||
|
||||
# -----------------------------
|
||||
# BUILD RAW MESSAGE
|
||||
# -----------------------------
|
||||
MESSAGE=$(cat <<EOF
|
||||
From: ${SMTP_FROM}
|
||||
To: ${TO_EMAIL}
|
||||
Reply-To: ${SMTP_REPLY_TO}
|
||||
Subject: ${SUBJECT}
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
|
||||
${BODY_HTML}
|
||||
EOF
|
||||
)
|
||||
|
||||
# -----------------------------
|
||||
# SEND VIA IMPLICIT TLS (465)
|
||||
# -----------------------------
|
||||
echo "📨 Sending LandingZone Email Notification..."
|
||||
|
||||
(
|
||||
echo "EHLO smtp.qq.com"
|
||||
echo "AUTH LOGIN"
|
||||
echo -ne "$(printf '%s' "${SMTP_USERNAME}" | base64)\r\n"
|
||||
echo -ne "$(printf '%s' "${SMTP_PASSWORD}" | base64)\r\n"
|
||||
echo "MAIL FROM:<${SMTP_USERNAME}>"
|
||||
echo "RCPT TO:<${TO_EMAIL}>"
|
||||
echo "DATA"
|
||||
echo "${MESSAGE}"
|
||||
echo "."
|
||||
echo "QUIT"
|
||||
) | openssl s_client -quiet -crlf -connect "${SMTP_HOST}:${SMTP_PORT}"
|
||||
|
||||
echo "✅ Notification sent."
|
||||
97
scripts/validation/validate-landingzone.sh
Normal file
97
scripts/validation/validate-landingzone.sh
Normal file
@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
TARGET_ENV_PATH="$1"
|
||||
|
||||
echo "🔍 Validating AWS LandingZone Baseline..."
|
||||
echo "Target path: $TARGET_ENV_PATH"
|
||||
echo "Region: ${AWS_REGION}"
|
||||
|
||||
# -------------------------
|
||||
# Check 1: IAM Group Exists
|
||||
# -------------------------
|
||||
echo -n "Checking IAM group LandingZoneBaseline... "
|
||||
if aws iam get-group --group-name LandingZoneBaseline >/dev/null 2>&1; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAILED"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# -----------------------------
|
||||
# Check 2: Required Policies
|
||||
# -----------------------------
|
||||
REQUIRED_POLICIES=(
|
||||
"landingzone-deny-root"
|
||||
"landingzone-deny-no-mfa"
|
||||
"landingzone-deny-console-write"
|
||||
"landingzone-deny-ri-sp"
|
||||
)
|
||||
|
||||
echo "Checking IAM baseline policies..."
|
||||
for p in "${REQUIRED_POLICIES[@]}"; do
|
||||
echo -n " - $p ... "
|
||||
if aws iam list-policies --scope Local --query "Policies[?PolicyName=='$p']" --output text | grep "$p" >/dev/null; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAILED"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# -----------------------------
|
||||
# Check 3: Policy Attachments
|
||||
# -----------------------------
|
||||
echo "Checking policy attachments..."
|
||||
for p in "${REQUIRED_POLICIES[@]}"; do
|
||||
ARN=$(aws iam list-policies --scope Local --query "Policies[?PolicyName=='$p'].Arn" --output text)
|
||||
|
||||
echo -n " - $p attached ... "
|
||||
if aws iam list-attached-group-policies \
|
||||
--group-name LandingZoneBaseline \
|
||||
--query "AttachedPolicies[?PolicyArn=='$ARN']" \
|
||||
--output text | grep "$p" >/dev/null; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAILED"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# -----------------------------
|
||||
# Check 4: Terraform State Exists
|
||||
# -----------------------------
|
||||
echo -n "Checking Terraform state presence... "
|
||||
if test -f "${TARGET_ENV_PATH}/terraform.tfstate"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "OK (remote backend)"
|
||||
fi
|
||||
|
||||
# -----------------------------
|
||||
# Check 5: root AccessKey
|
||||
# -----------------------------
|
||||
echo -n "Checking root AccessKey... "
|
||||
ROOT_KEYS=$(aws iam list-access-keys --user-name root 2>/dev/null || true)
|
||||
|
||||
if [[ -z "$ROOT_KEYS" ]]; then
|
||||
echo "OK (none)"
|
||||
else
|
||||
echo "FAILED (root has access keys!)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# -----------------------------
|
||||
# Check 6: MFA Enforcement (Account Summary)
|
||||
# -----------------------------
|
||||
echo -n "Checking MFA requirement... "
|
||||
MFA=$(aws iam get-account-summary --query "SummaryMap.AccountMFAEnabled" --output text)
|
||||
|
||||
if [[ "$MFA" == "1" ]]; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "WARNING (Account MFA not enforced globally)"
|
||||
fi
|
||||
|
||||
echo "✅ LandingZone baseline validation PASSED"
|
||||
exit 0
|
||||
Loading…
Reference in New Issue
Block a user