Files
Project_Velocity/infrastructure/aws/setup_s3_media_bucket.sh
Sayan Datta 6c93e31741
All checks were successful
Production Readiness / backend-contracts (pull_request) Successful in 3m19s
Production Readiness / webos-typecheck (pull_request) Successful in 2m38s
Production Readiness / ipad-parse (pull_request) Successful in 1m44s
feat: Ipad app production readiness, Colony orchestration, Social posting
2026-05-03 18:28:04 +05:30

199 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
if ! command -v aws >/dev/null 2>&1; then
echo "aws CLI is required. Install AWS CLI v2 and authenticate before running." >&2
exit 1
fi
AWS_REGION="${AWS_REGION:-ap-south-1}"
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID:-$(aws sts get-caller-identity --query Account --output text)}"
BUCKET_NAME="${VELOCITY_MEDIA_BUCKET:-velocity-media-${AWS_ACCOUNT_ID}-${AWS_REGION}}"
IAM_USER_NAME="${VELOCITY_MEDIA_IAM_USER:-velocity-media-app}"
IAM_POLICY_NAME="${VELOCITY_MEDIA_IAM_POLICY_NAME:-VelocityMediaBucketReadWriteObjects}"
CORS_ORIGIN="${VELOCITY_MEDIA_CORS_ORIGIN:-https://velocity.desineuron.in}"
TMP_DIR="$(mktemp -d)"
cleanup() {
rm -rf "${TMP_DIR}"
}
trap cleanup EXIT
bucket_exists() {
aws s3api head-bucket --bucket "${BUCKET_NAME}" >/dev/null 2>&1
}
create_bucket() {
if bucket_exists; then
echo "S3 bucket already exists: ${BUCKET_NAME}"
return
fi
echo "Creating private S3 bucket: ${BUCKET_NAME} (${AWS_REGION})"
if [[ "${AWS_REGION}" == "us-east-1" ]]; then
aws s3api create-bucket --bucket "${BUCKET_NAME}" --region "${AWS_REGION}" >/dev/null
else
aws s3api create-bucket \
--bucket "${BUCKET_NAME}" \
--region "${AWS_REGION}" \
--create-bucket-configuration "LocationConstraint=${AWS_REGION}" >/dev/null
fi
aws s3api wait bucket-exists --bucket "${BUCKET_NAME}"
}
secure_bucket() {
echo "Applying private bucket controls"
aws s3api put-public-access-block \
--bucket "${BUCKET_NAME}" \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
aws s3api put-bucket-ownership-controls \
--bucket "${BUCKET_NAME}" \
--ownership-controls '{
"Rules": [
{
"ObjectOwnership": "BucketOwnerEnforced"
}
]
}'
aws s3api put-bucket-encryption \
--bucket "${BUCKET_NAME}" \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
},
"BucketKeyEnabled": true
}
]
}'
aws s3api put-bucket-versioning \
--bucket "${BUCKET_NAME}" \
--versioning-configuration Status=Enabled
}
apply_cors() {
local cors_file="${TMP_DIR}/cors.json"
cat >"${cors_file}" <<JSON
{
"CORSRules": [
{
"AllowedOrigins": ["${CORS_ORIGIN}"],
"AllowedMethods": ["GET", "PUT", "HEAD"],
"AllowedHeaders": ["Authorization", "Content-Type", "Content-MD5", "x-amz-*"],
"ExposeHeaders": ["ETag", "x-amz-request-id", "x-amz-version-id"],
"MaxAgeSeconds": 3000
}
]
}
JSON
echo "Applying CORS policy for ${CORS_ORIGIN}"
aws s3api put-bucket-cors \
--bucket "${BUCKET_NAME}" \
--cors-configuration "file://${cors_file}"
}
apply_https_only_bucket_policy() {
local bucket_policy_file="${TMP_DIR}/bucket-policy.json"
cat >"${bucket_policy_file}" <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyInsecureTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::${BUCKET_NAME}",
"arn:aws:s3:::${BUCKET_NAME}/*"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
JSON
echo "Applying HTTPS-only bucket policy"
aws s3api put-bucket-policy \
--bucket "${BUCKET_NAME}" \
--policy "file://${bucket_policy_file}"
}
ensure_iam_user() {
if aws iam get-user --user-name "${IAM_USER_NAME}" >/dev/null 2>&1; then
echo "IAM user already exists: ${IAM_USER_NAME}"
return
fi
echo "Creating IAM user: ${IAM_USER_NAME}"
aws iam create-user \
--user-name "${IAM_USER_NAME}" \
--tags Key=Project,Value=Velocity Key=Purpose,Value=MediaStorage >/dev/null
}
attach_restricted_policy() {
local policy_file="${TMP_DIR}/iam-policy.json"
cat >"${policy_file}" <<JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VelocityMediaObjectReadWriteOnly",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::${BUCKET_NAME}/*"
}
]
}
JSON
echo "Attaching restricted inline IAM policy: ${IAM_POLICY_NAME}"
aws iam put-user-policy \
--user-name "${IAM_USER_NAME}" \
--policy-name "${IAM_POLICY_NAME}" \
--policy-document "file://${policy_file}"
}
print_summary() {
cat <<SUMMARY
Project Velocity media bucket provisioning complete.
Bucket: ${BUCKET_NAME}
Region: ${AWS_REGION}
CORS origin: ${CORS_ORIGIN}
IAM user: ${IAM_USER_NAME}
Inline policy: ${IAM_POLICY_NAME}
Environment values for backend/.env.production:
AWS_REGION=${AWS_REGION}
AWS_S3_BUCKET=${BUCKET_NAME}
AWS_S3_MEDIA_PREFIX=velocity-production
This script does not print or create long-lived access keys. Use your preferred
AWS credential vending path for production secrets.
SUMMARY
}
create_bucket
secure_bucket
apply_cors
apply_https_only_bucket_policy
ensure_iam_user
attach_restricted_policy
print_summary