diff --git a/.github/workflows/deploy-az.yml b/.github/workflows/deploy-az.yml index fbfff18..146a975 100644 --- a/.github/workflows/deploy-az.yml +++ b/.github/workflows/deploy-az.yml @@ -12,7 +12,7 @@ env: REGISTRY: ghcr.io NAMESPACE: austriandatalab SUB_NAMESPACE: indiegamestream - LABEL: sha-f641ffb9ebff0a3f8c8f9b968bfd50f83a316370 + LABEL: sha-350add069a4899d95e950578b37b43e2fd092fd2 jobs: deploy: runs-on: ubuntu-latest @@ -59,8 +59,7 @@ jobs: - name: Apply tailscale operator working-directory: ./iac run: | - az aks command invoke -n ${{ secrets.AZURERM_AKS_CLUSTER_NAME }} -g rg-service-not2day --command "helm uninstall tailscale-operator --namespace=tailscale || true" - az aks command invoke -n ${{ secrets.AZURERM_AKS_CLUSTER_NAME }} -g rg-service-not2day --command "helm repo add tailscale https://pkgs.tailscale.com/helmcharts && helm repo update && helm upgrade --install tailscale-operator tailscale/tailscale-operator --namespace=tailscale --create-namespace --set-string oauth.clientId=${{secrets.TAILSCALE_CLIENT_ID}} --set-string oauth.clientSecret=${{secrets.TAILSCALE_CLIENT_SECRET}} --set-string apiServerProxyConfig.mode=true --wait" + az aks command invoke -n ${{ secrets.AZURERM_AKS_CLUSTER_NAME }} -g rg-service-not2day --command "helm repo add tailscale https://pkgs.tailscale.com/helmcharts && helm repo update && helm upgrade --install tailscale-operator tailscale/tailscale-operator --set-string oauth.clientId=${{secrets.TAILSCALE_CLIENT_ID}} --set-string oauth.clientSecret=${{secrets.TAILSCALE_CLIENT_SECRET}} --set-string apiServerProxyConfig.mode=true --wait || true" - name: Connect to tailscale uses: tailscale/github-action@v2 with: @@ -79,14 +78,22 @@ jobs: helm repo add mysql-operator https://mysql.github.io/mysql-operator/ helm repo update helm install mysql-operator mysql-operator/mysql-operator --version "2.1.3" --wait \ - --create-namespace --namespace=mysql-operator + --create-namespace --namespace=mysql-operator || true helm install mysql mysql-operator/mysql-innodbcluster --version "2.1.3" --wait \ --create-namespace --namespace=mysql -f values.yaml \ - --set-string credentials.root.password=${{ secrets.MYSQL_ROOT_PASSWORD }} + --set-string credentials.root.password=${{ secrets.MYSQL_ROOT_PASSWORD }} || true + + - name: Install Open Policy Gatekeeper + working-directory: ./scripts/opa + run: | + helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts + helm repo update + helm install gatekeeper gatekeeper/gatekeeper --namespace gatekeeper-system --create-namespace --wait || true + kubectl apply -f loadbalancerclass_mutator.yaml - name: Install stunner working-directory: ./scripts/localenv - run: make install_stunner + run: make install_stunner || true - name: Install game operator manifests working-directory: ./operator @@ -185,9 +192,9 @@ jobs: export TF_CLI_ARGS_init=" -backend-config=\"resource_group_name=${{ secrets.AZURERM_RESOURCE_GROUP_NAME }}\" -backend-config=\"key=${{ secrets.KEY }}.tfstate\" -backend-config=\"storage_account_name=${{ secrets.AZURERM_STORAGE_ACCOUNT_NAME }}\" -backend-config=\"container_name=tfbootstrapadmin\" -backend-config=\"subscription_id=${{ secrets.AZURERM_SUBSCRIPTION_ID }}\" -backend-config=\"tenant_id=${{ secrets.AZURERM_TENANT_ID }}\" " terraform init terraform plan -out=tfplan.bin -input=false - terraform destroy -auto-approve - terraform destroy -auto-approve - terraform destroy -auto-approve + terraform destroy -auto-approve || true + terraform destroy -auto-approve || true + terraform destroy -auto-approve || true - name: Logout of Azure run: az logout \ No newline at end of file diff --git a/iac/.gitignore b/iac/.gitignore new file mode 100644 index 0000000..66df410 --- /dev/null +++ b/iac/.gitignore @@ -0,0 +1 @@ +.terraform* \ No newline at end of file diff --git a/iac/kubernetes.tf b/iac/kubernetes.tf index 8cdb75b..2e2dc41 100644 --- a/iac/kubernetes.tf +++ b/iac/kubernetes.tf @@ -6,13 +6,15 @@ resource "azurerm_kubernetes_cluster" "testCluster" { default_node_pool { name = "default" - node_count = 1 + node_count = 2 vm_size = "Standard_B2ms" upgrade_settings { - drain_timeout_in_minutes = 0 - max_surge = "10%" + drain_timeout_in_minutes = 5 + max_surge = "50%" node_soak_duration_in_minutes = 0 } + max_pods = 110 + temporary_name_for_rotation = "upgrade" } network_profile { @@ -21,6 +23,10 @@ resource "azurerm_kubernetes_cluster" "testCluster" { outbound_type = "loadBalancer" } + storage_profile { + blob_driver_enabled = true + } + identity { type = "SystemAssigned" } diff --git a/iac/nsg.tf b/iac/nsg.tf deleted file mode 100644 index 41de0e6..0000000 --- a/iac/nsg.tf +++ /dev/null @@ -1,23 +0,0 @@ - -resource azurerm_network_security_group "student" { - name = "student-network-security-group" - location = var.globals.location - resource_group_name = data.azurerm_resource_group.rgruntime.name - - #tags = local.common_tags -} - -resource "azurerm_network_security_rule" "lab_nsg" { - name = "Tailscale" - description = "Tailscale UDP port for direct connections. Reduces latency." - priority = 1010 - direction = "Inbound" - access = "Allow" - protocol = "Udp" - source_port_range = "*" - destination_port_range = 41641 - source_address_prefix = "*" - destination_address_prefix = "*" - resource_group_name = data.azurerm_resource_group.rgruntime.name - network_security_group_name = azurerm_network_security_group.student.name -} \ No newline at end of file diff --git a/operator/internal/controller/stream/game_controller.go b/operator/internal/controller/stream/game_controller.go index ffa97d5..316177b 100644 --- a/operator/internal/controller/stream/game_controller.go +++ b/operator/internal/controller/stream/game_controller.go @@ -502,7 +502,7 @@ func (r *GameReconciler) constructWorkerDeploymentForGame(game *streamv1.Game, r func (r *GameReconciler) constructLoadBalancer(game *streamv1.Game, name string, selector string, port int32) (*corev1.Service, error) { - //className := "tailscale" + className := "tailscale" svc := &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ @@ -510,8 +510,8 @@ func (r *GameReconciler) constructLoadBalancer(game *streamv1.Game, name string, Namespace: game.Namespace, }, Spec: corev1.ServiceSpec{ - Selector: map[string]string{"app": selector}, - // LoadBalancerClass: &className, + Selector: map[string]string{"app": selector}, + LoadBalancerClass: &className, Ports: []corev1.ServicePort{ { Port: port, @@ -567,6 +567,12 @@ func waitForLoadBalancerIP(ctx context.Context, k8sClient client.Client, namespa if ip != "" { return true, nil } + if len(svc.Status.LoadBalancer.Ingress) > 1 { + ip = svc.Status.LoadBalancer.Ingress[1].IP + if ip != "" { + return true, nil + } + } } return false, nil }) diff --git a/scripts/opa/loadbalancerclass_mutator.yaml b/scripts/opa/loadbalancerclass_mutator.yaml new file mode 100644 index 0000000..04e5ec0 --- /dev/null +++ b/scripts/opa/loadbalancerclass_mutator.yaml @@ -0,0 +1,21 @@ +apiVersion: mutations.gatekeeper.sh/v1 +kind: Assign +metadata: + name: demo-dns-policy +spec: + applyTo: + - groups: [""] + kinds: ["Service"] + versions: ["v1"] + match: + scope: Namespaced | Cluster + kinds: + - apiGroups: ["*"] + kinds: ["Service"] + labelSelector: + matchExpressions: + - {key: "stunner.l7mp.io/owned-by", operator: "In", values: ["stunner"]} + location: "spec.loadBalancerClass" + parameters: + assign: + value: "tailscale" \ No newline at end of file