diff --git a/pkg/setup/item.go b/pkg/setup/item.go
index d275d0ff38fa33e7c2a77010344b5f6117d2310d..a17512d0c0ce38714cc52cd7752ec7149ae292b3 100644
--- a/pkg/setup/item.go
+++ b/pkg/setup/item.go
@@ -18,18 +18,21 @@ var (
 )
 
 type ItemsOption func(c *ItemConfig)
+type PublishItemFn func(s *Setup, item *items.Item) (*items.Item, bool)
 type UpdateItemFn func(s *Setup, exist, new *items.Item) (*items.Item, bool)
 type DeleteItemFn func(s *Setup, col *items.Item) bool
 
 type ItemConfig struct {
-	item     *items.Item
-	UpdateFn UpdateItemFn
-	DeleteFn DeleteItemFn
+	item      *items.Item
+	PublishFn PublishItemFn
+	UpdateFn  UpdateItemFn
+	DeleteFn  DeleteItemFn
 }
 
 func NewItemConfig(item *items.Item, opt ...ItemsOption) ItemConfig {
 	c := ItemConfig{item: item}
 
+	PublishItem()(&c)
 	KeepExistingItem()(&c)
 	DeleteItemIfRemove()(&c)
 
@@ -120,6 +123,18 @@ func DeleteItemIfRemove() ItemsOption {
 	}
 }
 
+func PublishItem() ItemsOption {
+	return func(c *ItemConfig) {
+		c.PublishFn = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, true }
+	}
+}
+
+func KeepDraft() ItemsOption {
+	return func(c *ItemConfig) {
+		c.PublishFn = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, false }
+	}
+}
+
 func (s *Setup) InstallItems(ctx context.Context) error {
 	if len(s.Items) == 0 {
 		return nil
@@ -153,11 +168,27 @@ func (s *Setup) InstallItem(ctx context.Context, exists map[string]*items.Item,
 
 	exist, ok := exists[item.ID]
 	if !ok {
-		return items.CreateAndPublishItem(ctx, s.content.Items, item)
+		if item, publish := c.PublishFn(s, item); publish {
+			return items.CreateAndPublishItem(ctx, s.content.Items, item)
+		}
+		if _, err := s.content.Items.Create(ctx, item); err != nil {
+			return errors.Wrap(err, "create item")
+		}
+		return nil
 	}
 
-	if item, changed := c.UpdateFn(s, exist, c.item); changed {
-		return items.UpdateAndPublishItem(ctx, s.content.Items, item)
+	if item, changed := c.UpdateFn(s, exist, item); changed {
+		if _, publish := c.PublishFn(s, item); publish {
+			return items.UpdateAndPublishItem(ctx, s.content.Items, item)
+		}
+		if err := s.content.Items.Update(ctx, item); err != nil {
+			return errors.Wrap(err, "update item")
+		}
+		if err := s.content.Items.Unpublish(ctx, item); err != nil {
+			return errors.Wrap(err, "unpublish item")
+		}
+		return nil
+
 	}
 
 	return nil
diff --git a/pkg/setup/item_test.go b/pkg/setup/item_test.go
index 920292f501cf9e469150621b3894bcad41326aa8..2d2e1a7705a80be6d4eb783af5ad81daf431e886 100644
--- a/pkg/setup/item_test.go
+++ b/pkg/setup/item_test.go
@@ -277,3 +277,89 @@ func TestSetup_InstallItems(t *testing.T) {
 		})
 	}
 }
+
+func TestSetup_CreateDraft(t *testing.T) {
+
+	tests := []struct {
+		name      string
+		items     []*items.Item
+		itemsCall func(svc *itemsMock.Items)
+		wantErr   func(t *testing.T, err error)
+	}{
+		{
+			name:  "Install one item",
+			items: []*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}},
+			itemsCall: func(svc *itemsMock.Items) {
+				svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, 0, nil).Once()
+				svc.On("Create", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once()
+			},
+			wantErr: func(t *testing.T, err error) {
+				assert.NoError(t, err)
+			},
+		},
+		{
+			name: "Install multiple items success",
+			items: []*items.Item{
+				{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}},
+				{ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}},
+			},
+			itemsCall: func(svc *itemsMock.Items) {
+				svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, 0, nil).Once()
+				svc.On("Create", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once()
+				svc.On("Create", mock.Anything, &items.Item{ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once()
+			},
+			wantErr: func(t *testing.T, err error) {
+				assert.NoError(t, err)
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			i := &itemsMock.Items{}
+			if tt.itemsCall != nil {
+				tt.itemsCall(i)
+			}
+
+			s := NewSetup(&content.Content{Items: i}, "sp", "env", nil)
+			s.AddItems(tt.items, KeepDraft())
+			tt.wantErr(t, s.InstallItems(context.Background()))
+		})
+	}
+}
+
+func TestSetup_UpdateDraft(t *testing.T) {
+
+	tests := []struct {
+		name      string
+		items     []*items.Item
+		itemsCall func(svc *itemsMock.Items)
+		wantErr   func(t *testing.T, err error)
+	}{
+		{
+			name:  "Update one item that was published",
+			items: []*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}},
+			itemsCall: func(svc *itemsMock.Items) {
+				svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}}, 1, nil).Once()
+				svc.On("Update", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}).Return(nil).Once()
+				svc.On("Unpublish", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}).Return(nil).Once()
+			},
+			wantErr: func(t *testing.T, err error) {
+				assert.NoError(t, err)
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			i := &itemsMock.Items{}
+			if tt.itemsCall != nil {
+				tt.itemsCall(i)
+			}
+
+			s := NewSetup(&content.Content{Items: i}, "sp", "env", nil)
+			s.AddItems(tt.items, KeepDraft())
+			tt.wantErr(t, s.InstallItems(context.Background()))
+		})
+	}
+}