diff --git a/go.mod b/go.mod index 8d8493e0..860cae8c 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/stretchr/testify v1.9.0 github.com/yannh/kubeconform v0.6.7 go.uber.org/mock v0.4.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f golang.org/x/mod v0.20.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -142,6 +141,7 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect golang.org/x/crypto v0.28.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.19.0 // indirect golang.org/x/sync v0.8.0 // indirect diff --git a/go.sum b/go.sum index 2c32cd87..dd0aab19 100644 --- a/go.sum +++ b/go.sum @@ -507,8 +507,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -544,8 +542,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= diff --git a/pkg/providers/azure.go b/pkg/providers/azure.go index dfc2a8e4..b1be5e93 100644 --- a/pkg/providers/azure.go +++ b/pkg/providers/azure.go @@ -60,7 +60,7 @@ func InitiateAzureOIDCFlow(ctx context.Context, sc *SetUpCmd, s spinner.Spinner) return err } - if err := sc.assignSpRole(ctx); err != nil { + if err := sc.assignSpRoles(ctx); err != nil { return err } @@ -164,9 +164,21 @@ func (sc *SetUpCmd) CreateServicePrincipal() error { return nil } -func (sc *SetUpCmd) assignSpRole(ctx context.Context) error { - log.Debug("Assigning contributor role to service principal...") +func (sc *SetUpCmd) assignSpRoles(ctx context.Context) error { + var spRoles = []string{ + "b24988ac-6180-42a0-ab88-20f7382dd24c", // Contributor role ID + "5af6afb3-c06c-4fa4-8848-71a8aee05683", // Azure Kubernetes Fleet Manager RBAC Writer role ID + } + for _, role := range spRoles { + if err := sc.assignRole(ctx, role); err != nil { + return err + } + } + log.Debug("Roles assigned successfully!") + return nil +} +func (sc *SetUpCmd) assignRole(ctx context.Context, roleId string) error { roleAssignClient, err := createRoleAssignmentClient(sc.SubscriptionID) if err != nil { return fmt.Errorf("creating role assignment client: %w", err) @@ -174,7 +186,6 @@ func (sc *SetUpCmd) assignSpRole(ctx context.Context) error { scope := fmt.Sprintf("/subscriptions/%s/resourceGroups/%s", sc.SubscriptionID, sc.ResourceGroupName) objectID := sc.spObjectId - roleId := "b24988ac-6180-42a0-ab88-20f7382dd24c" // Contributor role ID raUid := uuid.New().String() fullAssignmentId := fmt.Sprintf("/%s/providers/Microsoft.Authorization/roleAssignments/%s", scope, raUid) @@ -194,7 +205,6 @@ func (sc *SetUpCmd) assignSpRole(ctx context.Context) error { return fmt.Errorf("creating role assignment: %w", err) } - log.Debug("Role assigned successfully!") return nil } diff --git a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml index 7e425e79..f1e05734 100644 --- a/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml +++ b/template/workflows/manifests/.github/workflows/azure-kubernetes-service.yml @@ -19,13 +19,13 @@ # - ACR_RESOURCE_GROUP (resource group of your ACR) # - AZURE_CONTAINER_REGISTRY (name of your container registry / ACR) # - CLUSTER_RESOURCE_GROUP (where your cluster is deployed) -# - CLUSTER_NAME (name of your AKS cluster) # - CONTAINER_NAME (name of the container image you would like to push up to your ACR) # - DEPLOYMENT_MANIFEST_PATH (path to the manifest yaml for your deployment) # - DOCKER_FILE (path to your Dockerfile) # - BUILD_CONTEXT_PATH (path to the context of your Dockerfile) # - NAMESPACE (namespace to deploy your application) -# +# - RESOURCE_TYPE (type of resource to deploy to, either 'fleet' or 'managed cluster') +# - RESOURCE_NAME (name of the resource to deploy to - fleet name or managed cluster name) # For more information on GitHub Actions for Azure, refer to https://github.com/Azure/Actions # For more samples to get started with GitHub Action workflows to deploy to Azure, refer to https://github.com/Azure/actions-workflow-samples # For more options with the actions used below please refer to https://github.com/Azure/login @@ -42,11 +42,13 @@ env: AZURE_CONTAINER_REGISTRY: {{ .Config.GetVariableValue "AZURECONTAINERREGISTRY" }} CONTAINER_NAME: {{ .Config.GetVariableValue "CONTAINERNAME" }} CLUSTER_RESOURCE_GROUP: {{ .Config.GetVariableValue "CLUSTERRESOURCEGROUP" }} - CLUSTER_NAME: {{ .Config.GetVariableValue "CLUSTERNAME" }} DEPLOYMENT_MANIFEST_PATH: {{ .Config.GetVariableValue "DEPLOYMENTMANIFESTPATH" }} DOCKER_FILE: {{ .Config.GetVariableValue "DOCKERFILE" }} BUILD_CONTEXT_PATH: {{ .Config.GetVariableValue "BUILDCONTEXTPATH" }} NAMESPACE: {{ .Config.GetVariableValue "NAMESPACE" }} + RESOURCE_TYPE: {{ .Config.GetVariableValue "RESOURCETYPE" }} + RESOURCE_NAME: {{ .Config.GetVariableValue "RESOURCENAME" }} + {{` jobs: buildImage: @@ -95,24 +97,33 @@ jobs: with: kubelogin-version: 'v0.0.25' + # gets credentials for a fleet + - name: Get fleet credentials + if: ${{ env.RESOURCE_TYPE == 'fleets' }} + run: | + az fleet get-credentials -g ${{ env.CLUSTER_RESOURCE_GROUP }} -n ${{ env.RESOURCE_NAME }} + # Retrieves your Azure Kubernetes Service cluster's kubeconfig file - name: Get K8s context + if: ${{ env.RESOURCE_TYPE != 'fleets' }} uses: azure/aks-set-context@v3 with: resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} - cluster-name: ${{ env.CLUSTER_NAME }} + cluster-name: ${{ env.RESOURCE_NAME }} admin: 'false' use-kubelogin: 'true' # Checks if the AKS cluster is private - name: Is private cluster + if: ${{ env.RESOURCE_TYPE != 'fleets' }} id: isPrivate run: | - result=$(az aks show --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.CLUSTER_NAME }} --query "apiServerAccessProfile.enablePrivateCluster") + result=$(az aks show --resource-group ${{ env.CLUSTER_RESOURCE_GROUP }} --name ${{ env.RESOURCE_NAME }} --query "apiServerAccessProfile.enablePrivateCluster") echo "PRIVATE_CLUSTER=$result" >> "$GITHUB_OUTPUT" # Deploys application based on given manifest file - name: Deploys application + if: ${{ env.RESOURCE_TYPE != 'fleets' }} uses: Azure/k8s-deploy@v4 with: action: deploy @@ -120,7 +131,14 @@ jobs: images: | ${{ env.AZURE_CONTAINER_REGISTRY }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.sha }} resource-group: ${{ env.CLUSTER_RESOURCE_GROUP }} - name: ${{ env.CLUSTER_NAME }} + name: ${{ env.RESOURCE_NAME }} private-cluster: ${{ steps.isPrivate.outputs.PRIVATE_CLUSTER == 'true' }} namespace: ${{ env.NAMESPACE }} + - name: Deploys fleet application + if: ${{ env.RESOURCE_TYPE == 'fleets' }} + run: | + kubectl config current-context + for manifest in $(echo "${{ env.DEPLOYMENT_MANIFEST_PATH }}" | tr '\n' ' '); do + /usr/bin/kubectl apply --validate=false --request-timeout=60s -f ./$manifest --namespace ${{ env.NAMESPACE }} + done `}} \ No newline at end of file