forked from sagnik/Project_Velocity
#38 Ipad app production readiness, Colony orchestration, Social posting Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local> Reviewed-on: sagnik/Project_Velocity#44
199 lines
5.0 KiB
Bash
Executable File
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
|