I hope I have understood this correctly please add a comment to clarify if this is not the case.
One solution would be to use facets to separate the plot the rows. To do this I have used the facet_wrap() function to separate the different group 2s and set the y axis to use the different group 1s.
library(tidyverse)
group1 = c(rep("A",3),rep("B",3),rep("C",3))
group2 = c(rep(c("param1","param2","param3"),3))
est = rnorm(9,mean = 0, sd = 1)
lwr = est - sd(est)
upr = est + sd(est)
df = data.frame(group1,group2,est,lwr,upr)
# Swapped the x axis to use group1
figure.gg = ggplot(data = df, aes(x = group1, y = est, ymin = lwr, ymax = upr)) +
geom_point(position = position_dodge(width = 0.5)) +
geom_errorbar(position = position_dodge(width = 0.5), width = 0.1) +
coord_flip() +
# Facet wrapped with one column using group 2s
facet_wrap(~group2, ncol = 1, strip.position = "right") +
ylab("estimate")
figure.gg

Created on 2021-04-05 by the reprex package (v2.0.0)
Alternatively we could use a secondary grouping to separate the different entries such as group = group1 or colour = group1 which are set within aes(). These are presented below
# Set group 1 as a group in aes
figure.gg = ggplot(data = df, aes(x = group2, group = group1, y = est, ymin = lwr, ymax = upr)) +
geom_point(position = position_dodge(width = 0.5)) +
geom_errorbar(position = position_dodge(width = 0.5), width = 0.1) +
coord_flip() +
ylab("estimate")
figure.gg

# Set group1 as the colour using aes
figure.gg = ggplot(data = df, aes(x = group2, colour = group1, y = est, ymin = lwr, ymax = upr)) +
geom_point(position = position_dodge(width = 0.5)) +
geom_errorbar(position = position_dodge(width = 0.5), width = 0.1) +
coord_flip() +
ylab("estimate")
figure.gg

Created on 2021-04-05 by the reprex package (v2.0.0)