Skip to content

Commit 3ed9acd

Browse files
🔧 Update required script to deploy to private eks clusters
1 parent c350152 commit 3ed9acd

3 files changed

Lines changed: 232 additions & 14 deletions

File tree

Dockerfile

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,17 @@ ENV KUBECONFIG="/opt/kubernetes/config"
88
# ca-certificates: For validating SSL/TLS connections
99
# bash: Shell environment
1010
# git: For cloning Git repositories, potentially private Helm charts
11-
# gnupg: For verifying signed Helm charts or other secured assets (already present, ensuring it's there)
11+
# gnupg: For verifying signed Helm charts or other secured assets
1212
# jq: A lightweight and flexible command-line JSON processor
1313
# py-pip: Python package installer, used for awscli
14-
# curl: Tool for transferring data with URL syntax (already present, ensuring it's there)
15-
# gettext: GNU gettext for internationalization (already present)
14+
# curl: Tool for transferring data with URL syntax
15+
# gettext: GNU gettext for internationalization
16+
# openssh-client: SSH client for bastion host connectivity
17+
# bind-tools: DNS utilities (nslookup, dig)
18+
# netcat-openbsd: Network testing utilities
19+
# timeout: Command timeout utility
1620
RUN apk add --no-cache ca-certificates bash git gnupg jq py-pip \
21+
openssh-client bind-tools netcat-openbsd coreutils \
1722
&& apk add --update -t deps curl gettext \
1823
&& pip install awscli
1924

