code: func (p *OCIProvider) ApplyChanges(changes *plan.Changes) error {
  	log.Debugf("Processing chages: %+v", changes)
  
  	ops := []dns.RecordOperation{}
  	ops = append(ops, p.newFilteredRecordOperations(changes.Create, dns.RecordOperationOperationAdd)...)
  
  	ops = append(ops, p.newFilteredRecordOperations(changes.UpdateNew, dns.RecordOperationOperationAdd)...)
  	ops = append(ops, p.newFilteredRecordOperations(changes.UpdateOld, dns.RecordOperationOperationRemove)...)
  
  	ops = append(ops, p.newFilteredRecordOperations(changes.Delete, dns.RecordOperationOperationRemove)...)
  
  	if len(ops) == 0 {
  		log.Info("All records are already up to date")
  		return nil
  	}
  
  	ctx := context.Background()
  	zones, err := p.zones(ctx)
  	if err != nil {
  		return errors.Wrap(err, "fetching zones")
  	}
  
  	// Separate into per-zone change sets to be passed to OCI API.
  	opsByZone := operationsByZone(zones, ops)
  	for zoneID, ops := range opsByZone {
  		log.Infof("Change zone: %q", zoneID)
  		for _, op := range ops {
  			log.Info(op)
  		}
  	}
  
  	if p.dryRun {
  		return nil
  	}
  
  	for zoneID, ops := range opsByZone {
  		if _, err := p.client.PatchZoneRecords(ctx, dns.PatchZoneRecordsRequest{
  			CompartmentId:           &p.cfg.CompartmentID,
  			ZoneNameOrId:            &zoneID,
  			PatchZoneRecordsDetails: dns.PatchZoneRecordsDetails{Items: ops},
  		}); err != nil {
  			return err
  		}
  	}
  
  	return nil
  }
docs: // ApplyChanges applies a given set of changes to a given zone.