Skip to content

feat: add pipeline for EKS #67

feat: add pipeline for EKS

feat: add pipeline for EKS #67

name: release-pullrequest-EKS
on:
pull_request:
branches:
- main
jobs:
install-EKS:
runs-on: ubuntu-latest
strategy:
matrix:
k8s_version: [ "1.32", "1.31" ]
steps:
- name: Extract and Store Trimmed Repository Name
run: |
REPO_CHART_NAME="${{ github.repository }}"
REPO_APP_NAME=$(echo "$REPO_CHART_NAME" | sed 's/-chart$//') # Remove "-chart" suffix if present
# Check if the trimmed repo exists
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/$REPO_APP_NAME")
if [[ "$HTTP_STATUS" -eq 200 ]]; then
echo "Using trimmed repository name: $REPO_APP_NAME"
echo "REPO_APP_NAME=$REPO_APP_NAME" >> $GITHUB_ENV
else
echo "Trimmed repository not found. Falling back to original repository name."
echo "REPO_APP_NAME=$REPO_CHART_NAME" >> $GITHUB_ENV
fi
- name: Use the Stored Variable
run: |
echo "Trimmed Repository Name: ${{ env.REPO_APP_NAME }}"
- name: Authenticate with GitHub App
id: authenticate
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
- name: Extract latest App Version
uses: tdemin/find-latest-tag@v1
id: app_version
with:
repo: https://${{ steps.authenticate.outputs.token }}@github.com/${{ env.REPO_APP_NAME }}.git
- name: Extract latest Chart Version
uses: tdemin/find-latest-tag@v1
id: chart_version
with:
repo: https://${{ steps.authenticate.outputs.token }}@github.com/${{ github.repository }}.git
- name: Checkout
uses: actions/checkout@v3
- name: Print latest Chart Version
run: |
echo APP_VERSION:${{steps.app_version.outputs.tag}}
echo CHART_VERSION:${{steps.chart_version.outputs.tag}}
- name: Replace Chart Version in Chart.yaml
run: sed -i 's/CHART_VERSION/${{ steps.chart_version.outputs.tag }}/g' ./chart/Chart.yaml
- name: Replace App Version in Chart.yaml
run: sed -i 's/APP_VERSION/${{ steps.app_version.outputs.tag }}/g' ./chart/Chart.yaml
# Prepare a sanitized version string (replace '.' with '-') and store it in K8S_VERSION_NODOT
- name: Prepare version variable
run: echo "K8S_VERSION_NODOT=$(echo '${{ matrix.k8s_version }}' | tr '.' '-')" >> $GITHUB_ENV
- name: Set up Helm
uses: azure/[email protected]
- name: Helm lint
run: helm lint ./chart
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1
- name: Install AWS Signing Helper
run: |
curl -Lo aws_signing_helper https://rolesanywhere.amazonaws.com/releases/1.4.0/X86_64/Linux/aws_signing_helper
chmod +x aws_signing_helper
- name: Write Certificate from Secrets
run: |
echo "${{ secrets.AWS_CERTIFICATE }}" | base64 --decode > certificato.txt
chmod 600 certificato.txt
- name: Write Private Key from Secrets
run: |
echo "${{ secrets.AWS_PRIVATE_KEY }}" | base64 --decode > chiave_privata_decifrata.key
chmod 600 chiave_privata_decifrata.key
- name: Get AWS Credentials via IAM Roles Anywhere
run: |
echo "Retrieving AWS credentials..."
CREDS=$(./aws_signing_helper credential-process \
--certificate ./certificato.txt \
--private-key ./chiave_privata_decifrata.key \
--trust-anchor-arn arn:aws:rolesanywhere:eu-central-1:654654440307:trust-anchor/5f810e29-6061-46d6-a1ff-d36a5ac5c8cc \
--profile-arn arn:aws:rolesanywhere:eu-central-1:654654440307:profile/32097de8-0ad3-41f6-8da9-c99fa1c82bf5 \
--role-arn arn:aws:iam::654654440307:role/github-action-admin \
--session-duration 14400)
ACCESS_KEY=$(echo $CREDS | jq -r '.AccessKeyId')
SECRET_KEY=$(echo $CREDS | jq -r '.SecretAccessKey')
SESSION_TOKEN=$(echo $CREDS | jq -r '.SessionToken')
EXPIRATION=$(echo $CREDS | jq -r '.Expiration')
cat > ./credentials <<EOF
[dev]
aws_access_key_id = $ACCESS_KEY
aws_secret_access_key = $SECRET_KEY
aws_session_token = $SESSION_TOKEN
EOF
echo "AWS credentials retrieved. Session expires at: $EXPIRATION"
- name: Create AWS Credentials Secret in Kubernetes
run: |
kubectl create ns ack-system
kubectl create secret generic aws-creds \
--from-file=credentials-file=./credentials \
--namespace=ack-system \
--type=Opaque
- name: Clean Up Sensitive Files
run: rm -f certificato.txt chiave_privata_decifrata.key ./credentials
- name: Install ACK EC2 Controller on Kind using Helm
run: |
helm install --create-namespace -n ack-system ack-ec2-controller \
oci://public.ecr.aws/aws-controllers-k8s/ec2-chart --version=1.3.7 --set=aws.region=eu-central-1 --wait --set=aws.credentials.secretName=aws-creds --set=aws.credentials.secretKey=credentials-file --set=aws.credentials.profile=dev
- name: Annotate ACK EC2 Controller serviceaccount
run: kubectl annotate serviceaccount -n ack-system ack-ec2-controller eks.amazonaws.com/role-arn=arn:aws:iam::539247454863:role/github-action
- name: Check ACK EC2 Controller serviceaccount
run: kubectl describe serviceaccount -n ack-system ack-ec2-controller
- name: Restart ACK EC2 Controller
run: kubectl rollout restart deployment -n ack-system ack-ec2-controller-ec2-chart
- name: Wait for ACK EC2 Controller Deployment to be Ready
run: kubectl rollout status deployment -n ack-system ack-ec2-controller-ec2-chart --timeout=300s
- name: Install ACK EKS Controller on Kind using Helm
run: |
helm install --create-namespace -n ack-system ack-eks-controller \
oci://public.ecr.aws/aws-controllers-k8s/eks-chart --version=1.6.3 --set=aws.region=eu-central-1 --wait --set=aws.credentials.secretName=aws-creds --set=aws.credentials.secretKey=credentials-file --set=aws.credentials.profile=dev
- name: Annotate ACK EKS Controller serviceaccount
run: kubectl annotate serviceaccount -n ack-system ack-eks-controller eks.amazonaws.com/role-arn=arn:aws:iam::539247454863:role/github-action
- name: Check ACK EKS Controller serviceaccount
run: kubectl describe serviceaccount -n ack-system ack-eks-controller
- name: Restart ACK EKS Controller
run: kubectl rollout restart deployment -n ack-system ack-eks-controller-eks-chart
- name: Wait for ACK EKS Controller Deployment to be Ready
run: kubectl rollout status deployment -n ack-system ack-eks-controller-eks-chart --timeout=300s
- name: Deploy VPC CR via EC2 Controller
run: |
echo "Deploying VPC resource with Kubernetes version ${{ matrix.k8s_version }}..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPC
metadata:
name: cluster-$K8S_VERSION_NODOT
spec:
cidrBlocks:
- 10.0.0.0/16
enableDNSSupport: true
enableDNSHostnames: true
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT
- key: kubernetes.io/cluster/cluster-$K8S_VERSION_NODOT
value: shared
EOF
- name: Wait for VPC Provisioning
run: |
echo "Waiting for VPC resource to become ACK.ResourceSynced..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s vpc/cluster-$K8S_VERSION_NODOT
- name: Check VPC status
if: always()
run: |
kubectl get vpc/cluster-$K8S_VERSION_NODOT -o yaml
- name: Deploy Subnet-1 CR via EC2 Controller
run: |
echo "Deploying Subnet-1 resource with Kubernetes version ${{ matrix.k8s_version }}..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: Subnet
metadata:
name: cluster-$K8S_VERSION_NODOT-1
spec:
cidrBlock: 10.0.1.0/24
availabilityZone: eu-central-1a
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-1
- key: kubernetes.io/cluster/cluster-$K8S_VERSION_NODOT
value: shared
EOF
- name: Wait for Subnet-1 Provisioning
run: |
echo "Waiting for Subnet-1 resource to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s subnet/cluster-$K8S_VERSION_NODOT-1
- name: Check Subnet-1 status
if: always()
run: |
kubectl get subnet/cluster-$K8S_VERSION_NODOT-1 -o yaml
- name: Deploy Subnet-2 CR via EC2 Controller
run: |
echo "Deploying Subnet-2 resource with Kubernetes version ${{ matrix.k8s_version }}..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: Subnet
metadata:
name: cluster-$K8S_VERSION_NODOT-2
spec:
cidrBlock: 10.0.2.0/24
availabilityZone: eu-central-1b
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-2
- key: kubernetes.io/cluster/cluster-$K8S_VERSION_NODOT
value: shared
EOF
- name: Wait for Subnet-2 Provisioning
run: |
echo "Waiting for Subnet-2 resource to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s subnet/cluster-$K8S_VERSION_NODOT-2
- name: Check Subnet-2 status
if: always()
run: |
kubectl get subnet/cluster-$K8S_VERSION_NODOT-2 -o yaml
- name: Create Security Group for VPC Endpoints
run: |
echo "Creating Security Group for VPC Endpoints..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: SecurityGroup
metadata:
name: cluster-$K8S_VERSION_NODOT-vpce-sg
spec:
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
description: Security group for VPC Endpoints
name: cluster-$K8S_VERSION_NODOT-vpce-sg
ingressRules:
- ipProtocol: tcp
fromPort: 443
toPort: 443
ipRanges:
- cidrIP: 10.0.0.0/16
description: Allow HTTPS from VPC CIDR
egressRules:
- ipProtocol: "-1"
fromPort: -1
toPort: -1
ipRanges:
- cidrIP: 0.0.0.0/0
description: Allow all outbound traffic
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-vpce-sg
EOF
- name: Wait for Security Group Provisioning
run: |
echo "Waiting forSecurity Group resource to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s securitygroup/cluster-$K8S_VERSION_NODOT-vpce-sg
- name: Check Security Group status
if: always()
run: |
kubectl get securitygroup/cluster-$K8S_VERSION_NODOT-vpce-sg -o yaml
- name: Deploy VPC Endpoint for EC2
run: |
echo "Deploying VPC Endpoint for EC2..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPCEndpoint
metadata:
name: cluster-$K8S_VERSION_NODOT-ec2-endpoint
spec:
serviceName: com.amazonaws.eu-central-1.ec2
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
securityGroupRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-vpce-sg
vpcEndpointType: Interface
privateDNSEnabled: true
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "*",
"Resource": "*"
}
]
}
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-ec2-endpoint
EOF
- name: Deploy VPC Endpoint for ECR API
run: |
echo "Deploying VPC Endpoint for ECR API..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPCEndpoint
metadata:
name: cluster-$K8S_VERSION_NODOT-ecr-api-endpoint
spec:
serviceName: com.amazonaws.eu-central-1.ecr.api
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
securityGroupRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-vpce-sg
vpcEndpointType: Interface
privateDNSEnabled: true
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "*",
"Resource": "*"
}
]
}
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-ecr-api-endpoint
EOF
- name: Deploy VPC Endpoint for ECR Docker
run: |
echo "Deploying VPC Endpoint for ECR Docker..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPCEndpoint
metadata:
name: cluster-$K8S_VERSION_NODOT-ecr-dkr-endpoint
spec:
serviceName: com.amazonaws.eu-central-1.ecr.dkr
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
securityGroupRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-vpce-sg
vpcEndpointType: Interface
privateDNSEnabled: true
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "*",
"Resource": "*"
}
]
}
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-ecr-dkr-endpoint
EOF
- name: Deploy VPC Endpoint for STS
run: |
echo "Deploying VPC Endpoint for STS..."
cat <<EOF | kubectl apply -f -
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: VPCEndpoint
metadata:
name: cluster-$K8S_VERSION_NODOT-sts-endpoint
spec:
serviceName: com.amazonaws.eu-central-1.sts
vpcRef:
from:
name: cluster-$K8S_VERSION_NODOT
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
securityGroupRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-vpce-sg
vpcEndpointType: Interface
privateDNSEnabled: true
policyDocument: |
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "*",
"Resource": "*"
}
]
}
tags:
- key: Name
value: cluster-$K8S_VERSION_NODOT-sts-endpoint
EOF
# Add a wait step for VPC Endpoints
- name: Wait for VPC Endpoints Provisioning
run: |
echo "Waiting for VPC Endpoints to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s vpcendpoint/cluster-$K8S_VERSION_NODOT-ec2-endpoint
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s vpcendpoint/cluster-$K8S_VERSION_NODOT-ecr-api-endpoint
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s vpcendpoint/cluster-$K8S_VERSION_NODOT-ecr-dkr-endpoint
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s vpcendpoint/cluster-$K8S_VERSION_NODOT-sts-endpoint
- name: Deploy Cluster CR via EKS Controller
run: |
echo "Deploying Cluster resource with Kubernetes version ${{ matrix.k8s_version }}..."
cat <<EOF | kubectl apply -f -
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Cluster
metadata:
name: cluster-$K8S_VERSION_NODOT
spec:
name: cluster-$K8S_VERSION_NODOT
roleARN: arn:aws:iam::654654440307:role/EKSClusterRole
version: "${{ matrix.k8s_version }}"
resourcesVPCConfig:
endpointPrivateAccess: false
endpointPublicAccess: true
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
EOF
- name: Wait for Cluster Provisioning
run: |
echo "Waiting for Cluster resource to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=600s cluster/cluster-$K8S_VERSION_NODOT
- name: Check Cluster status
if: always()
run: |
kubectl get cluster/cluster-$K8S_VERSION_NODOT -o yaml
- name: Deploy Nodegroup CR via EKS Controller
run: |
echo "Deploying Nodegroup resource with Kubernetes version ${{ matrix.k8s_version }}..."
cat <<EOF | kubectl apply -f -
apiVersion: eks.services.k8s.aws/v1alpha1
kind: Nodegroup
metadata:
name: cluster-$K8S_VERSION_NODOT
spec:
name: cluster-$K8S_VERSION_NODOT
clusterRef:
from:
name: cluster-$K8S_VERSION_NODOT
nodeRole: arn:aws:iam::654654440307:role/eks-node-role
subnetRefs:
- from:
name: cluster-$K8S_VERSION_NODOT-1
- from:
name: cluster-$K8S_VERSION_NODOT-2
instanceTypes:
- t3.medium
diskSize: 50
scalingConfig:
minSize: 2
maxSize: 5
desiredSize: 3
EOF
- name: Wait for Nodegroup Provisioning
run: |
echo "Waiting for Cluster resource to become Ready..."
kubectl wait --for=condition=ACK.ResourceSynced --timeout=1800s nodegroup/cluster-$K8S_VERSION_NODOT
- name: Check Nodegroup status
if: always()
run: |
kubectl get nodegroup/cluster-$K8S_VERSION_NODOT -o yaml
- name: Get events
if: always()
run: kubectl get events -A --sort-by='.lastTimestamp'
- name: Get deployments
if: always()
run: kubectl get deployments -n ack-system
- name: Get pods
if: always()
run: kubectl get pods -n ack-system
- name: Get logs of ACK EC2 Controller pod
if: always()
run: |
POD_NAME=$(kubectl get pods -n ack-system -l app.kubernetes.io/instance=ack-ec2-controller -o jsonpath="{.items[0].metadata.name}")
if [[ -n "$POD_NAME" ]]; then
kubectl logs -n ack-system "$POD_NAME"
else
echo "No pod found with label app.kubernetes.io/instance=ack-ec2-controller"
fi
- name: Get logs of ACK ECK Controller pod
if: always()
run: |
POD_NAME=$(kubectl get pods -n ack-system -l app.kubernetes.io/instance=ack-eks-controller -o jsonpath="{.items[0].metadata.name}")
if [[ -n "$POD_NAME" ]]; then
kubectl logs -n ack-system "$POD_NAME"
else
echo "No pod found with label app.kubernetes.io/instance=ack-eks-controller"
fi