Here's the Gurobi code to solve the optimization problem:

```python
import gurobipy as gp

# Create a new model
m = gp.Model("food_optimization")

# Create variables
bananas = m.addVar(lb=0, name="bananas")
chicken_thighs = m.addVar(lb=0, name="chicken_thighs")
strips_of_bacon = m.addVar(lb=0, name="strips_of_bacon")

# Set objective function
m.setObjective(6.76 * bananas + 8.33 * chicken_thighs + 5.66 * strips_of_bacon, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(11.46 * bananas + 6.36 * chicken_thighs >= 17, "c1")
m.addConstr(6.36 * chicken_thighs + 4.63 * strips_of_bacon >= 30, "c2")
m.addConstr(11.46 * bananas + 6.36 * chicken_thighs + 4.63 * strips_of_bacon >= 23, "c3")
m.addConstr(6.51 * bananas + 10.01 * chicken_thighs >= 52, "c4")
m.addConstr(10.01 * chicken_thighs + 7.3 * strips_of_bacon >= 27, "c5")
m.addConstr(6.51 * bananas + 7.3 * strips_of_bacon >= 51, "c6")
m.addConstr(6.51 * bananas + 10.01 * chicken_thighs + 7.3 * strips_of_bacon >= 51, "c7")
m.addConstr(11.08 * bananas + 10.99 * strips_of_bacon >= 10, "c8")
m.addConstr(11.08 * bananas + 5.82 * chicken_thighs + 10.99 * strips_of_bacon >= 10, "c9")
m.addConstr(8 * bananas - 6 * strips_of_bacon >= 0, "c10")
m.addConstr(-1 * bananas + 3 * chicken_thighs >= 0, "c11")
m.addConstr(11.46 * bananas + 4.63 * strips_of_bacon <= 119, "c12")
m.addConstr(6.36 * chicken_thighs + 4.63 * strips_of_bacon <= 123, "c13")
m.addConstr(6.51 * bananas + 7.3 * strips_of_bacon <= 168, "c14")
m.addConstr(10.01 * chicken_thighs + 7.3 * strips_of_bacon <= 107, "c15")
m.addConstr(6.51 * bananas + 10.01 * chicken_thighs <= 171, "c16")
m.addConstr(11.08 * bananas + 10.99 * strips_of_bacon <= 16, "c17")


# Add resource constraints based on the provided dictionary
resource_data = {'r0': {'description': 'grams of carbohydrates', 'upper_bound': 135, 'x0': 11.46, 'x1': 6.36, 'x2': 4.63}, 'r1': {'description': 'tastiness rating', 'upper_bound': 179, 'x0': 6.51, 'x1': 10.01, 'x2': 7.3}, 'r2': {'description': 'sourness index', 'upper_bound': 31, 'x0': 11.08, 'x1': 5.82, 'x2': 10.99}}

for resource, data in resource_data.items():
    m.addConstr(data['x0'] * bananas + data['x1'] * chicken_thighs + data['x2'] * strips_of_bacon <= data['upper_bound'], resource)


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    print('bananas:', bananas.x)
    print('chicken_thighs:', chicken_thighs.x)
    print('strips_of_bacon:', strips_of_bacon.x)
elif m.status == gp.GRB.INFEASIBLE:
    print('The model is infeasible.')
else:
    print('Optimization ended with status %d' % m.status)

```
