From ff68ad07f142e938948bc43f078ddf4e6cd543ac Mon Sep 17 00:00:00 2001 From: amber <> Date: Mon, 16 Sep 2024 21:32:18 +0800 Subject: [PATCH] [feat] Add YAML files for infrastructure setup --- .github/workflows/build.yaml | 61 +++++++++++++++++ .github/workflows/deploy.yaml | 64 +++++++++++++++++- .github/workflows/eks-deploy.yaml | 95 +++++++++++++++++++++++++++ .github/workflows/eksctl-cluster.yaml | 54 +++++++++++++++ README.md | 14 ++++ 5 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build.yaml create mode 100644 .github/workflows/eks-deploy.yaml create mode 100644 .github/workflows/eksctl-cluster.yaml create mode 100644 README.md diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..06c66bd0 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,61 @@ +name: Build + +on: + push: + branches: + - main + paths: + - 'frontend/**' + - 'backend/**' + +jobs: + build-frontend: + if: contains(github.event.head_commit.message, 'frontend') || github.event.head_commit.added | contains('frontend') || github.event.head_commit.modified | contains('frontend') + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to Amazon ECR + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build and push frontend image + env: + AWS_REGION: ${{ secrets.AWS_REGION }} + ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }} + NODE_ENV: ${{ secrets.NODE_ENV }} + run: | + docker build --cache-from $ECR_REGISTRY/frontend:$GITHUB_REF_NAME \ + -t $ECR_REGISTRY/frontend:$GITHUB_REF_NAME \ + --build-arg NODE_ENV=$NODE_ENV \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + -f frontend/Dockerfile . + docker push $ECR_REGISTRY/frontend:$GITHUB_REF_NAME + + build-backend: + if: contains(github.event.head_commit.message, 'backend') || github.event.head_commit.added | contains('backend') || github.event.head_commit.modified | contains('backend') + runs-on: ubuntu-latest + needs: build-frontend + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to Amazon ECR + uses: aws-actions/amazon-ecr-login@v1 + + - name: Build and push backend image + env: + AWS_REGION: ${{ secrets.AWS_REGION }} + ECR_REGISTRY: ${{ secrets.ECR_REGISTRY }} + run: | + docker build --cache-from $ECR_REGISTRY/backend:$GITHUB_REF_NAME \ + -t $ECR_REGISTRY/backend:$GITHUB_REF_NAME \ + --build-arg BUILDKIT_INLINE_CACHE=1 \ + -f backend/Dockerfile . + docker push $ECR_REGISTRY/backend:$GITHUB_REF_NAME diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 9daeafb9..0f40beef 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -1 +1,63 @@ -test +name: Deploy + +on: + workflow_dispatch: + inputs: + deploy-frontend: + description: 'Deploy frontend' + required: false + default: 'false' + type: boolean + deploy-backend: + description: 'Deploy backend' + required: false + default: 'false' + type: boolean + +jobs: + deploy-frontend: + if: ${{ github.event.inputs.deploy-frontend == 'true' }} + runs-on: ubuntu-latest + container: + image: z1yoon/k8s-base:v0.0.1 + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Update kubeconfig + run: aws eks --region ${{ secrets.AWS_REGION }} update-kubeconfig --name ${{ secrets.K8S_CLUSTER }} + + - name: Deploy frontend server + run: | + cd k8s/base + kustomize edit set image nuage/frontend=${{ secrets.ECR_REGISTRY }}/frontend:$(git rev-parse --short HEAD) + cd ../overlays/${{ secrets.K8S_OVERLAY }} + kustomize build . | kubectl apply -n ${{ secrets.K8S_NAMESPACE }} -f - + kubectl -n ${{ secrets.K8S_NAMESPACE }} rollout status deployment frontend-deployment --timeout=20m + + - name: Deploy frontend client assets to S3 + run: | + cd client + aws s3 cp --recursive . s3://$NUAGE_S3/frontend/$GITHUB_REF_NAME --exclude "*" --include "*.js" --content-type "application/javascript" --content-encoding "br" --cache-control "max-age=31536000" + # Additional aws s3 cp commands for other file types as in your original script + + deploy-backend: + if: ${{ github.event.inputs.deploy-backend == 'true' }} + runs-on: ubuntu-latest + container: + image: z1yoon/k8s-base:v0.0.1 + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Update kubeconfig + run: aws eks --region ${{ secrets.AWS_REGION }} update-kubeconfig --name ${{ secrets.K8S_CLUSTER }} + + - name: Deploy backend server + run: | + cd k8s/base + kustomize edit set image nuage/backend=${{ secrets.ECR_REGISTRY }}/backend:$(git rev-parse --short HEAD) + cd ../overlays/${{ secrets.K8S_OVERLAY }} + kustomize build . | kubectl apply -n ${{ secrets.K8S_NAMESPACE }} -f - + kubectl -n ${{ secrets.K8S_NAMESPACE }} rollout status deployment backend-deployment --timeout=20m + diff --git a/.github/workflows/eks-deploy.yaml b/.github/workflows/eks-deploy.yaml new file mode 100644 index 00000000..9a0d11d9 --- /dev/null +++ b/.github/workflows/eks-deploy.yaml @@ -0,0 +1,95 @@ +name: EKS Deployment + +on: + workflow_dispatch: + inputs: + deploy: + description: 'Trigger deployment' + required: true + default: 'false' + type: boolean + delete: + description: 'Trigger deletion of the cluster' + required: true + default: 'false' + type: boolean + +jobs: + create_cluster: + runs-on: ubuntu-latest + if: ${{ github.event.inputs.deploy == 'true' && github.event.inputs.delete == 'false' }} + container: + image: z1yoon/k8s-base:v0.0.1 + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Create EKS cluster + run: | + eksctl create cluster -f .github/workflows/eksctl-cluster.yaml + + - name: Create Node Group + run: | + eksctl create nodegroup -f .github/workflows/eksctl-cluster.yaml + + deploy_alb_controller: + runs-on: ubuntu-latest + needs: create_cluster + if: ${{ github.event.inputs.deploy == 'true' && github.event.inputs.delete == 'false' }} + container: + image: z1yoon/k8s-base:v0.0.1 + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Associate IAM OIDC provider + run: | + eksctl utils associate-iam-oidc-provider --region ${{ secrets.AWS_REGION }} --cluster ${{ secrets.EKS_CLUSTER_NAME }} --approve + + - name: Create IAM Policy for ALB Controller + run: | + curl -o alb-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.1/docs/install/iam_policy.json + aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://alb-policy.json + + - name: Create IAM Service Account for ALB Controller + run: | + eksctl create iamserviceaccount \ + --cluster ${{ secrets.EKS_CLUSTER_NAME }} \ + --namespace kube-system \ + --name aws-load-balancer-controller \ + --attach-policy-arn arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:policy/AWSLoadBalancerControllerIAMPolicy \ + --override-existing-serviceaccounts \ + --approve + + - name: Install AWS Load Balancer Controller + run: | + helm repo add eks https://aws.github.io/eks-charts + helm repo update + helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ + --set clusterName=${{ secrets.EKS_CLUSTER_NAME }} \ + --set serviceAccount.create=false \ + --set region=${{ secrets.AWS_REGION }} \ + --set vpcId=$(aws eks describe-cluster --name ${{ secrets.EKS_CLUSTER_NAME }} --region ${{ secrets.AWS_REGION }} --query "cluster.resourcesVpcConfig.vpcId" --output text) \ + --namespace kube-system \ + --set serviceAccount.name=aws-load-balancer-controller + + - name: Deploy Example Application with ALB Ingress + run: | + kubectl apply -f alb-ingress.yaml + + delete_cluster: + runs-on: ubuntu-latest + if: ${{ github.event.inputs.delete == 'true' }} + container: + image: z1yoon/k8s-base:v0.0.1 + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Delete Node Group + run: | + eksctl delete nodegroup -f .github/workflows/eksctl-cluster.yaml + + - name: Delete EKS cluster + run: | + eksctl delete cluster -f .github/workflows/eksctl-cluster.yaml diff --git a/.github/workflows/eksctl-cluster.yaml b/.github/workflows/eksctl-cluster.yaml new file mode 100644 index 00000000..9556cc60 --- /dev/null +++ b/.github/workflows/eksctl-cluster.yaml @@ -0,0 +1,54 @@ +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig +metadata: + version: "1.29" + name: nus-eks + region: ap-southeast-1 + tags: + Environment: production + Created: EKS +vpc: + clusterEndpoints: + publicAccess: false + privateAccess: true + subnets: + public: + ap-southeast-1a: { id: subnet-} + ap-southeast-1b: { id: subnet-} + private: + ap-southeast-1a: { id: subnet-} + ap-southeast-1b: { id: subnet-} + securityGroup: sg- +cloudWatch: + clusterLogging: + enableTypes: ["*"] +managedNodeGroups: + - name: nus-eks-workers-28 + minSize: 0 + maxSize: 2 + desiredCapacity: 2 + volumeSize: 20 + instanceTypes: + - t3a.small + - t3a.medium + - t3a.large + spot: true + privateNetworking: true + ssh: + allow: true + publicKeyName: nus + labels: {role: worker} + tags: + Environment: production + Created: EKS + iam: + attachPolicyARNs: [ + "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy", + "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", + "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", + ] + withAddonPolicies: + autoScaler: true + albIngress: true + cloudWatch: true + externalDNS: true diff --git a/README.md b/README.md new file mode 100644 index 00000000..b0f8d8b5 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +. +├── backend +│ └── Dockerfile +├── frontend +│ └── Dockerfile +└── k8s + └── base +└── .github + └── workflows + ├── build.yaml + ├── deploy.yaml + ├── eks-deploy.yaml + └── eksctl-cluster.yaml +