# Azure DevOps Git Repository Archiver

[](https://badge.fury.io/js/azure-devops-repository-archiver)
[](https://badge.fury.io/nu/Io.Github.StefanFreitag.AzureS3RepositoryArchiver)
[](https://badge.fury.io/py/azure-devops-repository-archiver)

Allows to backup regularly git repositories hosted in Azure DevOps to an S3 Bucket.
In the S3 bucket the backups are placed in a "directory" structure like
```plain
|
|--- organization 1
| |
| |--- project 1
| | |
| | |--- repository 1
| | |
| | |--- repository 2
| | | ...
| |
| |--- project 2
| |
| |--- ...
|
|
|--- organization 2
| ...
```
## Features
The S3 bucket is configured as below
* enabled versioning of objects
* enabled encryption using an S3 managed Key
* disallowing public access
* A lifecycle configuration for the archived repositories. They and their
versions transistion through different storage classes
* Infrequent Access after 30 days
* Glacier after 90 days
* Deep Archive 180 days
* Expiry after 365 days
* configurable notifications to SNS about uploaded/ expired objects
The CodeBuild projects are configured as below
* Logging to CloudWatch
* Configurable retention period. Default is one month.
* Encryption using customer-managed KMS key
* Schedule based execution.
* The default schedule is one week and can be overriden as part of the backup
configuration.
## Prerequisites
The connection to the Azure DevOps organization requires a [personal access
token](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate).
The PAT needs to have "Code read" permission and stored in a SecretsManager secret
```shell
aws secretsmanager create-secret --name repository_archiver --description "Secret for the repository archiver" --secret-string "{\"pat\":\"<your_pat>\"}"
```
## How to use
### Example
* Add the library to your dependencies, e.g to the `package.json` file
```javascript
"dependencies": {
[...],
"azure-devops-repository-archiver": "1.4.0",
},
```
* Per `BackupConfiguration` a secret containing the Azure DevOps PAT needs to be
specified. It can e.g. be imported
```python
const secret = Secret.fromSecretAttributes(this, 'azure-devops-pat', {
secretCompleteArn:
'arn:aws:secretsmanager:eu-central-1:<aws_account_id>:secret:<secret_name>',
});
```
* When creating the construct the required `BackupConfiguration`s can be passed
as below. The grouping is per organization and project.
```python
const backupConfigurations: BackupConfiguration[] = [
{
organizationName: 'MyOrganization',
projectName: 'project-1',
repositoryNames: [
'repository-1-a',
'repository-1-b',
],
secretArn: secret.secretArn,
},
{
organizationName: 'MyOrganization',
projectName: 'project-2',
repositoryNames: [
'repository-2-a',
'repository-2-b',
],
secretArn: secret.secretArn,
},
]
```
* The archiver properties and the archiver can then be created as
```python
const archiverProps: ArchiverProperties = {
retention: RetentionDays.ONE_WEEK,
backupConfigurations: backupConfigurations,
};
new Archiver(this, 'archiver', archiverProps);
```
### Restoring a repository
* Download the archive from S3 to your local machine.
* Extract the archive.
```shell
tar xzf backup.tar
```
* Create a new directory and run a `git clone` operation.
```shell
mkdir backup-repo
cd backup-repo
git clone ../backup.git
```
## Links
* [projen](https://github.com/projen/projen)
* [cdk](https://github.com/aws/aws-cdk)
* [AWS CodeBuild Specification](https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html)