@@ -75,14 +75,102 @@ tasks:
7575 post-install :
7676 desc : Workshop post-install steps (IDC/Keycloak federation for ArgoCD SSO)
7777 cmds :
78- - task : idc:configure
78+ - task : idc:setup
79+ - task : idc:configure-keycloak
7980
8081 # ============================================================
8182 # IDC / KEYCLOAK FEDERATION
8283 # Configures IAM Identity Center with Keycloak as external IdP
8384 # ============================================================
8485
85- idc:configure :
86+
87+ idc:setup :
88+ desc : Create IDC groups if they don't exist (idempotent)
89+ vars :
90+ STORE_ID :
91+ sh : |
92+ ID=$(yq '.identityCenter.identityStoreId // ""' {{.CONFIG_FILE}})
93+ if [ -z "$ID" ]; then
94+ aws sso-admin list-instances --region {{.IDC_REGION}} --query 'Instances[0].IdentityStoreId' --output text 2>/dev/null || echo ""
95+ else
96+ echo "$ID"
97+ fi
98+ ADMIN_GROUP :
99+ sh : |
100+ EXISTING=$(yq '.identityCenter.adminGroupId // ""' {{.CONFIG_FILE}})
101+ if [ -n "$EXISTING" ]; then echo "$EXISTING"; exit 0; fi
102+ STORE_ID=$(yq '.identityCenter.identityStoreId // ""' {{.CONFIG_FILE}})
103+ [ -z "$STORE_ID" ] && STORE_ID=$(aws sso-admin list-instances --region {{.IDC_REGION}} --query 'Instances[0].IdentityStoreId' --output text 2>/dev/null)
104+ aws identitystore list-groups --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} --filters '[{"AttributePath":"DisplayName","AttributeValue":"admin"}]' --query 'Groups[0].GroupId' --output text 2>/dev/null | grep -v None || echo ""
105+ cmds :
106+ - |
107+ STORE_ID="{{.STORE_ID}}"
108+ if [ -z "$STORE_ID" ]; then
109+ echo "ERROR: No IDC Identity Store found. Set identityCenter.identityStoreId in config.local.yaml"
110+ exit 1
111+ fi
112+ printf '{{.C_STEP}}▸ IDC Identity Store: %s{{.C_RESET}}\n' "$STORE_ID"
113+ # BYO IdC: if adminGroupId AND adminUserId are pre-populated in config,
114+ # skip group/user/membership creation entirely (useful when IdC lives in
115+ # a different AWS account and the bootstrap role lacks identitystore:Create* perms).
116+ BYO_GROUP=$(yq '.identityCenter.adminGroupId // ""' {{.CONFIG_FILE}})
117+ BYO_USER=$(yq '.identityCenter.adminUserId // ""' {{.CONFIG_FILE}})
118+ if [ -n "$BYO_GROUP" ] && [ -n "$BYO_USER" ]; then
119+ printf '{{.C_INFO}} BYO IdC detected (adminGroupId + adminUserId set) — skipping group/user/membership creation{{.C_RESET}}\n'
120+ printf '{{.C_OK}}✓ IDC admin group: %s{{.C_RESET}}\n' "$BYO_GROUP"
121+ printf '{{.C_OK}}✓ IDC admin user: %s{{.C_RESET}}\n' "$BYO_USER"
122+ yq -i ".identityCenter.identityStoreId = \"$STORE_ID\"" {{.CONFIG_FILE}}
123+ exit 0
124+ fi
125+ # Create groups idempotently
126+ for GROUP_NAME in admin editor viewer; do
127+ EXISTING=$(aws identitystore list-groups --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
128+ --filters "[{\"AttributePath\":\"DisplayName\",\"AttributeValue\":\"$GROUP_NAME\"}]" \
129+ --query 'Groups[0].GroupId' --output text 2>/dev/null | grep -v None || echo "")
130+ if [ -n "$EXISTING" ]; then
131+ printf '{{.C_INFO}} Group "%s" exists: %s{{.C_RESET}}\n' "$GROUP_NAME" "$EXISTING"
132+ else
133+ NEW_ID=$(aws identitystore create-group --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
134+ --display-name "$GROUP_NAME" --description "Platform group for EKS ArgoCD Capability" \
135+ --query 'GroupId' --output text)
136+ printf '{{.C_OK}} Created group "%s": %s{{.C_RESET}}\n' "$GROUP_NAME" "$NEW_ID"
137+ fi
138+ done
139+ # Output admin group ID (prefer config value, fallback to lookup)
140+ ADMIN_ID=$(yq '.identityCenter.adminGroupId // ""' {{.CONFIG_FILE}})
141+ if [ -z "$ADMIN_ID" ]; then
142+ ADMIN_ID=$(aws identitystore list-groups --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
143+ --filters '[{"AttributePath":"DisplayName","AttributeValue":"admin"}]' \
144+ --query 'Groups[0].GroupId' --output text)
145+ fi
146+ printf '{{.C_OK}}✓ IDC admin group: %s{{.C_RESET}}\n' "$ADMIN_ID"
147+ # Create admin user if not exists
148+ ADMIN_USER=$(aws identitystore list-users --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
149+ --filters '[{"AttributePath":"UserName","AttributeValue":"eks-argocd-admin-user"}]' \
150+ --query 'Users[0].UserId' --output text 2>/dev/null | grep -v None || echo "")
151+ if [ -z "$ADMIN_USER" ]; then
152+ ADMIN_USER=$(aws identitystore create-user --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
153+ --user-name "eks-argocd-admin-user" --display-name "EKS ArgoCD Admin" \
154+ --name '{"GivenName":"EKS Admin","FamilyName":"User"}' \
155+ --emails '[{"Value":"eks-argocd-admin@example.com","Primary":true}]' \
156+ --query 'UserId' --output text)
157+ printf '{{.C_OK}} Created admin user: %s{{.C_RESET}}\n' "$ADMIN_USER"
158+ else
159+ printf '{{.C_INFO}} Admin user exists: %s{{.C_RESET}}\n' "$ADMIN_USER"
160+ fi
161+ # Add user to admin group if not already member
162+ IS_MEMBER=$(aws identitystore is-member-in-groups --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
163+ --member-id '{"UserId":"'"$ADMIN_USER"'"}' --group-ids "$ADMIN_ID" \
164+ --query 'Results[0].MembershipExists' --output text 2>/dev/null || echo "false")
165+ if [ "$IS_MEMBER" != "True" ]; then
166+ aws identitystore create-group-membership --identity-store-id "$STORE_ID" --region {{.IDC_REGION}} \
167+ --group-id "$ADMIN_ID" --member-id '{"UserId":"'"$ADMIN_USER"'"}' >/dev/null 2>&1 || true
168+ printf '{{.C_OK}} Added user to admin group{{.C_RESET}}\n'
169+ fi
170+ # Update config.local.yaml with discovered values
171+ yq -i ".identityCenter.adminGroupId = \"$ADMIN_ID\"" {{.CONFIG_FILE}}
172+ yq -i ".identityCenter.identityStoreId = \"$STORE_ID\"" {{.CONFIG_FILE}}
173+ idc:configure-keycloak :
86174 desc : Configure IDC with Keycloak as external IdP and sync users via SCIM
87175 status :
88176 - |
0 commit comments