You need to outer-join a query that calculates the actual sums to a query that generates a dummy row for each month, using the month as the join key.
Here is how I would do it in Oracle using CONNECT BY LEVEL:
select foo.monthdate
, bar.amount_sum
from (select add_months(to_date('01-JAN-2011'),level-1) as MONTHDATE
from dual
connect by level <= 8
) foo
, (select trunc(sale_date,'MM') as SALE_MONTH
, sum(amount) as AMOUNT_SUM
from sales
where sale_date >= '01-JAN-2011'
and sale_date < '01-SEP-2011'
group by trunc(sale_date,'MM')
) bar
where foo.monthdate = bar.sale_month(+)
order by foo.monthdate
Unfortunately there's no simple translation of CONNECT BY LEVEL to Postgres (edit: apparently there is, see Jack Douglas' answer), but a simple alternative is to construct a date dimension table...
create table date_dim
(
date_id number
, daydate date
, week_begin date
, month_begin date
, year number
, month number
, day_of_month number
, day_of_year number
--et cetera...
);
...and populate that table with every date for a hundred years in both directions. Then you can generate the dates you need very simply (converting dates to spelled-out months left as an exercise for the reader):
select daydate
from date_dim
where daydate >= '01-JAN-2011'
and daydate < '01-SEP-2011'
and day_of_month = 1