Skip to content

Commit 8d4eefc

Browse files
committed
update: installer
1 parent 0b00ce7 commit 8d4eefc

2 files changed

Lines changed: 298 additions & 15 deletions

File tree

docs/public/install.sh

Lines changed: 250 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ SKIP_NAMESPACES="kube-system,aiostack-test,myaiostack,aiostack,monitoring,gke-mc
5252
COMMANDER_URL="hq.aurva.ai:443"
5353
INSECURE_SKIP_VERIFY="true"
5454
OBSERVER_VERSION="latest"
55-
OUTPOST_VERSION="trueID-alpha"
55+
OUTPOST_VERSION="latest"
5656
CREATE_NAMESPACE="true"
5757
HELM_REPO_NAME="aiostack"
5858
HELM_REPO_URL="https://charts.aurva.ai/"
@@ -61,10 +61,12 @@ DEPLOYMENT_TYPE="kubernetes"
6161
CLOUD_PROVIDER="aws"
6262
REGION="unknown"
6363
CLUSTER_ID=""
64+
IAM_ROLE_ARN=""
65+
GCP_SERVICE_ACCOUNT=""
6466

6567
# State tracking
6668
CURRENT_STEP=0
67-
TOTAL_STEPS=7
69+
TOTAL_STEPS=8
6870
HELM_REPO_ADDED=false
6971
NAMESPACE_CREATED=false
7072
INSTALLATION_STARTED=false
@@ -420,8 +422,7 @@ collect_credentials() {
420422
print_color "$BOLD$BRIGHT_GREEN" "Before proceeding, you need credentials from Aurva:"
421423
echo ""
422424
print_info "1. Sign up for a free account (takes 30 seconds)"
423-
print_info "2. Check your registered email for your credentials:"
424-
print_info " - Company ID"
425+
print_info "2. Check your registered email for your Company ID"
425426
echo ""
426427

427428
# Ask if they want to open the signup page
@@ -534,6 +535,229 @@ collect_env_config() {
534535
print_success "Configuration completed"
535536
}
536537

538+
# Collect IAM access configuration (AWS IRSA or GCP Workload Identity)
539+
collect_iam_config() {
540+
print_step "Configuring IAM Access"
541+
542+
echo ""
543+
print_info "The outpost needs cloud IAM access to enumerate roles in your account."
544+
echo ""
545+
546+
case "$CLOUD_PROVIDER" in
547+
aws) _collect_aws_iam_config ;;
548+
gcp) _collect_gcp_iam_config ;;
549+
*)
550+
print_warning "Cloud provider '${CLOUD_PROVIDER}' — IAM fetch not supported yet."
551+
print_info "Skipping IAM access configuration."
552+
;;
553+
esac
554+
}
555+
556+
_collect_aws_iam_config() {
557+
print_color "$BOLD" "AWS IAM Access via IRSA (IAM Roles for Service Accounts)"
558+
echo ""
559+
print_info "The outpost assumes an IAM role through IRSA to call read-only APIs."
560+
print_info "Required permissions on the role:"
561+
echo ""
562+
print_color "$WHITE" " IAM inventory:"
563+
print_color "$WHITE" " iam:ListRoles iam:GetRole"
564+
print_color "$WHITE" " iam:ListAttachedRolePolicies iam:GetPolicy iam:GetPolicyVersion"
565+
print_color "$WHITE" " iam:ListRolePolicies iam:GetRolePolicy"
566+
echo ""
567+
print_color "$WHITE" " RDS datasource inventory:"
568+
print_color "$WHITE" " rds:DescribeDBInstances rds:DescribeDBClusters"
569+
print_color "$WHITE" " rds:DescribeDBSubnetGroups rds:ListTagsForResource"
570+
echo ""
571+
print_color "$WHITE" " S3 datasource inventory:"
572+
print_color "$WHITE" " s3:ListAllMyBuckets s3:GetBucketLocation"
573+
print_color "$WHITE" " s3:GetBucketPublicAccessBlock s3:GetBucketTagging"
574+
print_color "$WHITE" " s3:GetBucketVersioning s3:GetBucketAcl"
575+
echo ""
576+
577+
# Attempt to derive account ID and OIDC issuer automatically
578+
local aws_account_id="" oidc_issuer="" cluster_name=""
579+
580+
if [[ "$CLUSTER_ID" =~ arn:aws:eks:[^:]+:([^:]+):cluster/(.+)$ ]]; then
581+
aws_account_id="${BASH_REMATCH[1]}"
582+
cluster_name="${BASH_REMATCH[2]}"
583+
fi
584+
585+
if command -v aws &> /dev/null; then
586+
print_info "AWS CLI detected — fetching account and OIDC details..."
587+
if [[ -z "$aws_account_id" ]]; then
588+
aws_account_id=$(aws sts get-caller-identity --query Account --output text 2>/dev/null || echo "")
589+
fi
590+
if [[ -n "$cluster_name" && -n "$REGION" && "$REGION" != "unknown" ]]; then
591+
oidc_issuer=$(aws eks describe-cluster \
592+
--name "$cluster_name" --region "$REGION" \
593+
--query "cluster.identity.oidc.issuer" \
594+
--output text 2>/dev/null | sed 's|https://||' || echo "")
595+
fi
596+
if [[ -n "$aws_account_id" ]]; then
597+
print_success "Account ID: ${aws_account_id}"
598+
fi
599+
if [[ -n "$oidc_issuer" ]]; then
600+
print_success "OIDC issuer: ${oidc_issuer}"
601+
fi
602+
echo ""
603+
fi
604+
605+
local acct="${aws_account_id:-YOUR_ACCOUNT_ID}"
606+
local oidc="${oidc_issuer:-oidc.eks.${REGION}.amazonaws.com/id/YOUR_OIDC_ID}"
607+
local role_name="aiostack-outpost-secure-readonly-role"
608+
local sa_name="aiostack-outpost-sa"
609+
local role_arn="arn:aws:iam::${acct}:role/${role_name}"
610+
611+
print_color "$BOLD$BRIGHT_GREEN" "Run these commands to create the role (copy-paste ready):"
612+
echo ""
613+
cat << AWSCMDS
614+
# 1. Create the IAM policy
615+
aws iam create-policy \\
616+
--policy-name AIOStackOutpostSecureReadOnlyPolicy \\
617+
--policy-document '{
618+
"Version": "2012-10-17",
619+
"Statement": [
620+
{
621+
"Sid": "IAMInventory",
622+
"Effect": "Allow",
623+
"Action": [
624+
"iam:ListRoles","iam:GetRole",
625+
"iam:ListAttachedRolePolicies","iam:GetPolicy","iam:GetPolicyVersion",
626+
"iam:ListRolePolicies","iam:GetRolePolicy"
627+
],
628+
"Resource": "*"
629+
},
630+
{
631+
"Sid": "RDSDatasourceInventory",
632+
"Effect": "Allow",
633+
"Action": [
634+
"rds:DescribeDBInstances",
635+
"rds:DescribeDBClusters",
636+
"rds:DescribeDBSubnetGroups",
637+
"rds:ListTagsForResource"
638+
],
639+
"Resource": "*"
640+
},
641+
{
642+
"Sid": "S3DatasourceInventory",
643+
"Effect": "Allow",
644+
"Action": [
645+
"s3:ListAllMyBuckets",
646+
"s3:GetBucketLocation",
647+
"s3:GetBucketPublicAccessBlock",
648+
"s3:GetBucketTagging",
649+
"s3:GetBucketVersioning",
650+
"s3:GetBucketAcl"
651+
],
652+
"Resource": "*"
653+
}
654+
]
655+
}'
656+
657+
# 2. Create the role with OIDC trust for this cluster's service account
658+
aws iam create-role \\
659+
--role-name ${role_name} \\
660+
--assume-role-policy-document '{
661+
"Version": "2012-10-17",
662+
"Statement": [{
663+
"Effect": "Allow",
664+
"Principal": {"Federated": "arn:aws:iam::${acct}:oidc-provider/${oidc}"},
665+
"Action": "sts:AssumeRoleWithWebIdentity",
666+
"Condition": {"StringEquals": {
667+
"${oidc}:sub": "system:serviceaccount:${NAMESPACE}:${sa_name}",
668+
"${oidc}:aud": "sts.amazonaws.com"
669+
}}
670+
}]
671+
}'
672+
673+
# 3. Attach the policy to the role
674+
aws iam attach-role-policy \\
675+
--role-name ${role_name} \\
676+
--policy-arn arn:aws:iam::${acct}:policy/AIOStackOutpostSecureReadOnlyPolicy
677+
AWSCMDS
678+
679+
echo ""
680+
print_info "Expected role ARN: ${role_arn}"
681+
echo ""
682+
683+
while true; do
684+
IAM_ROLE_ARN=$(prompt "Paste your IAM Role ARN (press Enter to skip)" "")
685+
IAM_ROLE_ARN=$(echo "$IAM_ROLE_ARN" | xargs)
686+
687+
if [[ -z "$IAM_ROLE_ARN" ]]; then
688+
print_warning "No IAM role provided — outpost will not be able to enumerate IAM roles, RDS instances, or S3 buckets."
689+
break
690+
elif [[ "$IAM_ROLE_ARN" =~ ^arn:aws:iam::[0-9]{12}:role/.+$ ]]; then
691+
print_success "IAM role ARN accepted."
692+
break
693+
else
694+
print_error "That doesn't look like a valid IAM role ARN."
695+
print_info "Expected format: arn:aws:iam::123456789012:role/role-name"
696+
fi
697+
done
698+
}
699+
700+
_collect_gcp_iam_config() {
701+
print_color "$BOLD" "GCP IAM Access via Workload Identity"
702+
echo ""
703+
print_info "The outpost impersonates a GCP Service Account to call IAM read APIs."
704+
print_info "The service account needs roles/iam.securityReviewer (or equivalent)."
705+
echo ""
706+
707+
local project_id=""
708+
if command -v gcloud &> /dev/null; then
709+
project_id=$(gcloud config get-value project 2>/dev/null || echo "")
710+
if [[ -n "$project_id" ]]; then
711+
print_success "GCP project: ${project_id}"
712+
echo ""
713+
fi
714+
fi
715+
716+
local proj="${project_id:-YOUR_PROJECT_ID}"
717+
local gsa_name="aiostack-outpost"
718+
local gsa_email="${gsa_name}@${proj}.iam.gserviceaccount.com"
719+
local ksa_name="aiostack-outpost-sa"
720+
721+
print_color "$BOLD$BRIGHT_GREEN" "Run these commands to set up Workload Identity (copy-paste ready):"
722+
echo ""
723+
cat << GCPCMDS
724+
# 1. Create the GCP Service Account
725+
gcloud iam service-accounts create ${gsa_name} \\
726+
--project=${proj} \\
727+
--display-name="AIOStack Outpost"
728+
729+
# 2. Grant IAM read permissions
730+
gcloud projects add-iam-policy-binding ${proj} \\
731+
--member="serviceAccount:${gsa_email}" \\
732+
--role="roles/iam.securityReviewer"
733+
734+
# 3. Allow the Kubernetes SA to impersonate the GCP SA
735+
gcloud iam service-accounts add-iam-policy-binding ${gsa_email} \\
736+
--role="roles/iam.workloadIdentityUser" \\
737+
--member="serviceAccount:${proj}.svc.id.goog[${NAMESPACE}/${ksa_name}]"
738+
GCPCMDS
739+
740+
echo ""
741+
print_info "Expected service account email: ${gsa_email}"
742+
echo ""
743+
744+
while true; do
745+
GCP_SERVICE_ACCOUNT=$(prompt "Paste your GCP Service Account email (press Enter to skip)" "")
746+
GCP_SERVICE_ACCOUNT=$(echo "$GCP_SERVICE_ACCOUNT" | xargs)
747+
748+
if [[ -z "$GCP_SERVICE_ACCOUNT" ]]; then
749+
print_warning "No GCP SA provided — outpost will not be able to enumerate IAM roles."
750+
break
751+
elif [[ "$GCP_SERVICE_ACCOUNT" =~ ^[^@]+@[^@]+\.iam\.gserviceaccount\.com$ ]]; then
752+
print_success "GCP service account accepted."
753+
break
754+
else
755+
print_error "That doesn't look like a valid GCP service account email."
756+
print_info "Expected format: name@project.iam.gserviceaccount.com"
757+
fi
758+
done
759+
}
760+
537761
# Review configuration
538762
review_config() {
539763
print_step "Reviewing Configuration"
@@ -568,6 +792,16 @@ review_config() {
568792
echo " Cluster ID: ${CLUSTER_ID}"
569793
echo ""
570794

795+
print_color "$BOLD" "IAM Access:"
796+
if [[ -n "$IAM_ROLE_ARN" ]]; then
797+
echo " AWS IAM Role ARN: ${IAM_ROLE_ARN}"
798+
elif [[ -n "$GCP_SERVICE_ACCOUNT" ]]; then
799+
echo " GCP Service Account: ${GCP_SERVICE_ACCOUNT}"
800+
else
801+
echo " IAM Access: not configured (IAM fetch disabled)"
802+
fi
803+
echo ""
804+
571805
# Show the helm command
572806
print_color "$BOLD$BRIGHT_GREEN" "Helm command that will be executed:"
573807
print_color "$GREEN" "helm install ${RELEASE_NAME} ${HELM_CHART} \\"
@@ -625,6 +859,8 @@ deploymentType: ${DEPLOYMENT_TYPE}
625859
cloudProvider: ${CLOUD_PROVIDER}
626860
region: ${REGION}
627861
clusterId: ${CLUSTER_ID}
862+
iamRoleArn: ${IAM_ROLE_ARN}
863+
gcpServiceAccount: ${GCP_SERVICE_ACCOUNT}
628864
EOF
629865

630866
chmod 600 "$config_file"
@@ -662,6 +898,8 @@ load_config() {
662898
cloudProvider) CLOUD_PROVIDER="$value" ;;
663899
region) REGION="$value" ;;
664900
clusterId) CLUSTER_ID="$value" ;;
901+
iamRoleArn) IAM_ROLE_ARN="$value" ;;
902+
gcpServiceAccount) GCP_SERVICE_ACCOUNT="$value" ;;
665903
esac
666904
done < "$config_file"
667905

@@ -742,6 +980,13 @@ install_aurva() {
742980
--set "outpost.version=${OUTPOST_VERSION}"
743981
)
744982

983+
if [[ -n "$IAM_ROLE_ARN" ]]; then
984+
helm_cmd+=(--set "outpost.serviceAccount.aws.iamRoleArn=${IAM_ROLE_ARN}")
985+
fi
986+
if [[ -n "$GCP_SERVICE_ACCOUNT" ]]; then
987+
helm_cmd+=(--set "outpost.serviceAccount.gcp.serviceAccount=${GCP_SERVICE_ACCOUNT}")
988+
fi
989+
745990
print_verbose "Running: ${helm_cmd[*]}"
746991

747992
# Execute helm install
@@ -966,6 +1211,7 @@ main() {
9661211

9671212
configure_namespace
9681213
collect_env_config
1214+
collect_iam_config
9691215
review_config
9701216
install_aurva
9711217
verify_deployment

0 commit comments

Comments
 (0)