It is a best practice to keep root on a separate aggregate (wafl_check , wafliron), however on smaller systems like this we often use one aggregate to contain all volumes. Just make sure you have a volume guarantee on all volumes (default is volume guarantee) so the root volume never runs out of space. So you could do something like below to get about 2TB usable across both nodes (6x 450GB data drives split across 2 controllers)..
3x aggr0 (rg0: 1D+2P)
7x aggr0 (rg0: 5D+2P)
Or you could make a more even layout to use both nodes symmetrically (not required) to get ~1TB usable per node.
Spares are not global, so each controller needs a dedicated spare. Disk ownership is used to assign disks between controllers. The layout below is for aggregates, not for root. The root volume will be a flexible volume and can share aggr0 with other volumes. For a larger system we don't prefer doing this, but for smaller systems like this it is common. The root volume in aggr0 can be as small as 10GB for a 2020, but I wouldn't go that small...maybe 50 or 100GB or whatever is enough depending on if you are running cifs auditing or other logging. Out of the 2TB, you will subtract the root volume size then have the rest of the aggr0 aggregate free for other flexible volumes.
You don't need a dedicated root aggregate - it may be recommended for bigger systems, but makes no sense with just 12 drives.
So you can assign 3 drives to controller 1 - assuming it will be in fact passive (containing only root volume), and all remaining drives to controller 2 - keeping there its root volume plus all your actual data (in separate volumes, but within the same aggregate)