paint-brush
Azure DevOps'ta Hakların, İzinlerin ve Erişim Düzeylerinin Otomasyonuile@socialdiscoverygroup
12,833 okumalar
12,833 okumalar

Azure DevOps'ta Hakların, İzinlerin ve Erişim Düzeylerinin Otomasyonu

ile Social Discovery Group6m2023/11/29
Read on Terminal Reader

Çok uzun; Okumak

İşletme hızla büyüdüğünde, bir DevOps mühendisi, manuel erişim yönetimi de dahil olmak üzere CI/CD için kullanılan tüm sistemlerdeki süreçleri otomatikleştirme zorluğuyla karşı karşıya kalır. Bu tür rutin görevler, müşteri isteklerinin çözümlenmesini önemli ölçüde yavaşlatır. Makalede Social Discovery Group ekibi, Azure DevOps'ta hakları, izinleri ve erişim düzeylerini otomatikleştirmek için özelleştirilmiş çözümler paylaşıyor.
featured image - Azure DevOps'ta Hakların, İzinlerin ve Erişim Düzeylerinin Otomasyonu
Social Discovery Group HackerNoon profile picture
0-item

İşletme hızla büyüdüğünde, bir DevOps mühendisi, manuel erişim yönetimi de dahil olmak üzere CI/CD için kullanılan tüm sistemlerdeki süreçleri otomatikleştirme zorluğuyla karşı karşıya kalır. Bu tür rutin görevler, küçük bir ekibiniz, her biri 3 aşamadan oluşan 10'a kadar sürüm ve 10 değişken grubunuz olduğunda kabul edilebilir.


Ancak ekibinizin, her biri 10 aşamadan oluşan 500'e kadar sürüm ve 200 değişken grupla manuel olarak çalışması gereken yüzlerce kişiye ulaştığını hayal edin. Bu durumda manuel erişim yönetimi, müşteri isteklerinin çözümlenmesini önemli ölçüde yavaşlatır.


Bu aşamada her işletme verimli bir otomasyona ihtiyaç duyar.


Social Discovery Group olarak birincil bulut teknolojisi olarak Azure DevOps'a güveniyoruz. Ancak şu anda hakları, izinleri ve erişim düzeylerini otomatikleştirme işlevinden yoksundur. Kullanıcı ihtiyaçlarını hızlı bir şekilde karşılamak için bazı özel çözümler bulmaya ve izin atamayı otomatikleştirmeye karar verdik.

Azure DevOps'ta Otomatikleştirme Nasıl Yapılır?

Bu makalede, aşağıdakilere odaklanarak Azure DevOps'ta belirli rutin görevlerin nasıl otomatikleştirileceğine dair bazı yararlı ipuçları paylaşacağız:


  • Azure Pipeline'ı kullanarak bir maskeye dayalı olarak değişken gruplar için bir gruba veya kullanıcıya izinler atama.


  • Azure Pipeline kullanılarak katalog gruplarına kategorize edilmiş tüm yayın grupları için belirli aşamalara grup veya kullanıcı izinleri atama.

Kullanılan Teknoloji Yığını: Azure Hizmetleri, Azure DevOps, Bash, Azure CLI

Şu anda Azure, izin atamak için 3 seçenek sunmaktadır: sitenin grafik arayüzünü kullanma, az DevOps CLI'yi kullanma ve API isteklerini kullanma. İlk seçenek en basit ve hızlı olanıdır; ancak şirket ölçeklendikçe ve CI/CD işlem hatları ile değişkenlerin sayısı arttıkça izinlerin manuel olarak atanması zaman alıcı hale gelir.


İzin vermenin ikinci seçeneğinin işlevselliği sınırlıdır; yani kullanıcı belirli bir takımın sunduklarının ötesine geçemez. REST API aracılığıyla üçüncü seçenek şu anda en çok yönlü olanıdır. Birden fazla aşamaya sahip çok sayıda sürüm hattımızın olduğu belirli bir örneği ele alalım:


Birden çok aşamalı işlem hatlarını serbest bırakın


Birden çok aşamalı işlem hatlarını serbest bırakın


Her dağıtım aşaması, belirli bir kullanıcı/gruptan izin gerektirir (dağıtım öncesi onay işlevi olarak adlandırılır). Belirli bir kullanıcının veya grubun belirli bir onaylayanlar listesine eklenmesi veya listeden çıkarılması gerektiğinde burada bir sorun ortaya çıkar.


