Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

154 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

terraform-aws-github-backup

Need Help? Docs Registry Release Security License

AWS ECS AWS S3

A Terraform module that backs up all repositories in a GitHub organization to S3 using an ECS Fargate scheduled task. Designed to be deployed by the customer in their own AWS account with zero operational dependency on InfraHouse.

Why This Module?

  • No always-on compute -- Fargate runs on a schedule, you only pay for backup time
  • No Lambda timeout limits -- large organizations with many repos back up without issues
  • Customer-owned GitHub App -- no shared credentials, short-lived tokens only
  • Cross-region replication -- S3 replication for disaster recovery
  • Full git history -- uses git bundle for complete, portable backups

Features

  • ECS Fargate scheduled task (EventBridge) for daily/custom-schedule backups
  • S3 bucket with versioning and configurable retention lifecycle
  • Cross-region S3 replication (AWS provider v6, no aliased providers)
  • CloudWatch Logs, metrics, and alarm on backup failure
  • Least-privilege IAM roles for task execution and task runtime
  • Customer creates and owns their own GitHub App (read-only access)

Architecture

Architecture

Quick Start

  1. Create a GitHub App in your organization (see Getting Started)
  2. Deploy the module -- the module creates a Secrets Manager secret for the App private key:
module "github_backup" {
  source  = "registry.infrahouse.com/infrahouse/github-backup/aws"
  version = "2.0.3"

  github_app_id              = "123456"
  github_app_installation_id = "78901234"

  alarm_emails                  = ["devops@example.com"]
  github_app_key_secret_writers = [aws_iam_role.deployer.arn]
  replica_region                = "us-east-1"
  subnets                       = ["subnet-abc123", "subnet-def456"]

  # Optional
  schedule_expression  = "rate(1 day)"
  backup_retention_days = 365
}
  1. Store the App private key in the secret created by the module (output: github_app_key_secret_arn)

Documentation

Requirements

Name Version
terraform ~> 1.5
aws ~> 6.0

Providers

Name Version
aws 6.49.0

Modules

Name Source Version
backup_bucket registry.infrahouse.com/infrahouse/s3-bucket/aws 0.6.0
github_app_key registry.infrahouse.com/infrahouse/secret/aws ~> 1.1

Resources

Name Type
aws_cloudwatch_event_rule.backup resource
aws_cloudwatch_event_target.backup resource
aws_cloudwatch_log_group.backup resource
aws_cloudwatch_log_group.container_insights resource
aws_cloudwatch_metric_alarm.backup_failure resource
aws_cloudwatch_metric_alarm.task_not_running resource
aws_ecs_cluster.backup resource
aws_ecs_task_definition.backup resource
aws_iam_role.eventbridge resource
aws_iam_role.execution resource
aws_iam_role.task resource
aws_iam_role_policy.eventbridge resource
aws_iam_role_policy.task resource
aws_iam_role_policy_attachment.execution resource
aws_s3_bucket_lifecycle_configuration.backup resource
aws_security_group.backup resource
aws_sns_topic.alarms resource
aws_sns_topic_subscription.alarm_emails resource
aws_vpc_security_group_egress_rule.all_outbound resource
aws_caller_identity.current data source
aws_default_tags.provider data source
aws_iam_policy.ecs_task_execution data source
aws_iam_policy_document.eventbridge_assume_role data source
aws_iam_policy_document.eventbridge_permissions data source
aws_iam_policy_document.execution_assume_role data source
aws_iam_policy_document.task_assume_role data source
aws_iam_policy_document.task_permissions data source
aws_region.current data source
aws_subnet.selected data source

Inputs

Name Description Type Default Required
alarm_emails List of email addresses to receive CloudWatch alarm
notifications. AWS will send confirmation emails that
must be accepted.
list(string) n/a yes
backup_retention_days Number of days to retain backups in S3 before
expiration. Set to 0 to disable expiration.
number 365 no
environment Name of environment. string "development" no
force_destroy Allow destroying S3 buckets even when they contain
objects. Set to true only for testing.
bool false no
github_app_id The GitHub App ID. Found in the App's settings page. string n/a yes
github_app_installation_id The installation ID of the GitHub App on
the target organization.
string n/a yes
github_app_key_secret_writers List of IAM role ARNs that are allowed to write
the GitHub App private key (PEM) into the secret
created by this module.
list(string) n/a yes
image_uri Docker image URI for the backup runner.
Defaults to the InfraHouse public ECR image tagged "latest".
For production use, consider pinning to a specific commit SHA tag
(e.g., "public.ecr.aws/infrahouse/github-backup:abc1234")
to avoid unexpected changes.
string "public.ecr.aws/infrahouse/github-backup:latest" no
log_group_kms_key_arn ARN of a KMS key to encrypt the CloudWatch Log Group.
If null, logs are encrypted with the default
AWS-managed key.
string null no
log_retention_days Number of days to retain CloudWatch logs. number 365 no
replica_region AWS region for cross-region backup replication. string n/a yes
s3_bucket_name Name for the S3 backup bucket.
If null, a name is auto-generated.
string null no
schedule_expression EventBridge schedule expression for backup frequency.
Examples: "rate(1 day)", "cron(0 2 * * ? *)"
string "rate(1 day)" no
service_name Descriptive name of the service.
Used for naming resources.
string "github-backup" no
subnets List of subnet IDs for the Fargate task.
The subnets must have outbound internet access
(GitHub API, S3, etc.) — either private subnets
with a NAT gateway or public subnets.
Public IP assignment is detected automatically
from the subnet configuration.
list(string) n/a yes
tags Tags to apply to all resources. map(string) {} no
task_cpu CPU units for the Fargate task (1024 = 1 vCPU). number 1024 no
task_ephemeral_storage_gb Ephemeral storage (GiB) for the Fargate task.
Must be large enough to hold the biggest single
repository mirror and its git bundle simultaneously.
number 50 no
task_memory Memory (MiB) for the Fargate task. number 2048 no

Outputs

Name Description
ecs_cluster_arn ARN of the ECS cluster.
ecs_cluster_name Name of the ECS cluster.
github_app_key_secret_arn ARN of the Secrets Manager secret for the GitHub App private key.
log_group_name Name of the CloudWatch log group.
replica_bucket_arn ARN of the replica S3 bucket (cross-region).
replica_bucket_name Name of the replica S3 bucket (cross-region).
s3_bucket_arn ARN of the S3 bucket where backups are stored.
s3_bucket_name Name of the S3 bucket where backups are stored.
schedule_rule_arn ARN of the EventBridge schedule rule.
security_group_id ID of the security group for the Fargate task.
task_definition_arn ARN of the ECS task definition.
task_role_arn ARN of the IAM role used by the backup task.

Contributing

See CONTRIBUTING.md for guidelines.

License

Apache 2.0

About

Terraform module for Lambda-based GitHub organization backup to S3 with scheduled execution, repository cloning, and CloudWatch monitoring.

Topics

Resources

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages