iT邦幫忙

0

如何備份 Azure DevOps Git 儲存庫

  • 分享至 

  • xImage
  •  

Azure DevOps 提供 99.9% 的 SLA 服務等級保證,表示一年之中必須要有 99.9% 的時間正常營運,如果 Azure DevOps 在特定月份遺漏 SLA,則會將每月費用的一部分退款。

換言之,無法提供服務的時間為 8 小時 45 分 36 秒。

(60秒 * 60分 * 24小時 * 365天 ) * 0.1% = 31536秒 = 8 小時 45 分 36 秒

為了防止意外刪除資料,Microsoft 也會針對 Azure Blob 和 Azure SQL 資料庫進行時間點備份。Azure DevOps 會利用這項功能維護您的資料 28 天,這些備份也會在配對區域中複寫,以協助從區域中斷復原。

Azure DevOps 可以在刪除後最多 28 天復原已刪除的組織或專案。

  • 這些備份僅適用于商務持續性,並協助從中斷或災害案例中復原。
  • 不包括客戶意外刪除資產(例如儲存庫、工作專案、附件或成品)
  • 不支援還原客戶意外刪除的資產

雖然 Azure DevOps 有 99.9 的 SLA,但它仍然有趴下的可能性。

又或是哪天某位同事突然中邪把 Repository 給刪了

在組織評估其資訊系統與資產所面臨的潛在風險時,就必須將這一點納入考量,尤其是資訊單位同時又擔任 RD 的角色時,程式碼版本管控伺服器的備援就相當重要。

在資訊安全風險評鑑的過程,我們就會列舉資訊系統可能遇到的風險情境與影響範圍,根據損害的等級與發生的可能性來估算風險值。

若超出可承受之風險值,組織就必須有所作為。
例如新增風險處理措施來備份 Azure DevOps Git 儲存庫,並評估殘餘風險值是否在可接受之範圍。

如何備份 Azure DevOps Git 儲存庫
以下我們將了解如何使用 YAML 檔案備份儲存庫。

包括以下步驟:

  • 建立 Azure DevOps 個人存取權杖 (PAT)
  • 建立 YAML 文件
  • 建立訂閱連接

建立 Azure DevOps 個人存取權杖 (PAT)
登入您的 Azure DevOps 門戶,前往個人存取權杖。

點選 New Token 建立令牌

輸入 Token 的名字,例如 Repo Backup Token。

選擇您的 Organization

範圍選擇 Custom defined,只給予該 Token 對 Code 有讀取權限

到期日可以選擇 Custom defined,最久可以設定一年。

注意:複製並保存 Token,因為您將無法再次看到它。

建立 YAML 文件
前往 Pipelines,建立 Pipeline。

選擇 Azure Repos Git

選擇您要備份的 Repository。

選擇 Starter pipeline

以下是您將看到的預設代碼

將 yaml 更新為以下程式碼

trigger:
  branches:
    include:
      - '*'
stages:
  - stage: _default
    jobs:
      - job: Job
        pool: 
          vmImage: windows-latest
        steps:
          - task: CmdLine@2
            inputs:
              script: git clone --mirror https://{pat-token}@dev.azure.com/{organization}/{project}/_git/{repo}
          - task: ArchiveFiles@2
            inputs:
              rootFolderOrFile: $(System.DefaultWorkingDirectory)
              includeRootFolder: true
              archiveType: zip
              archiveFile : $(Build.ArtifactStagingDirectory)/Backup.zip
              replaceExistingArchive: true
          - task: AzureFileCopy@3
            displayName: AzureBlob File Copy
            inputs:
              SourcePath: $(Build.ArtifactStagingDirectory)/Backup.zip
              azureSubscription: '{subscription-connection}'
              Destination: 'AzureBlob'
              storage: '{storage-name}'
              ContainerName : '{container-name}'
              BlobPrefix : '{blob-name}'

Trigger:通配符 * 將監視所有分支,儲存庫中有任何變更時都會觸發管道。

CmdLine:呼叫 git clone –mirror 來建立儲存庫的副本,取得儲存庫時需要使用個人存取權杖 (PAT)。

存檔檔案:將取得上一個步驟中複製的 git 儲存庫,壓縮為 Backup.zip。

檔案複製:它將取得存檔副本並將其傳送至 Azure Blob 存儲

建立訂閱連接
前往專案設定

前往 Service Connections

建立 Service Connection

選擇 Azure Resource Manager

認證方式選擇 Service Principal (automatic)

選擇您擁有儲存帳戶的資源群組

輸入訂閱連接的名字,例如 repobackup。

儲存後完成

回到 YAML 文件

我們需要填寫以下參數

  • {pat-token}:使用上面取得的 PAT 個人存取權杖
  • {organization}:您的組織名稱
  • {project}:儲存庫所在的專案名稱,例如 UPInstrument。
  • {repo}:要備份的儲存庫,例如 Wpf_ASTM。
  • {subscription-connection}:替換為 Azure Service Connection Name,例如 repobackup。
  • {storage-name}:存放備份的儲存體帳號名稱
  • {container-name}:存放備份的容器名稱
  • {blob-name}:設定 BlobPrefix,選用的。

確認完成後,點選 Save and Run。

第一次執行會遇到權限請求,點選 View。

允許存取

沒有意外的話,通常會執行成功。

Pipeline 也會發信通知您

前往儲存體帳號進行驗證,資料果然產生了。

建議設定 BlobPrefix,會多一層資料夾方便我們區分備份檔案。