Şirket büyüdükçe boru hattı ve aşama sayısı N kat arttığında rutin durum sorun haline gelir ve bu sorunun çözümü ancak API istekleri ile mümkün olur. Bizim tarafımızdan uygulamanın nasıl göründüğü:


 " pool: vmImage: ubuntu-latest parameters: - name: folder_names type: string default: '\' - name: stage_names type: string default: 'Dev' - name: group_names type: string default: 'Devops' variables: - name: organization value: ORGANIZATION - name: project value: PROJECT - name: pat Value: PAT steps: - bash: | export organization="$(organization)" export project="$(project)" export pat="$(pat)" export folder_names='${{ parameters.folder_names }}' export stage_names='${{ parameters.stage_names }}' export group_names='${{ parameters.group_names }}' export pipeline_name_array=() export stage_name_array=() export group_name_array=() IFS=',' read -ra folder_name_array <<< "$folder_names" IFS=',' read -ra stage_name_array <<< "$stage_names" IFS=',' read -ra group_name_array <<< "$group_names" # Make a GET request to retrieve the release pipelines within the specified project pipeline_url="https://vsrm.dev.azure.com/$organization/$project/_apis/release/definitions?api-version=7.0" pipeline_response=$(curl -s -u ":$pat" "$pipeline_url") # Check for errors in the response if [[ "$pipeline_response" == *"error"* ]]; then echo "Error fetching release pipeline data." exit 1 fi pipeline_names=($(echo "$pipeline_response" | jq -r '.value[].name')) pipeline_ids=($(echo "$pipeline_response" | jq -r '.value[].id')) for ((i=0; i<${#pipeline_names[@]}; i++)); do pipeline_name="${pipeline_names[i]}" pipeline_id="${pipeline_ids[i]}" # Make a GET request to retrieve the release pipeline details pipeline_detail_url="https://vsrm.dev.azure.com/$organization/$project/_apis/release/definitions/$pipeline_id?api-version=7.0" pipeline_detail_response=$(curl -s -u ":$pat" "$pipeline_detail_url") # Extract the releaseDefinition.path from the pipeline details pipeline_path=$(echo "$pipeline_detail_response" | jq -r '.path') # Check if the pipeline_path matches any of the specified folder_names for folder_name in "${folder_name_array[@]}"; do if [[ "$pipeline_path" == *"$folder_name"* ]]; then # Make a GET request to retrieve all releases for the specified pipeline releases_url="https://vsrm.dev.azure.com/$organization/$project/_apis/release/releases?api-version=7.0&definitionId=$pipeline_id" releases_response=$(curl -s -u ":$pat" "$releases_url") # Extract the release names release_names=$(echo "$releases_response" | jq -r '.value[].id') release_definition_url="https://vsrm.dev.azure.com/$organization/$project/_apis/release/definitions/$pipeline_id?api-version=7.0" release_definition_response=$(curl -s -u ":$pat" "$release_definition_url") # Iterate through each group name for group_name in "${group_name_array[@]}"; do # Make a GET request to retrieve the list of groups groups_response=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/graph/groups?api-version=7.1-preview.1") # Find the origin_id for the specified group name origin_id=$(echo "$groups_response" | jq -r ".value[] | select(.displayName == \"$group_name\") | .originId") if [ -z "$origin_id" ]; then echo "Group '$group_name' not found or origin_id not available for release '$release_name'." else # Iterate through each stage name for stage_name in "${stage_name_array[@]}"; do # Construct the JSON structure for the new approval new_approval='{ "rank": 1, "isAutomated": false, "isNotificationOn": false, "approver": { "id": "'"$origin_id"'" } }' # Use jq to update the JSON structure for the specified stage updated_definition=$(echo "$release_definition_response" | jq --argjson new_approval "$new_approval" '.environments |= map(if .name == "'"$stage_name"'" then .preDeployApprovals.approvals += [$new_approval] else . end)') # Make a PUT request to update the release definition for the specified stage put_response=$(curl -s -u ":$pat" -X PUT -H "Content-Type: application/json" -d "$updated_definition" "$release_definition_url") release_definition_response=$(curl -s -u ":$pat" "$release_definition_url") # Check if the update was successful if [[ "$put_response" == *"The resource could not be found."* ]]; then echo "Error updating release definition for stage '$stage_name' and group '$group_name'." else echo "Pre-deployment approval added successfully to stage '$stage_name' for group '$group_name' in '$pipeline_id'." fi done fi done fi done done displayName: 'PreDeployApprovals' "


Benzer bir sorun, belirli bir kelimenin bir şeye olan bağlılığı belirtmek için kullanıldığı çok sayıda değişken grup oluşturulduğunda Kütüphane bölümünde de ortaya çıkar. Hizmetle ilgili değişkenlerle ilişkilerini belirtmek için "HİZMETLER" kelimesini içeren birden fazla değişken grubunun oluşturulduğu bir örneği inceleyelim.


Ayrıca belirli bir grubun tüm değişkenlere belirli izinlerle erişmesi gereken bir senaryoyu da inceleyin.


Çok sayıda değişken grubu olduğunda kütüphane bölümü


Bu yaygın durumun çözümü de yalnızca REST API aracılığıyla mümkündür:


 " variables: - name: organization value: ORGANIZATION - name: project value: PROJECT - name: pat value: PAT parameters: - name: searchWord type: string default: 'SERVICES' - name: UserOrGroupName type: string default: 'Devops' - name: UserRights type: string default: 'Administrator' steps: - bash: | export organization="$(organization)" export project="$(project)" export pat="$(pat)" export userOrGroupName='${{ parameters.UserOrGroupName }}' export UserRights='${{ parameters.UserRights }}' export searchWord='${{ parameters.searchWord }}' # Perform the API request and store the JSON response in a variable response=$(curl -s -u ":$pat" "https://dev.azure.com/$organization/$project/_apis/distributedtask/variablegroups?api-version=6.0") # Initialize an empty array to store matching JSON objects matching_json=() # Loop through the JSON objects and append matching objects to the array while read -r json; do if [[ $(echo "$json" | jq -r '.name' | grep "$searchWord") ]]; then matching_json+=("$json") fi done < <(echo "$response" | jq -c '.value[]') # Iterate through the matching variable groups and assign permissions for group in "${matching_json[@]}"; do # Extract the variable group ID and name variableGroupId=$(echo "$group" | jq -r '.id') variableGroupName=$(echo "$group" | jq -r '.name') # Determine the type of userOrGroupName (username or group name) if [[ $myString != *'@'* ]]; then # If userOrGroupName matches the username format, it's treated as a username roleName=$UserRights assignType="group" groupsResponse=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/graph/groups?api-version=6.0-preview.1") #groupOriginId=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=$userOrGroupName&api-version=6.0" | jq -r '.value[0].originId') groupOriginId=$(echo "$groupsResponse" | jq -r ".value[] | select(.displayName == \"$userOrGroupName\") | .originId") # Get the user's originId using Azure DevOps REST API #userOriginId=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=$userOrGroupName&api-version=6.0" | jq -r '.value[0].principalName') else # Otherwise, it's treated as a group name roleName=$UserRights assignType="user" userOriginId=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=$userOrGroupName&api-version=6.0" | jq -r '.value[0].principalName') # Get the group's originId using Azure DevOps REST API #groupOriginId=$(curl -s -u ":$pat" "https://vssps.dev.azure.com/$organization/_apis/identities?searchFilter=$userOrGroupName&api-version=6.0" | jq -r '.value[0].originId') fi # Construct the API URL for assigning permissions apiUrl="https://dev.azure.com/$organization/_apis/securityroles/scopes/distributedtask.variablegroup/roleassignments/resources/19802563-1b7b-43d6-81e0-16cf29d68c0d$"$variableGroupId"?api-version=5.1-preview" # Assign permissions based on the userOrGroupName type if [ "$assignType" == "group" ]; then # Assign permissions to a group # Construct the request body with group's originId requestBody="[{ \"roleName\": \"$roleName\", \"userId\": \"$groupOriginId\" }]" else # Assign permissions to a user # Construct the request body with the user's uniqueName requestBody="[{ \"roleName\": \"$roleName\", \"uniqueName\": \"$userOrGroupName\" }]" fi # Execute the REST API call to assign permissions response=$(curl -s -u ":$pat" -X PUT -H "Content-Type: application/json" -d "$requestBody" "$apiUrl") # Check if the permissions were successfully assigned if [[ "$response" == *"error"* ]]; then echo "Error assigning permissions to $assignType '$userOrGroupName' in variable group '$variableGroupName'." else echo "Permissions assigned successfully to $assignType '$userOrGroupName' in variable group '$variableGroupName'." fi done displayName: 'variable-groups' "


Bu süreçleri otomatikleştirerek Azure DevOps'taki haklar ve izin yapılarına ilişkin daha ayrıntılı bir anlayış elde ederek projenin güvenliğini artırdık.


Artık çok çeşitli görevlere yönelik, kullanıcı isteklerinin işlem süresini hızlandıran ve yürütme kalitesini artıran istikrarlı ve çok yönlü işlem hatlarına sahibiz.


Ayrıca rutin işlemlerden uzaklaşıp diğer CI/CD görevlerine daha fazla zaman ayırdığımız için genel sistem geliştirme hızımız ve kalitemiz arttı.


Günlük görevleri otomatikleştirmek, çeşitli uygulama seçeneklerini araştırmak ve analiz etmek, hata ayıklamak ve hassaslaştırmak için önemli çaba harcadık. Hazır işlem hatlarına ve komut dosyalarına sahip olmak, görevleri birkaç saniye içinde gerçekleştirebildikleri için çok büyük kolaylık sağlar.