@@ -42,9 +47,11 @@ RUN curl -o aws-iam-authenticator https://github.com/kubernetes-sigs/aws-iam-aut
4247
# Clean up APK cache to reduce image size
4348
RUN rm -rf /var/cache/apk/*
4449

45-
# Create directories for Kubernetes config and Helm, and set appropriate permissions
46-
# These directories are used for storing configurations and cache
47-
RUN mkdir -p /opt/kubernetes && chmod a+rwx /opt/kubernetes && mkdir -p /opt/helm && chmod a+rwx /opt/helm
50+
# Create directories for Kubernetes config, Helm, and SSH
51+
# Set appropriate permissions for multi-user scenarios
52+
RUN mkdir -p /opt/kubernetes && chmod a+rwx /opt/kubernetes && \
53+
mkdir -p /opt/helm && chmod a+rwx /opt/helm && \
54+
mkdir -p /root/.ssh && chmod 700 /root/.ssh
4855

4956
# Set Helm environment variables for cache and config home
5057
ENV HELM_HOME="/opt/helm"
@@ -61,4 +68,4 @@ ADD . .
6168
RUN chmod +x entrypoint.sh
6269

6370
# Set the entrypoint for the Docker container
64-
ENTRYPOINT [ "/entrypoint.sh" ]
71+
ENTRYPOINT [ "/entrypoint.sh" ]

action.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# action.yml
22
name: 'EKS Helm Client'
3-
description: 'Helm client to install and upgrade Helm chart on EKS cluster with comprehensive error handling'
3+
description: 'Helm client to install and upgrade Helm chart on EKS cluster with support for private clusters'
44
branding:
55
icon: 'upload-cloud'
66
color: 'blue'
@@ -11,6 +11,7 @@ inputs:
1111
args:
1212
description: 'Commands to execute'
1313
required: true
14+
# AWS Configuration
1415
aws-access-key-id:
1516
description: 'AWS Access Key ID'
1617
required: false
@@ -30,4 +31,23 @@ inputs:
3031
required: false
3132
helm-registry-password:
3233
description: 'Password for Helm registry authentication'
34+
required: false
35+
# Private Cluster Support
36+
bastion-host:
37+
description: 'Bastion host IP/hostname for private cluster access'
38+
required: false
39+
bastion-user:
40+
description: 'SSH username for bastion host'
41+
required: false
42+
ssh-private-key:
43+
description: 'SSH private key for bastion host access'
44+
required: false
45+
http-proxy:
46+
description: 'HTTP proxy URL for private cluster access'
47+
required: false
48+
https-proxy:
49+
description: 'HTTPS proxy URL for private cluster access'
50+
required: false
51+
no-proxy:
52+
description: 'Comma-separated list of hosts to bypass proxy'
3353
required: false

entrypoint.sh

Lines changed: 197 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,123 @@ log_success() {
2121

2222
echo "--- Pre-flight Checks ---"
2323

24+
# Function to check if cluster is private
25+
check_cluster_privacy() {
26+
local endpoint_config
27+
endpoint_config=$(aws eks describe-cluster --region "$REGION_CODE" --name "$CLUSTER_NAME" --query "cluster.resourcesVpcConfig.endpointConfig" --output json 2>/dev/null)
28+
29+
if [ $? -ne 0 ]; then
30+
return 1
31+
fi
32+
33+
local public_access=$(echo "$endpoint_config" | jq -r '.publicAccess // true')
34+
local private_access=$(echo "$endpoint_config" | jq -r '.privateAccess // false')
35+
36+
log_info "Cluster endpoint configuration:"
37+
log_info " - Public access: $public_access"
38+
log_info " - Private access: $private_access"
39+
40+
if [ "$public_access" = "false" ] && [ "$private_access" = "true" ]; then
41+
log_info "Detected fully private EKS cluster"
42+
return 0
43+
elif [ "$public_access" = "true" ] && [ "$private_access" = "true" ]; then
44+
log_info "Detected EKS cluster with both public and private access"
45+
return 1
46+
else
47+
log_info "Detected public EKS cluster"
48+
return 1
49+
fi
50+
}
51+
52+
# Check if we're running in a private network context
53+
check_private_network_setup() {
54+
log_info "Checking private network setup..."
55+
56+
# Check if we're running on a self-hosted runner (common for private clusters)
57+
if [ -n "$RUNNER_NAME" ] && [ "$RUNNER_NAME" != "GitHub Actions" ]; then
58+
log_info "Running on self-hosted runner: $RUNNER_NAME"
59+
return 0
60+
fi
61+
62+
# Check if VPN environment variables are set
63+
if [ -n "$VPN_CONFIG" ] || [ -n "$BASTION_HOST" ]; then
64+
log_info "VPN or bastion configuration detected"
65+
return 0
66+
fi
67+
68+
# Check for AWS VPC environment (like running in EC2)
69+
if curl -s --max-time 5 http://169.254.169.254/latest/meta-data/instance-id > /dev/null 2>&1; then
70+
log_info "Running in AWS environment (likely EC2 instance)"
71+
return 0
72+
fi
73+
74+
return 1
75+
}
76+
77+
# Function to test network connectivity to EKS endpoint
78+
test_eks_connectivity() {
79+
local endpoint_url="$1"
80+
local host=$(echo "$endpoint_url" | sed 's|https://||' | sed 's|/.*||')
81+
82+
log_info "Testing network connectivity to EKS endpoint: $host"
83+
84+
# Test DNS resolution
85+
if ! nslookup "$host" > /dev/null 2>&1; then
86+
log_error "DNS resolution failed for $host"
87+
return 1
88+
fi
89+
90+
# Test TCP connectivity
91+
if ! timeout 10 bash -c "</dev/tcp/$host/443" 2>/dev/null; then
92+
log_error "TCP connection failed to $host:443"
93+
return 1
94+
fi
95+
96+
log_success "Network connectivity to EKS endpoint verified"
97+
return 0
98+
}
99+
100+
# Function to setup bastion/proxy if configured
101+
setup_network_proxy() {
102+
if [ -n "$BASTION_HOST" ] && [ -n "$BASTION_USER" ]; then
103+
log_info "Setting up SSH tunnel through bastion host..."
104+
105+
# Check if SSH key is provided
106+
if [ -n "$SSH_PRIVATE_KEY" ]; then
107+
echo "$SSH_PRIVATE_KEY" > /tmp/ssh_key
108+
chmod 600 /tmp/ssh_key
109+
SSH_KEY_PARAM="-i /tmp/ssh_key"
110+
else
111+
SSH_KEY_PARAM=""
112+
fi
113+
114+
# Start SSH tunnel in background
115+
ssh -f -N -L 8443:$CLUSTER_ENDPOINT_HOST:443 \
116+
$SSH_KEY_PARAM \
117+
-o StrictHostKeyChecking=no \
118+
-o UserKnownHostsFile=/dev/null \
119+
$BASTION_USER@$BASTION_HOST
120+
121+
if [ $? -eq 0 ]; then
122+
log_success "SSH tunnel established through bastion"
123+
export PROXY_ENDPOINT="https://localhost:8443"
124+
else
125+
log_error "Failed to establish SSH tunnel through bastion"
126+
return 1
127+
fi
128+
fi
129+
130+
# Setup HTTP proxy if configured
131+
if [ -n "$HTTP_PROXY" ] || [ -n "$HTTPS_PROXY" ]; then
132+
log_info "HTTP proxy configuration detected"
133+
export http_proxy="$HTTP_PROXY"
134+
export https_proxy="$HTTPS_PROXY"
135+
export no_proxy="$NO_PROXY"
136+
fi
137+
138+
return 0
139+
}
140+
24141
# Check if required environment variables are set
25142
log_info "Checking required environment variables..."
26143

@@ -68,7 +185,34 @@ if ! aws eks describe-cluster --region "$REGION_CODE" --name "$CLUSTER_NAME" > /
68185
exit 1
69186
fi
70187

71-
log_success "EKS cluster is accessible"
188+
log_success "EKS cluster is accessible via AWS API"
189+
190+
# Check if cluster is private and handle accordingly
191+
if check_cluster_privacy; then
192+
log_info "Private EKS cluster detected - checking network setup..."
193+
194+
if ! check_private_network_setup; then
195+
log_error "Private EKS cluster requires special network setup!"
196+
log_error "For private EKS clusters, you need one of the following:"
197+
log_error " 1. Self-hosted GitHub Actions runner in the same VPC"
198+
log_error " 2. VPN connection to the cluster's VPC"
199+
log_error " 3. Bastion host configuration"
200+
log_error " 4. GitHub Actions runner in EC2 with proper networking"
201+
log_error ""
202+
log_error "Environment variables for private cluster access:"
203+
log_error " - BASTION_HOST: SSH bastion host IP/hostname"
204+
log_error " - BASTION_USER: SSH username for bastion"
205+
log_error " - SSH_PRIVATE_KEY: SSH private key for bastion access"
206+
log_error " - HTTP_PROXY/HTTPS_PROXY: HTTP proxy settings"
207+
exit 1
208+
fi
209+
210+
# Setup network proxy/tunnel if configured
211+
if ! setup_network_proxy; then
212+
log_error "Failed to setup network connectivity for private cluster"
213+
exit 1
214+
fi
215+
fi
72216

73217
echo "--- Configuring AWS EKS Kubeconfig ---"
74218

@@ -90,9 +234,27 @@ if [ -z "$ENDPOINT_URL" ] || [ "$ENDPOINT_URL" = "None" ]; then
90234
exit 1
91235
fi
92236

237+
# Use proxy endpoint if configured
238+
if [ -n "$PROXY_ENDPOINT" ]; then
239+
log_info "Using proxy endpoint for private cluster access"
240+
export ENDPOINT_URL="$PROXY_ENDPOINT"
241+
fi
242+
93243
log_success "Retrieved EKS cluster configuration"
94244
log_info "EKS Cluster Endpoint: $ENDPOINT_URL"
95245

246+
# Test network connectivity to the endpoint
247+
export CLUSTER_ENDPOINT_HOST=$(echo "$ENDPOINT_URL" | sed 's|https://||' | sed 's|/.*||')
248+
if ! test_eks_connectivity "$ENDPOINT_URL"; then
249+
log_error "Cannot establish network connectivity to EKS cluster endpoint"
250+
log_error "This is common with private EKS clusters. Please ensure:"
251+
log_error " - You're running from within the cluster's VPC"
252+
log_error " - VPN connection is established"
253+
log_error " - Bastion host/proxy is properly configured"
254+
log_error " - Security groups allow access on port 443"
255+
exit 1
256+
fi
257+
96258
# Generate Kubernetes configuration file (/opt/kubernetes/config)
97259
log_info "Generating Kubernetes configuration file..."
98260
if ! cat /config.template | envsubst > /opt/kubernetes/config; then
@@ -111,19 +273,48 @@ log_success "Kubernetes configuration file generated successfully"
111273
# Ensure KUBECONFIG environment variable is correctly set for subsequent commands
112274
export KUBECONFIG=/opt/kubernetes/config
113275

114-
# Test kubectl connectivity
276+
# Test kubectl connectivity with longer timeout for private clusters
115277
log_info "Testing kubectl connectivity to EKS cluster..."
116-
if ! kubectl cluster-info --request-timeout=10s > /dev/null 2>&1; then
278+
kubectl_timeout=30
279+
if [ -n "$PROXY_ENDPOINT" ] || check_cluster_privacy; then
280+
kubectl_timeout=60
281+
log_info "Using extended timeout for private cluster connectivity test"
282+
fi
283+
284+
if ! timeout $kubectl_timeout kubectl cluster-info --request-timeout=30s > /dev/null 2>&1; then
117285
log_error "Cannot connect to Kubernetes cluster"
118286
log_error "Please check:"
119-
log_error " - EKS cluster is running"
120-
log_error " - AWS credentials have kubernetes access permissions"
121-
log_error " - Network connectivity to the cluster"
287+
log_error " - EKS cluster is running and healthy"
288+
log_error " - AWS credentials have kubernetes access permissions (eks:DescribeCluster)"
289+
log_error " - Network connectivity to the cluster endpoint"
290+
log_error " - Security groups allow inbound traffic on port 443"
291+
log_error " - RBAC permissions for the AWS user/role"
292+
293+
# Additional troubleshooting for private clusters
294+
if check_cluster_privacy 2>/dev/null; then
295+
log_error ""
296+
log_error "Private cluster specific checks:"
297+
log_error " - Runner is in the same VPC as the EKS cluster"
298+
log_error " - VPC has proper DNS resolution enabled"
299+
log_error " - Route tables allow access to the cluster subnets"
300+
log_error " - NAT Gateway/Instance for internet access (if needed)"
301+
fi
302+
122303
exit 1
123304
fi
124305

125306
log_success "Successfully connected to Kubernetes cluster"
126307

308+
# Test basic kubectl permissions
309+
log_info "Testing basic kubectl permissions..."
310+
if kubectl auth can-i get pods --all-namespaces > /dev/null 2>&1; then
311+
log_success "Basic kubectl permissions verified"
312+
else
313+
log_error "Limited kubectl permissions detected"
314+
log_error "Some operations may fail due to RBAC restrictions"
315+
log_error "Ensure your AWS user/role has proper Kubernetes RBAC bindings"
316+
fi
317+
127318
# Check for Helm registry credentials if any helm registry login commands are present
128319
log_info "Checking for Helm registry credentials..."
129320
helm_login_required=false

0 commit comments

Comments
 (0)