diff --git a/br/pkg/aws/ebs.go b/br/pkg/aws/ebs.go index 01f912e78f140..8c0af465dd103 100644 --- a/br/pkg/aws/ebs.go +++ b/br/pkg/aws/ebs.go @@ -149,7 +149,20 @@ func (e *EC2Session) CreateSnapshots(backupInfo *config.EBSBasedBRMeta) (map[str resp, err := e.createSnapshotsWithRetry(context.TODO(), &createSnapshotInput) if err != nil { - return errors.Trace(err) + if aErr, ok := err.(awserr.Error); ok { + if aErr.Code() == "TagLimitExceeded" { + log.Warn("tag number exceeds AWS limitation during snapshots, retry without tagging") + createSnapshotInput.SetTagSpecifications(nil) + resp, err = e.createSnapshotsWithRetry(context.TODO(), &createSnapshotInput) + if err != nil { + return errors.Trace(err) + } + } else { + return errors.Trace(err) + } + } else { + return errors.Trace(err) + } } fillResult(resp) return nil @@ -592,10 +605,12 @@ func (e *EC2Session) CreateVolumes(meta *config.EBSBasedBRMeta, volumeType strin return errors.Errorf("specified snapshot [%s] is not found", oldVol.SnapshotID) } - // Copy tags from source snapshots + // Copy tags from source snapshots, but avoid recursive tagging for j := range resp.Snapshots[0].Tags { - tags = append(tags, - ec2Tag("snapshot/"+aws.StringValue(resp.Snapshots[0].Tags[j].Key), aws.StringValue(resp.Snapshots[0].Tags[j].Value))) + if !strings.HasPrefix(aws.StringValue(resp.Snapshots[0].Tags[j].Key), "snapshot/") { + tags = append(tags, + ec2Tag("snapshot/"+aws.StringValue(resp.Snapshots[0].Tags[j].Key), aws.StringValue(resp.Snapshots[0].Tags[j].Value))) + } } req.SetTagSpecifications([]*ec2.TagSpecification{ @@ -607,7 +622,20 @@ func (e *EC2Session) CreateVolumes(meta *config.EBSBasedBRMeta, volumeType strin newVol, err := e.ec2.CreateVolume(&req) if err != nil { - return errors.Trace(err) + if aErr, ok := err.(awserr.Error); ok { + if aErr.Code() == "TagLimitExceeded" { + log.Warn("tag number exceeds AWS limitation, retry without tagging", zap.String("from_snapshot", oldVol.SnapshotID)) + req.SetTagSpecifications(nil) + newVol, err = e.ec2.CreateVolume(&req) + if err != nil { + return errors.Trace(err) + } + } else { + return errors.Trace(err) + } + } else { + return errors.Trace(err) + } } log.Info("new volume creating", zap.Stringer("vol", newVol)) fillResult(newVol, oldVol)