1. Answers
  2. AWS Backup Cross-account Backup With Pulumi Using TypeScript

AWS Backup Cross-Account Backup With Pulumi Using TypeScript

Introduction

In this solution, we will set up AWS Backup to perform cross-account backups using Pulumi with TypeScript. AWS Backup is a fully managed backup service that makes it easy to centralize and automate the backup of data across AWS services. By leveraging cross-account backups, we can ensure that our backup data is stored in a separate AWS account, providing an additional layer of security and disaster recovery.

The key services involved in this solution are:

  • AWS Backup: To manage and automate backups.
  • AWS IAM: To manage permissions and roles for cross-account access.
  • AWS S3: To store the backup data.

Step-by-Step Explanation

Step 1: Set Up IAM Roles

We will create IAM roles in both the source and destination accounts to allow AWS Backup to perform cross-account backups. The source account role will have permissions to read the backup data, and the destination account role will have permissions to write the backup data to an S3 bucket.

Step 2: Create an S3 Bucket in the Destination Account

We will create an S3 bucket in the destination account to store the backup data. This bucket will be configured to allow access from the source account.

Step 3: Configure AWS Backup in the Source Account

We will set up an AWS Backup plan and backup vault in the source account. The backup plan will define the backup schedule and the resources to be backed up. The backup vault will store the backup data temporarily before it is copied to the destination account.

Step 4: Set Up Cross-Account Backup

We will configure the backup vault in the source account to copy the backup data to the S3 bucket in the destination account. This will involve setting up the necessary permissions and policies to allow cross-account access.

Key Points

  • Ensure that the IAM roles have the necessary permissions for cross-account access.
  • Configure the S3 bucket policy to allow access from the source account.
  • Verify that the backup plan and backup vault are set up correctly in the source account.
  • Test the cross-account backup configuration to ensure that the backup data is successfully copied to the destination account.

Conclusion

By following this solution, we have successfully set up AWS Backup to perform cross-account backups using Pulumi with TypeScript. This configuration provides an additional layer of security and disaster recovery by storing backup data in a separate AWS account. AWS Backup, along with IAM and S3, enables us to automate and manage backups efficiently across multiple accounts.

Full Code Example

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Create IAM Role in Source Account
const sourceRole = new aws.iam.Role("sourceRole", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: "sts:AssumeRole",
                Principal: {
                    Service: "backup.amazonaws.com",
                },
                Effect: "Allow",
                Sid: ""
            }
        ]
    })
});

const sourceRolePolicy = new aws.iam.RolePolicy("sourceRolePolicy", {
    role: sourceRole.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: [
                    "s3:GetObject",
                    "s3:ListBucket"
                ],
                Resource: "*",
                Effect: "Allow"
            }
        ]
    })
});

// Create IAM Role in Destination Account
const destinationRole = new aws.iam.Role("destinationRole", {
    assumeRolePolicy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: "sts:AssumeRole",
                Principal: {
                    Service: "backup.amazonaws.com",
                },
                Effect: "Allow",
                Sid: ""
            }
        ]
    })
});

const destinationRolePolicy = new aws.iam.RolePolicy("destinationRolePolicy", {
    role: destinationRole.id,
    policy: JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Action: [
                    "s3:PutObject",
                    "s3:ListBucket"
                ],
                Resource: "*",
                Effect: "Allow"
            }
        ]
    })
});

// Create S3 Bucket in Destination Account
const backupBucket = new aws.s3.Bucket("backupBucket");

const bucketPolicy = new aws.s3.BucketPolicy("bucketPolicy", {
    bucket: backupBucket.id,
    policy: pulumi.all([backupBucket.arn, sourceRole.arn]).apply(([bucketArn, roleArn]) => JSON.stringify({
        Version: "2012-10-17",
        Statement: [
            {
                Effect: "Allow",
                Principal: {
                    AWS: roleArn,
                },
                Action: [
                    "s3:PutObject",
                    "s3:ListBucket"
                ],
                Resource: [
                    `${bucketArn}/*`,
                    bucketArn
                ]
            }
        ]
    }))
});

// Create Backup Vault in Source Account
const backupVault = new aws.backup.Vault("backupVault");

// Create Backup Plan in Source Account
const backupPlan = new aws.backup.Plan("backupPlan", {
    rules: [{
        ruleName: "dailyBackup",
        targetVaultName: backupVault.name,
        schedule: "cron(0 12 * * ? *)",
        lifecycle: {
            deleteAfter: 30,
        },
    }],
});

// Create Backup Selection in Source Account
const backupSelection = new aws.backup.Selection("backupSelection", {
    iamRoleArn: sourceRole.arn,
    planId: backupPlan.id,
    selectionTags: [{
        type: "STRINGEQUALS",
        key: "backup",
        value: "true",
    }],
});

// Export the ARNs and IDs
export const sourceRoleArn = sourceRole.arn;
export const destinationRoleArn = destinationRole.arn;
export const bucketArn = backupBucket.arn;
export const backupVaultArn = backupVault.arn;
export const backupPlanId = backupPlan.id;

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up