Skip to content

CID Modules

CID Modules #323

name: Terraform Test Deployment
on:
pull_request:
branches:
- "*"
permissions:
id-token: write
contents: read
jobs:
test-deployment:
runs-on: ubuntu-latest
env:
DATABASE_NAME: cid_data_export
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y bats jq
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Get CID versions
id: versions
run: |
# Extract CID CFN version from local cid-cfn.yml file (line 3)
CFN_VERSION=$(sed -n '3p' ./cfn-templates/cid-cfn.yml | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/v//' || echo "1.0.0")
echo "cid_cfn_version=$CFN_VERSION" >> $GITHUB_OUTPUT
echo "Using local CID CFN version: $CFN_VERSION"
# Get latest data export version from external S3 public URL
EXPORT_VERSION=$(curl -s https://raw.githubusercontent.com/aws-solutions-library-samples/cloud-intelligence-dashboards-data-collection/main/data-exports/deploy/data-exports-aggregation.yaml | grep Description | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1 || echo "0.5.0")
echo "data_export_version=$EXPORT_VERSION" >> $GITHUB_OUTPUT
echo "Using latest data export version: $EXPORT_VERSION"
- name: Create terraform.tfvars file
run: |
cat > ./terraform/cicd-deployment/terraform.tfvars << EOF
global_values = {
destination_account_id = "${{ secrets.AWS_ACCOUNT_ID }}"
source_account_ids = "${{ secrets.AWS_ACCOUNT_ID }}"
aws_region = "${{ secrets.AWS_REGION_TF }}"
quicksight_user = "${{ secrets.QUICKSIGHT_USER }}"
cid_cfn_version = "${{ steps.versions.outputs.cid_cfn_version }}"
data_export_version = "${{ steps.versions.outputs.data_export_version }}"
environment = "dev"
}
EOF
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE }}
aws-region: ${{ secrets.AWS_REGION_TF }}
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Initialize Terraform
working-directory: ./terraform/cicd-deployment
run: |
cat > backend.tf << EOF
terraform {
backend "s3" {
bucket = "${{ secrets.BACKEND_S3_BUCKET }}"
key = "terraform/cid-test/terraform.tfstate"
region = "${{ secrets.AWS_REGION }}"
encrypt = true
}
}
EOF
cat > providers.tf << EOF
provider "aws" {
alias = "management"
region = "${{ secrets.AWS_REGION_TF }}"
}
provider "aws" {
alias = "datacollection"
region = "${{ secrets.AWS_REGION_TF }}"
}
EOF
terraform fmt terraform.tfvars backend.tf providers.tf
terraform init
- name: Terraform Format Check
working-directory: ./terraform/cicd-deployment
run: terraform fmt -check -recursive
- name: Terraform Validate
working-directory: ./terraform/cicd-deployment
run: terraform validate
- name: Check for existing stacks and cleanup if needed
run: |
export RESOURCE_PREFIX="cid-tf"
export BACKEND_TYPE="s3"
export S3_BUCKET="${{ secrets.BACKEND_S3_BUCKET }}"
export S3_KEY="terraform/cid-test/terraform.tfstate"
export S3_REGION="${{ secrets.AWS_REGION_TF }}"
export BACKEND_REGION="${{ secrets.AWS_REGION }}"
# Check for existing CloudFormation stacks
# Foundational stacks
FOUNDATIONAL_STACKS=("CID-DataExports-Destination" "Cloud-Intelligence-Dashboards")
# Additional CUR-based dashboard stacks
ADDITIONAL_STACKS=("Trends-Dashboard" "DataTransfer-Cost-Analysis-Dashboard" "AWS-Marketplace-SPG-Dashboard" "Amazon-Connect-Cost-Insight-Dashboard" "SCAD-Containers-Cost-Allocation-Dashboard")
# Other optional stacks
OTHER_STACKS=("CID-DataExports-Source" "CID-DataCollection" "CID-OptimizationDataCollection")
# All stacks to check
STACKS_TO_CHECK=("${FOUNDATIONAL_STACKS[@]}" "${ADDITIONAL_STACKS[@]}" "${OTHER_STACKS[@]}")
GOOD_STATES=("CREATE_COMPLETE" "UPDATE_COMPLETE")
FAILED_STATES=("CREATE_FAILED" "ROLLBACK_COMPLETE" "ROLLBACK_FAILED" "DELETE_FAILED" "UPDATE_ROLLBACK_COMPLETE" "UPDATE_ROLLBACK_FAILED" "IMPORT_ROLLBACK_COMPLETE" "IMPORT_ROLLBACK_FAILED")
IN_PROGRESS_STATES=("CREATE_IN_PROGRESS" "DELETE_IN_PROGRESS" "UPDATE_IN_PROGRESS" "UPDATE_ROLLBACK_IN_PROGRESS" "REVIEW_IN_PROGRESS" "IMPORT_IN_PROGRESS" "IMPORT_ROLLBACK_IN_PROGRESS")
FOUND_STACKS=()
GOOD_STACKS=()
FAILED_STACKS=()
IN_PROGRESS_STACKS=()
for stack in "${STACKS_TO_CHECK[@]}"; do
if STACK_STATUS=$(aws cloudformation describe-stacks --stack-name "$stack" --region "${{ secrets.AWS_REGION_TF }}" --query 'Stacks[0].StackStatus' --output text 2>/dev/null); then
echo "Found existing stack: $stack (Status: $STACK_STATUS)"
FOUND_STACKS+=("$stack")
if [[ " ${GOOD_STATES[*]} " =~ " ${STACK_STATUS} " ]]; then
GOOD_STACKS+=("$stack")
elif [[ " ${FAILED_STATES[*]} " =~ " ${STACK_STATUS} " ]]; then
FAILED_STACKS+=("$stack")
elif [[ " ${IN_PROGRESS_STATES[*]} " =~ " ${STACK_STATUS} " ]]; then
IN_PROGRESS_STACKS+=("$stack")
fi
fi
done
if [ ${#FOUND_STACKS[@]} -gt 0 ]; then
# Handle in-progress stacks first
if [ ${#IN_PROGRESS_STACKS[@]} -gt 0 ]; then
echo "ERROR: Found stacks in progress states:"
for stack in "${IN_PROGRESS_STACKS[@]}"; do
echo " - $stack"
done
echo "Cannot proceed while stacks are in progress. Please wait for completion."
exit 1
# Auto-cleanup if any stacks are in failed states
elif [ ${#FAILED_STACKS[@]} -gt 0 ]; then
echo "Found stacks in failed states. Auto-cleaning up:"
for stack in "${FAILED_STACKS[@]}"; do
echo " - $stack"
done
echo "Running cleanup..."
bash ./terraform/terraform-test/cleanup.sh
echo "Cleanup completed. Proceeding with fresh deployment..."
# Auto-cleanup for any existing stacks (CI/CD should always start fresh)
else
echo "Found existing stacks (${#GOOD_STACKS[@]} total). Auto-cleaning up for fresh CI/CD deployment:"
for stack in "${GOOD_STACKS[@]}"; do
echo " - $stack"
done
bash ./terraform/terraform-test/cleanup.sh
echo "Cleanup completed. Proceeding with fresh deployment..."
fi
else
echo "No existing stacks found. Proceeding with fresh deployment."
fi
- name: Run deploy script
run: |
export DATABASE_NAME="cid_data_export"
export RESOURCE_PREFIX="cid-tf"
export BACKEND_TYPE="s3"
export S3_BUCKET="${{ secrets.BACKEND_S3_BUCKET }}"
export S3_KEY="terraform/cid-test/terraform.tfstate"
export S3_REGION="${{ secrets.AWS_REGION_TF }}"
export BACKEND_REGION="${{ secrets.AWS_REGION }}"
bash ./terraform/terraform-test/deploy.sh
- name: Run dashboard checks
run: |
export DATABASE_NAME="cid_data_export"
# Get the temp directory from deploy script
if [ -f "./terraform/terraform-test/.temp_dir" ]; then
TEMP_DIR=$(cat "./terraform/terraform-test/.temp_dir")
echo "Using temp directory: $TEMP_DIR"
bash ./terraform/terraform-test/check_dashboards.sh "$TEMP_DIR"
else
echo "Error: No temp directory reference found from deploy script"
exit 1
fi
cleanup:
needs: test-deployment
if: always()
runs-on: ubuntu-latest
env:
DATABASE_NAME: cid_data_export
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
- name: Get CID versions
id: versions
run: |
# Extract CID CFN version from local cid-cfn.yml file (line 3)
CFN_VERSION=$(sed -n '3p' ./cfn-templates/cid-cfn.yml | grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' | sed 's/v//' || echo "1.0.0")
echo "cid_cfn_version=$CFN_VERSION" >> $GITHUB_OUTPUT
echo "Using local CID CFN version: $CFN_VERSION"
# Get latest data export version from external S3 public URL
EXPORT_VERSION=$(curl -s https://raw.githubusercontent.com/aws-solutions-library-samples/cloud-intelligence-dashboards-data-collection/main/data-exports/deploy/data-exports-aggregation.yaml | grep Description | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' | head -1 || echo "0.5.0")
echo "data_export_version=$EXPORT_VERSION" >> $GITHUB_OUTPUT
echo "Using latest data export version: $EXPORT_VERSION"
- name: Create terraform.tfvars file
run: |
cat > ./terraform/cicd-deployment/terraform.tfvars << EOF
global_values = {
destination_account_id = "${{ secrets.AWS_ACCOUNT_ID }}"
source_account_ids = "${{ secrets.AWS_ACCOUNT_ID }}"
aws_region = "${{ secrets.AWS_REGION_TF }}"
quicksight_user = "${{ secrets.QUICKSIGHT_USER }}"
cid_cfn_version = "${{ steps.versions.outputs.cid_cfn_version }}"
data_export_version = "${{ steps.versions.outputs.data_export_version }}"
environment = "dev"
}
EOF
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE }}
aws-region: ${{ secrets.AWS_REGION_TF }}
role-duration-seconds: 3600
role-skip-session-tagging: true
- name: Initialize Terraform
working-directory: ./terraform/cicd-deployment
run: |
cat > backend.tf << EOF
terraform {
backend "s3" {
bucket = "${{ secrets.BACKEND_S3_BUCKET }}"
key = "terraform/cid-test/terraform.tfstate"
region = "${{ secrets.AWS_REGION }}"
encrypt = true
}
}
EOF
cat > providers.tf << EOF
provider "aws" {
alias = "management"
region = "${{ secrets.AWS_REGION_TF }}"
}
provider "aws" {
alias = "datacollection"
region = "${{ secrets.AWS_REGION_TF }}"
}
EOF
terraform init
- name: Run cleanup script
run: |
export RESOURCE_PREFIX="cid-tf"
export BACKEND_TYPE="s3"
export S3_BUCKET="${{ secrets.BACKEND_S3_BUCKET }}"
export S3_KEY="terraform/cid-test/terraform.tfstate"
export S3_REGION="${{ secrets.AWS_REGION_TF }}"
export BACKEND_REGION="${{ secrets.AWS_REGION }}"
bash ./terraform/terraform-test/cleanup.sh