點進去就可以看到儲存庫的備份了

我們也可以使用變數把日期加入檔名

trigger:
  branches:
    include:
      - '*'
variables: 
  backup_date: $[format('{0:yyyy}-{0:MM}-{0:dd}T{0:HH}-{0:mm}-{0:ss}', pipeline.startTime)]
stages:
  - stage: _default
    jobs:
      - job: Job
        pool: 
          vmImage: windows-latest
        steps:
          - task: CmdLine@2
            inputs:
              script: git clone --mirror https://{pat-token}@dev.azure.com/{organization}/{project}/_git/{repo}
          - task: ArchiveFiles@2
            inputs:
              rootFolderOrFile: $(System.DefaultWorkingDirectory)
              includeRootFolder: true
              archiveType: zip
              archiveFile : $(Build.ArtifactStagingDirectory)/$(backup_date)_Backup.zip
              replaceExistingArchive: true
          - task: AzureFileCopy@3
            displayName: AzureBlob File Copy
            inputs:
              SourcePath: $(Build.ArtifactStagingDirectory)/$(backup_date)_Backup.zip
              azureSubscription: '{subscription-connection}'
              Destination: 'AzureBlob'
              storage: '{storage-name}'
              ContainerName : '{container-name}'
              BlobPrefix : '{blob-name}'

每次產出的備份檔案就不會被覆寫了

定期刪除備份
我們可以到 Stroage Account 的 Lifecycle Management,新增規則。

輸入規則名稱

若 Blob 超過 30 天沒有修改,則進行刪除。
當然您也可以設定先搬至冷儲存在進行刪除,來節省儲存體的費用。

還原備份檔案
接下來我們要透過 Backup.zip 去還原 Azure DevOps 的 Repository,很多人備份都不做還原測試,等出事之後才發現備份檔根本無效,我們事情不要做半套阿。

If you don’t like your job, you don’t strike! You just go in every day and do it really half-assed. That’s the American way.

如果你不喜歡你的工作,你不主動出擊,你就每天一樣去上班,然後把事情亂做或做一半,這就是美國人的做法。

下載備份檔案

接其解壓縮

使用命令提示字元切換到該路徑底下

就可以透過下列指令進行還原到原本的 Repository

git push --force --mirror https://dev.azure.com/{your_organization}/{your_project}/_git/{your_repo}

發生錯誤,缺少 ForcePush 權限。

Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM
 * [new reference]   origin/main -> origin/main
 ! [remote rejected] main (TF401027: You need the Git 'ForcePush' permission to perform this action. Details: identity '61d9f138-8c41-45f6-8c24-e69e4dc9b580\ivan_cheng@domain', scope 'branch'.)
error: failed to push some refs to 'https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM'

前往專案設定,調整自己所屬角色的權限允許 ForcePush。

再試一次就成功了

Enumerating objects: 12, done.
Counting objects: 100% (12/12), done.
Delta compression using up to 8 threads
Compressing objects: 100% (12/12), done.
Writing objects: 100% (12/12), 9.00 KiB | 4.50 MiB/s, done.
Total 12 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Analyzing objects... (12/12) (7 ms)
remote: Validating commits... (2/2) done (0 ms)
remote: Storing packfile... done (50 ms)
remote: Storing index... done (66 ms)
To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM
 - [deleted]         origin/dd11a2ae47a38e348d72515e83759e37436c97a1
 - [deleted]         origin/main
 * [new branch]      ivan -> ivan
 * [new branch]      main -> main
 * [new branch]      master -> master

也可以還原到新的 Repository,建立一個新的叫 Wpf_ASTM_Restore

Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Delta compression using up to 8 threads
Compressing objects: 100% (37/37), done.
Writing objects: 100% (38/38), 12.73 KiB | 2.54 MiB/s, done.
Total 38 (delta 9), reused 0 (delta 0), pack-reused 0
remote: Analyzing objects... (38/38) (7 ms)
remote: Validating commits... (12/12) done (0 ms)
remote: Storing packfile... done (49 ms)
remote: Storing index... done (50 ms)
To https://dev.azure.com/{your_organization}/UPInstrument/_git/Wpf_ASTM_Restore
 + 80e8be0...dd11a2a main -> main (forced update)
 * [new branch]      ivan -> ivan
 * [new branch]      master -> master

回到 Repository 檢查,程式碼都順利回來囉。

還原到 GitHub 也是沒問題

git push --force --mirror https://github.com/jieshiun/Wpf_ASTM.git
Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Delta compression using up to 8 threads
Compressing objects: 100% (37/37), done.
Writing objects: 100% (38/38), 12.57 KiB | 559.00 KiB/s, done.
Total 38 (delta 9), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (9/9), done.
To https://github.com/jieshiun/Wpf_ASTM.git
 * [new branch]      ivan -> ivan
 * [new branch]      main -> main
 * [new branch]      master -> master

今天的分享就到這邊,謝謝大家。

後續更新
如何在 Azure DevOps 備份多個儲存庫

參考文件

  1. https://learn.microsoft.com/zh-tw/azure/devops/organizations/security/data-protection?view=azure-devops
  2. https://www.cloudfronts.com/azure/azure-devops-services/backup-azure-devops-git-repositorie
  3. https://learn.microsoft.com/zh-tw/azure/devops/pipelines/tasks/reference/azure-file-copy-v3?view=azure-pipelines
  4. https://charbelnemnom.com/how-to-backup-azure-devops-git-repositories

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言