diff --git a/client/device/cloudfmc/fmcappliance/update.go b/client/device/cloudfmc/fmcappliance/update.go
index 297d8702..4117f448 100644
--- a/client/device/cloudfmc/fmcappliance/update.go
+++ b/client/device/cloudfmc/fmcappliance/update.go
@@ -9,10 +9,10 @@ import (
 type UpdateInput struct {
 	FmcApplianceUid     string
 	QueueTriggerState   string
-	StateMachineContext *map[string]string
+	StateMachineContext map[string]string
 }
 
-func NewUpdateInput(FmcApplianceUid, queueTriggerState string, stateMachineContext *map[string]string) UpdateInput {
+func NewUpdateInput(FmcApplianceUid, queueTriggerState string, stateMachineContext map[string]string) UpdateInput {
 	return UpdateInput{
 		FmcApplianceUid:     FmcApplianceUid,
 		QueueTriggerState:   queueTriggerState,
@@ -27,9 +27,8 @@ type UpdateOutput struct {
 }
 
 type updateRequestBody struct {
-	QueueTriggerState   string             `json:"queueTriggerState"`
-	StateMachineContext *map[string]string `json:"stateMachineContext,omitempty"`
-	Uid                 string             `json:"uid,omitempty"`
+	QueueTriggerState   string            `json:"queueTriggerState"`
+	StateMachineContext map[string]string `json:"stateMachineContext"`
 }
 
 func Update(ctx context.Context, client http.Client, updateInp UpdateInput) (*UpdateOutput, error) {
@@ -37,7 +36,6 @@ func Update(ctx context.Context, client http.Client, updateInp UpdateInput) (*Up
 	updateBody := newUpdateRequestBodyBuilder().
 		QueueTriggerState(updateInp.QueueTriggerState).
 		StateMachineContext(updateInp.StateMachineContext).
-		Uid(updateInp.FmcApplianceUid).
 		Build()
 	req := client.NewPut(ctx, updateUrl, updateBody)
 	var updateOup UpdateOutput
diff --git a/client/device/cloudfmc/fmcappliance/update_inputbuilder.go b/client/device/cloudfmc/fmcappliance/update_inputbuilder.go
index eab12f77..648753bb 100644
--- a/client/device/cloudfmc/fmcappliance/update_inputbuilder.go
+++ b/client/device/cloudfmc/fmcappliance/update_inputbuilder.go
@@ -20,7 +20,7 @@ func (b *UpdateInputBuilder) QueueTriggerState(queueTriggerState string) *Update
 	return b
 }
 
-func (b *UpdateInputBuilder) StateMachineContext(stateMachineContext *map[string]string) *UpdateInputBuilder {
+func (b *UpdateInputBuilder) StateMachineContext(stateMachineContext map[string]string) *UpdateInputBuilder {
 	b.updateInput.StateMachineContext = stateMachineContext
 	return b
 }
diff --git a/client/device/cloudfmc/fmcappliance/update_outputbuilder.go b/client/device/cloudfmc/fmcappliance/update_outputbuilder.go
index e9562559..455a473e 100644
--- a/client/device/cloudfmc/fmcappliance/update_outputbuilder.go
+++ b/client/device/cloudfmc/fmcappliance/update_outputbuilder.go
@@ -44,16 +44,11 @@ func (b *updateRequestBodyBuilder) QueueTriggerState(queueTriggerState string) *
 	return b
 }
 
-func (b *updateRequestBodyBuilder) StateMachineContext(stateMachineContext *map[string]string) *updateRequestBodyBuilder {
+func (b *updateRequestBodyBuilder) StateMachineContext(stateMachineContext map[string]string) *updateRequestBodyBuilder {
 	b.updateRequestBody.StateMachineContext = stateMachineContext
 	return b
 }
 
-func (b *updateRequestBodyBuilder) Uid(uid string) *updateRequestBodyBuilder {
-	b.updateRequestBody.Uid = uid
-	return b
-}
-
 func (b *updateRequestBodyBuilder) Build() updateRequestBody {
 	return *b.updateRequestBody
 }
diff --git a/client/device/cloudfmc/fmcappliance/update_test.go b/client/device/cloudfmc/fmcappliance/update_test.go
index 852e6123..cb7273e0 100644
--- a/client/device/cloudfmc/fmcappliance/update_test.go
+++ b/client/device/cloudfmc/fmcappliance/update_test.go
@@ -31,7 +31,7 @@ func TestUpdate(t *testing.T) {
 	}{
 		{
 			testName: "successfully updates FMC Appliance name",
-			input:    fmcappliance.NewUpdateInput(fmcApplianceUid, queueTriggerState, &stateMachineContext),
+			input:    fmcappliance.NewUpdateInput(fmcApplianceUid, queueTriggerState, stateMachineContext),
 
 			setupFunc: func() {
 				httpmock.RegisterResponder(
@@ -50,7 +50,7 @@ func TestUpdate(t *testing.T) {
 
 		{
 			testName: "error when update FMC Appliance name error",
-			input:    fmcappliance.NewUpdateInput(fmcApplianceUid, queueTriggerState, &stateMachineContext),
+			input:    fmcappliance.NewUpdateInput(fmcApplianceUid, queueTriggerState, stateMachineContext),
 
 			setupFunc: func() {
 				httpmock.RegisterResponder(
diff --git a/client/device/cloudfmc/fmcplatform/read_devicelicenses.go b/client/device/cloudfmc/fmcplatform/read_devicelicenses.go
deleted file mode 100644
index 3a3d13ee..00000000
--- a/client/device/cloudfmc/fmcplatform/read_devicelicenses.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package fmcplatform
-
-import (
-	"context"
-	"fmt"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/cloudfmc/devicelicense"
-)
-
-type ReadDeviceLicensesInput struct {
-	FmcHost string
-}
-
-func NewReadDeviceLicensesInput(fmcHost string) ReadDeviceLicensesInput {
-	return ReadDeviceLicensesInput{
-		FmcHost: fmcHost,
-	}
-}
-
-type ReadDeviceLicensesOutput = devicelicense.Item
-
-var NewReadDeviceLicensesOutputBuilder = devicelicense.NewItemBuilder
-
-func ReadDeviceLicenses(ctx context.Context, client http.Client, readInp ReadDeviceLicensesInput) (*ReadDeviceLicensesOutput, error) {
-
-	client.Logger.Println("reading FMC device licenses")
-
-	readUrl := url.ReadFmcDeviceLicenses(client.BaseUrl())
-	req := client.NewGet(ctx, readUrl)
-	req.Header.Set("Fmc-Hostname", readInp.FmcHost)
-
-	var outp devicelicense.DeviceLicense
-	if err := req.Send(&outp); err != nil {
-		return nil, err
-	}
-
-	if len(outp.Items) != 1 {
-		return nil, fmt.Errorf("failed to get device licenses")
-	}
-
-	return &outp.Items[0], nil
-}
diff --git a/client/device/cloudfmc/fmcplatform/read_devicelicenses_inputbuilder.go b/client/device/cloudfmc/fmcplatform/read_devicelicenses_inputbuilder.go
deleted file mode 100644
index 955fa24d..00000000
--- a/client/device/cloudfmc/fmcplatform/read_devicelicenses_inputbuilder.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package fmcplatform
-
-type ReadDeviceLicensesInputBuilder struct {
-	readDeviceLicensesInput *ReadDeviceLicensesInput
-}
-
-func NewReadDeviceLicensesInputBuilder() *ReadDeviceLicensesInputBuilder {
-	readDeviceLicensesInput := &ReadDeviceLicensesInput{}
-	b := &ReadDeviceLicensesInputBuilder{readDeviceLicensesInput: readDeviceLicensesInput}
-	return b
-}
-
-func (b *ReadDeviceLicensesInputBuilder) FmcHost(fmcHost string) *ReadDeviceLicensesInputBuilder {
-	b.readDeviceLicensesInput.FmcHost = fmcHost
-	return b
-}
-
-func (b *ReadDeviceLicensesInputBuilder) Build() ReadDeviceLicensesInput {
-	return *b.readDeviceLicensesInput
-}
diff --git a/client/device/cloudfmc/fmcplatform/read_domaininfo.go b/client/device/cloudfmc/fmcplatform/readdomaininfo.go
similarity index 100%
rename from client/device/cloudfmc/fmcplatform/read_domaininfo.go
rename to client/device/cloudfmc/fmcplatform/readdomaininfo.go
diff --git a/client/device/cloudfmc/fmcplatform/read_domaininfo_test.go b/client/device/cloudfmc/fmcplatform/readdomaininfo_test.go
similarity index 100%
rename from client/device/cloudfmc/fmcplatform/read_domaininfo_test.go
rename to client/device/cloudfmc/fmcplatform/readdomaininfo_test.go
diff --git a/client/device/cloudfmc/fmcplatform/update_devicelicenses.go b/client/device/cloudfmc/fmcplatform/update_devicelicenses.go
deleted file mode 100644
index f6e75cad..00000000
--- a/client/device/cloudfmc/fmcplatform/update_devicelicenses.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package fmcplatform
-
-import (
-	"context"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/cloudfmc/devicelicense"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-)
-
-type UpdateDeviceLicensesInput struct {
-	FmcHost      string
-	LicenseTypes []license.Type
-}
-
-type UpdateDeviceLicensesOutput = devicelicense.Item
-
-var NewUpdateDeviceLicensesOutputBuilder = devicelicense.NewItemBuilder
-
-type updateRequestBody struct {
-	Type         string         `json:"type"`
-	Id           string         `json:"id"`
-	LicenseTypes []license.Type `json:"licenseTypes"` // must be FMC license types
-}
-
-func UpdateDeviceLicenses(ctx context.Context, client http.Client, updateInp UpdateDeviceLicensesInput) (*UpdateDeviceLicensesOutput, error) {
-
-	client.Logger.Println("updating FMC device licenses")
-
-	readOutput, err := ReadDeviceLicenses(ctx, client, NewReadDeviceLicensesInputBuilder().FmcHost(updateInp.FmcHost).Build())
-	if err != nil {
-		return nil, err
-	}
-
-	updateUrl := url.UpdateFmcDeviceLicenses(client.BaseUrl(), readOutput.Id)
-	updateBody := updateRequestBody{
-		Type:         "DeviceLicense",
-		Id:           readOutput.Id,
-		LicenseTypes: license.LicensesToFmcLicenses(updateInp.LicenseTypes),
-	}
-	req := client.NewPut(ctx, updateUrl, updateBody)
-	req.Header.Set("Fmc-Hostname", updateInp.FmcHost)
-
-	var outp UpdateDeviceLicensesOutput
-	if err := req.Send(&outp); err != nil {
-		return nil, err
-	}
-
-	return &outp, nil
-}
diff --git a/client/device/cloudfmc/fmcplatform/update_devicelicenses_inputbuilder.go b/client/device/cloudfmc/fmcplatform/update_devicelicenses_inputbuilder.go
deleted file mode 100644
index a818c496..00000000
--- a/client/device/cloudfmc/fmcplatform/update_devicelicenses_inputbuilder.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package fmcplatform
-
-import "github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-
-type UpdateDeviceLicensesInputBuilder struct {
-	updateDeviceLicensesInput *UpdateDeviceLicensesInput
-}
-
-func NewUpdateDeviceLicensesInputBuilder() *UpdateDeviceLicensesInputBuilder {
-	updateDeviceLicensesInput := &UpdateDeviceLicensesInput{}
-	b := &UpdateDeviceLicensesInputBuilder{updateDeviceLicensesInput: updateDeviceLicensesInput}
-	return b
-}
-
-func (b *UpdateDeviceLicensesInputBuilder) FmcHost(fmcHost string) *UpdateDeviceLicensesInputBuilder {
-	b.updateDeviceLicensesInput.FmcHost = fmcHost
-	return b
-}
-
-func (b *UpdateDeviceLicensesInputBuilder) LicenseTypes(licenseTypes []license.Type) *UpdateDeviceLicensesInputBuilder {
-	b.updateDeviceLicensesInput.LicenseTypes = licenseTypes
-	return b
-}
-
-func (b *UpdateDeviceLicensesInputBuilder) Build() UpdateDeviceLicensesInput {
-	return *b.updateDeviceLicensesInput
-}
diff --git a/client/device/cloudfmc/read.go b/client/device/cloudfmc/read.go
index b00bdfb6..97cf7bc8 100644
--- a/client/device/cloudfmc/read.go
+++ b/client/device/cloudfmc/read.go
@@ -19,8 +19,6 @@ func NewReadInput() ReadInput {
 
 type ReadOutput = device.ReadOutput
 
-var NewReadOutputBuilder = device.NewReadOutputBuilder
-
 func Read(ctx context.Context, client http.Client, readInp ReadInput) (*ReadOutput, error) {
 
 	client.Logger.Println("reading cloud FMC")
diff --git a/client/device/cloudfmc/readspecific.go b/client/device/cloudfmc/readspecific.go
index 55f379e1..1f6a26dc 100644
--- a/client/device/cloudfmc/readspecific.go
+++ b/client/device/cloudfmc/readspecific.go
@@ -4,7 +4,6 @@ import (
 	"context"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/statemachine"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/statemachine/state"
 )
 
@@ -13,11 +12,10 @@ type ReadSpecificInput struct {
 }
 
 type ReadSpecificOutput struct {
-	SpecificUid         string               `json:"uid"`
-	DomainUid           string               `json:"domainUid"`
-	State               state.Type           `json:"state"`
-	Status              string               `json:"status"`
-	StateMachineDetails statemachine.Details `json:"stateMachineDetails"`
+	SpecificUid string     `json:"uid"`
+	DomainUid   string     `json:"domainUid"`
+	State       state.Type `json:"state"`
+	Status      string     `json:"status"`
 }
 
 func NewReadSpecificInput(fmcId string) ReadSpecificInput {
@@ -28,8 +26,6 @@ func NewReadSpecificInput(fmcId string) ReadSpecificInput {
 
 func ReadSpecific(ctx context.Context, client http.Client, inp ReadSpecificInput) (*ReadSpecificOutput, error) {
 
-	client.Logger.Println("reading Cloud FMC specific")
-
 	req := device.NewReadSpecificRequest(ctx, client, *device.NewReadSpecificInput(inp.FmcId))
 
 	var readSpecificOutp ReadSpecificOutput
diff --git a/client/device/cloudfmc/retry.go b/client/device/cloudfmc/retry.go
deleted file mode 100644
index 644e281f..00000000
--- a/client/device/cloudfmc/retry.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package cloudfmc
-
-import (
-	"context"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/retry"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/statemachine"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/statemachine/state"
-)
-
-func UntilStateDone(ctx context.Context, client http.Client, uid string) retry.Func {
-	return func() (bool, error) {
-		fmcReadSpecificRes, err := ReadSpecific(ctx, client, NewReadSpecificInput(uid))
-		if err != nil {
-			return false, err
-		}
-		client.Logger.Printf("fmcReadSpecificRes.State=%s\n", fmcReadSpecificRes.State)
-		if fmcReadSpecificRes.State == state.DONE {
-			return true, nil
-		} else if fmcReadSpecificRes.State == state.ERROR {
-			return false, statemachine.NewWorkflowErrorFromDetails(fmcReadSpecificRes.StateMachineDetails)
-		}
-		return false, nil
-	}
-}
diff --git a/client/device/cloudftd/cloudftdonboarding/create.go b/client/device/cloudftd/cloudftdonboarding/create.go
index 84fd4625..c2979c3d 100644
--- a/client/device/cloudftd/cloudftdonboarding/create.go
+++ b/client/device/cloudftd/cloudftdonboarding/create.go
@@ -104,7 +104,7 @@ func Create(ctx context.Context, client http.Client, createInp CreateInput) (*Cr
 
 	// 3.1 read ftd metadata
 	// 3.1.5 handle license
-	licenseCaps, err := license.StringToCdoLicenses(readFtdOutp.Metadata.LicenseCaps)
+	licenseCaps, err := license.DeserializeAllFromCdo(readFtdOutp.Metadata.LicenseCaps)
 	if err != nil {
 		return nil, err
 	}
diff --git a/client/device/cloudftd/create.go b/client/device/cloudftd/create.go
index da744220..ed6d11e4 100644
--- a/client/device/cloudftd/create.go
+++ b/client/device/cloudftd/create.go
@@ -119,7 +119,7 @@ func Create(ctx context.Context, client http.Client, createInp CreateInput) (*Cr
 		Metadata: &Metadata{
 			AccessPolicyName: selectedPolicy.Name,
 			AccessPolicyUid:  selectedPolicy.Id,
-			LicenseCaps:      license.LicensesToString(*createInp.Licenses),
+			LicenseCaps:      license.SerializeAllAsCdo(*createInp.Licenses),
 			PerformanceTier:  performanceTier,
 		},
 		State: "NEW",
diff --git a/client/device/cloudftd/create_metadatabuilder.go b/client/device/cloudftd/create_metadatabuilder.go
index 4e03be0a..945baefa 100644
--- a/client/device/cloudftd/create_metadatabuilder.go
+++ b/client/device/cloudftd/create_metadatabuilder.go
@@ -36,7 +36,7 @@ func (b *MetadataBuilder) GeneratedCommand(generatedCommand string) *MetadataBui
 }
 
 func (b *MetadataBuilder) LicenseCaps(licenseCaps *[]license.Type) *MetadataBuilder {
-	b.metadata.LicenseCaps = license.LicensesToString(*licenseCaps)
+	b.metadata.LicenseCaps = license.SerializeAllAsCdo(*licenseCaps)
 	return b
 }
 
diff --git a/client/device/cloudftd/delete.go b/client/device/cloudftd/delete.go
index 9ea5e0b5..5176cf71 100644
--- a/client/device/cloudftd/delete.go
+++ b/client/device/cloudftd/delete.go
@@ -43,7 +43,7 @@ func Delete(ctx context.Context, client http.Client, deleteInp DeleteInput) (*De
 		fmcappliance.NewUpdateInputBuilder().
 			FmcApplianceUid(fmcReadSpecificRes.SpecificUid).
 			QueueTriggerState("PENDING_DELETE_FTDC").
-			StateMachineContext(&map[string]string{"ftdCDeviceIDs": deleteInp.Uid}).
+			StateMachineContext(map[string]string{"ftdCDeviceIDs": deleteInp.Uid}).
 			Build(),
 	)
 	if err != nil {
diff --git a/client/device/cloudftd/update.go b/client/device/cloudftd/update.go
index ca0364c9..51d3f93f 100644
--- a/client/device/cloudftd/update.go
+++ b/client/device/cloudftd/update.go
@@ -2,30 +2,22 @@ package cloudftd
 
 import (
 	"context"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudfmc"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudfmc/fmcappliance"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudfmc/fmcplatform"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/retry"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/device/tags"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-	"time"
 )
 
 type UpdateInput struct {
-	Uid      string
-	Name     string
-	Tags     tags.Type
-	Licenses []license.Type
+	Uid  string
+	Name string
+	Tags tags.Type
 }
 
-func NewUpdateInput(uid, name string, tags tags.Type, licenses []license.Type) UpdateInput {
+func NewUpdateInput(uid, name string, tags tags.Type) UpdateInput {
 	return UpdateInput{
-		Uid:      uid,
-		Name:     name,
-		Tags:     tags,
-		Licenses: licenses,
+		Uid:  uid,
+		Name: name,
+		Tags: tags,
 	}
 }
 
@@ -36,15 +28,8 @@ type updateRequestBody struct {
 
 type UpdateOutput = ReadOutput
 
-var NewUpdateOutputBuilder = NewReadOutputBuilder
-
 func Update(ctx context.Context, client http.Client, updateInp UpdateInput) (*UpdateOutput, error) {
 
-	client.Logger.Println("updating FTD")
-
-	client.Logger.Println("updating CDO settings")
-
-	// update CDO settings
 	updateUrl := url.UpdateDevice(client.BaseUrl(), updateInp.Uid)
 	updateBody := updateRequestBody{
 		Name: updateInp.Name,
@@ -56,78 +41,6 @@ func Update(ctx context.Context, client http.Client, updateInp UpdateInput) (*Up
 		return nil, err
 	}
 
-	// read FMC host
-	client.Logger.Println("reading FMC host")
-	fmcRes, err := cloudfmc.Read(ctx, client, cloudfmc.NewReadInput())
-	if err != nil {
-		return nil, err
-	}
-
-	// update FTD license through FMC api
-	client.Logger.Println("updating FTD licenses")
-	_, err = fmcplatform.UpdateDeviceLicenses(
-		ctx,
-		client,
-		fmcplatform.NewUpdateDeviceLicensesInputBuilder().
-			FmcHost(fmcRes.Host).
-			LicenseTypes(updateInp.Licenses).
-			Build(),
-	)
-	if err != nil {
-		return nil, err
-	}
-
-	// trigger oob detection in cdo to sync license changes
-
-	// read FMC that manages this cloud FTD for its uid, so that we can get its specific uid later
-	fmcReadRes, err := cloudfmc.Read(ctx, client, cloudfmc.NewReadInput())
-	if err != nil {
-		return nil, err
-	}
-
-	// read FMC specific device, i.e. the actual FMC for its device uid
-	fmcReadSpecificRes, err := cloudfmc.ReadSpecific(ctx, client, cloudfmc.NewReadSpecificInput(fmcReadRes.Uid))
-	if err != nil {
-		return nil, err
-	}
-
-	// trigger oob detection
-	_, err = fmcappliance.Update(
-		ctx,
-		client,
-		fmcappliance.NewUpdateInputBuilder().
-			FmcApplianceUid(fmcReadSpecificRes.SpecificUid).
-			QueueTriggerState("PENDING_OOB_DETECTION").
-			Build(),
-	)
-	if err != nil {
-		return nil, err
-	}
-
-	// waiting for oob to be done
-	err = retry.Do(
-		ctx,
-		cloudfmc.UntilStateDone(ctx, client, fmcReadRes.Uid),
-		retry.NewOptionsBuilder().
-			Message("Waiting for FTD to be updated...").
-			Retries(-1).
-			Timeout(5*time.Minute).
-			Logger(client.Logger).
-			EarlyExitOnError(true).
-			Delay(3*time.Second).
-			Build(),
-	)
-	if err != nil {
-		return nil, err
-	}
-
-	client.Logger.Println("re-reading FTD for latest info")
-
-	// re-read the FTD for new license change
-	ftdReadRes, err := ReadByUid(ctx, client, NewReadByUidInput(updateInp.Uid))
-	if err != nil {
-		return nil, err
-	}
+	return &updateOutp, nil
 
-	return ftdReadRes, nil
 }
diff --git a/client/device/cloudftd/update_inputbuilder.go b/client/device/cloudftd/update_inputbuilder.go
deleted file mode 100644
index dd8e057b..00000000
--- a/client/device/cloudftd/update_inputbuilder.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package cloudftd
-
-import (
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/device/tags"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-)
-
-type UpdateInputBuilder struct {
-	updateInput *UpdateInput
-}
-
-func NewUpdateInputBuilder() *UpdateInputBuilder {
-	updateInput := &UpdateInput{}
-	b := &UpdateInputBuilder{updateInput: updateInput}
-	return b
-}
-
-func (b *UpdateInputBuilder) Uid(uid string) *UpdateInputBuilder {
-	b.updateInput.Uid = uid
-	return b
-}
-
-func (b *UpdateInputBuilder) Name(name string) *UpdateInputBuilder {
-	b.updateInput.Name = name
-	return b
-}
-
-func (b *UpdateInputBuilder) Tags(tags tags.Type) *UpdateInputBuilder {
-	b.updateInput.Tags = tags
-	return b
-}
-
-func (b *UpdateInputBuilder) Licenses(licenses []license.Type) *UpdateInputBuilder {
-	b.updateInput.Licenses = licenses
-	return b
-}
-
-func (b *UpdateInputBuilder) Build() UpdateInput {
-	return *b.updateInput
-}
diff --git a/client/device/cloudftd/update_test.go b/client/device/cloudftd/update_test.go
deleted file mode 100644
index 6b9f4d10..00000000
--- a/client/device/cloudftd/update_test.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package cloudftd_test
-
-import (
-	"context"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudfmc"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudfmc/fmcplatform"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudftd"
-	internalHttp "github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/http"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/cloudfmc/devicelicense"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/device/tags"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/statemachine/state"
-	"github.com/jarcoal/httpmock"
-	"github.com/stretchr/testify/assert"
-	"net/http"
-	"testing"
-	"time"
-)
-
-func TestUpdateCloudFtd(t *testing.T) {
-	httpmock.Activate()
-	defer httpmock.DeactivateAndReset()
-
-	testHost := "test-host"
-	var testPort uint = 443
-
-	testCloudFtdInput := cloudftd.NewUpdateInputBuilder().
-		Uid("test-uid").
-		Licenses([]license.Type{license.Essentials}).
-		Name("test-name").
-		Tags(tags.Type{Labels: []string{"test-tag"}}).
-		Build()
-
-	testMetadata := cloudftd.NewMetadataBuilder().
-		LicenseCaps(&[]license.Type{}).
-		Build()
-
-	successFmcSpecificOutput := cloudfmc.NewReadSpecificOutputBuilder().
-		SpecificUid("test-specific-uid").
-		State(state.DONE).
-		Build()
-
-	successCloudFtdOutput := cloudftd.NewUpdateOutputBuilder().
-		Uid(testCloudFtdInput.Uid).
-		Metadata(testMetadata).
-		Name(testCloudFtdInput.Name).
-		Build()
-
-	successCloudFmcOutput := cloudfmc.NewReadOutputBuilder().
-		WithUid(successFmcSpecificOutput.SpecificUid).
-		WithLocation(testHost, testPort).
-		Build()
-
-	successReadDeviceLicenseOutput := fmcplatform.NewReadDeviceLicensesOutputBuilder().
-		Id("test-license-id").
-		Build()
-
-	successUpdateDeviceLicenseOutput := fmcplatform.NewUpdateDeviceLicensesOutputBuilder().
-		Id("test-license-id").
-		Build()
-
-	successFmcApplianceOutput := cloudftd.NewUpdateOutputBuilder().
-		Uid(successFmcSpecificOutput.SpecificUid).
-		Build()
-
-	testCases := []struct {
-		testName   string
-		input      cloudftd.UpdateInput
-		setupFunc  func()
-		assertFunc func(output *cloudftd.UpdateOutput, err error, t *testing.T)
-	}{
-		{
-			testName: "successfully update Cloud FTD",
-			input:    testCloudFtdInput,
-			setupFunc: func() {
-				updateCdoFtdSettings(baseUrl, successCloudFtdOutput)
-				readCloudFmc(baseUrl, successCloudFmcOutput)
-				readFtdDeviceLicense(baseUrl, successReadDeviceLicenseOutput)
-				updateFtdDeviceLicense(baseUrl, successUpdateDeviceLicenseOutput)
-				readCloudFmcSpecific(baseUrl, successFmcSpecificOutput)
-				updateCloudFmcAppliance(baseUrl, successFmcApplianceOutput)
-				readFtd(baseUrl, successCloudFtdOutput)
-			},
-			assertFunc: func(output *cloudftd.UpdateOutput, err error, t *testing.T) {
-				assert.Nil(t, err)
-				assert.NotNil(t, output)
-				assert.Equal(t, successCloudFtdOutput, *output)
-			},
-		},
-	}
-
-	for _, testCase := range testCases {
-		t.Run(testCase.testName, func(t *testing.T) {
-			httpmock.Reset()
-
-			testCase.setupFunc()
-
-			output, err := cloudftd.Update(
-				context.Background(),
-				*internalHttp.MustNewWithConfig(baseUrl, "a_valid_token", 0, 0, time.Minute),
-				testCase.input,
-			)
-
-			testCase.assertFunc(output, err, t)
-		})
-	}
-}
-
-func updateCdoFtdSettings(baseUrl string, output cloudftd.UpdateOutput) {
-	httpmock.RegisterResponder(
-		http.MethodPut,
-		url.UpdateDevice(baseUrl, output.Uid),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, output),
-	)
-}
-
-func readCloudFmc(baseUrl string, output cloudfmc.ReadOutput) {
-	httpmock.RegisterResponder(
-		http.MethodGet,
-		url.ReadAllDevicesByType(baseUrl),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, []cloudfmc.ReadOutput{output}),
-	)
-}
-
-func readCloudFmcSpecific(baseUrl string, output cloudfmc.ReadSpecificOutput) {
-	httpmock.RegisterResponder(
-		http.MethodGet,
-		url.ReadSpecificDevice(baseUrl, output.SpecificUid),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, output),
-	)
-}
-
-func updateCloudFmcAppliance(baseUrl string, output cloudftd.UpdateOutput) {
-	httpmock.RegisterResponder(
-		http.MethodPut,
-		url.UpdateFmcAppliance(baseUrl, output.Uid),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, output),
-	)
-}
-
-func readFtdDeviceLicense(baseUrl string, readOutput fmcplatform.ReadDeviceLicensesOutput) {
-	httpmock.RegisterResponder(
-		http.MethodGet,
-		url.ReadFmcDeviceLicenses(baseUrl),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, devicelicense.DeviceLicense{Items: []fmcplatform.ReadDeviceLicensesOutput{readOutput}}),
-	)
-}
-
-func updateFtdDeviceLicense(baseUrl string, updateOutput fmcplatform.UpdateDeviceLicensesOutput) {
-	httpmock.RegisterResponder(
-		http.MethodPut,
-		url.UpdateFmcDeviceLicenses(baseUrl, updateOutput.Id),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, updateOutput),
-	)
-}
-
-func readFtd(baseUrl string, output cloudftd.ReadOutput) {
-	httpmock.RegisterResponder(
-		http.MethodGet,
-		url.ReadDevice(baseUrl, output.Uid),
-		httpmock.NewJsonResponderOrPanic(http.StatusOK, output),
-	)
-}
diff --git a/client/internal/goutil/goutil.go b/client/internal/goutil/goutil.go
index ec9f7697..845f19e6 100644
--- a/client/internal/goutil/goutil.go
+++ b/client/internal/goutil/goutil.go
@@ -1,9 +1,6 @@
 package goutil
 
-import (
-	"golang.org/x/exp/constraints"
-	"sort"
-)
+import "golang.org/x/exp/constraints"
 
 // AsPointer convert interface{} to *interface{}, if input is not nil
 func AsPointer(obj interface{}) *interface{} {
@@ -36,11 +33,3 @@ func Max[T constraints.Ordered](a, b T) T {
 	}
 	return b
 }
-
-// SortStrings return a sorted copy of the input string array.
-func SortStrings(inp []string) []string {
-	temp := make([]string, len(inp))
-	copy(temp, inp)
-	sort.Strings(temp)
-	return temp
-}
diff --git a/client/internal/url/url.go b/client/internal/url/url.go
index 235815de..df39d298 100644
--- a/client/internal/url/url.go
+++ b/client/internal/url/url.go
@@ -98,14 +98,6 @@ func ReadFmcDomainInfo(fmcHost string) string {
 	return fmt.Sprintf("https://%s/api/fmc_platform/v1/info/domain", fmcHost)
 }
 
-func ReadFmcDeviceLicenses(baseUrl string) string {
-	return fmt.Sprintf("%s/fmc/api/fmc_platform/v1/license/devicelicenses", baseUrl)
-}
-
-func UpdateFmcDeviceLicenses(baseUrl string, objectId string) string {
-	return fmt.Sprintf("%s/fmc/api/fmc_platform/v1/license/devicelicenses/%s", baseUrl, objectId)
-}
-
 func CreateUser(baseUrl string, username string) string {
 	return fmt.Sprintf("%s/anubis/rest/v1/users/%s", baseUrl, username)
 }
diff --git a/client/model/cloudfmc/devicelicense/devicelicense.go b/client/model/cloudfmc/devicelicense/devicelicense.go
deleted file mode 100644
index 5e99e6d0..00000000
--- a/client/model/cloudfmc/devicelicense/devicelicense.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package devicelicense
-
-import (
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/cloudfmc/internal"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/tier"
-)
-
-type DeviceLicense struct {
-	Links  Links  `json:"links"`
-	Paging Paging `json:"paging"`
-	Items  []Item `json:"items"`
-}
-
-func NewDeviceLicense(links Links, paging Paging, items []Item) DeviceLicense {
-	return DeviceLicense{
-		Links:  links,
-		Paging: paging,
-		Items:  items,
-	}
-}
-
-type Item struct {
-	Id              string         `json:"id"`
-	Type            string         `json:"type"`
-	LicenseTypes    []license.Type `json:"licenseTypes"`
-	PerformanceTier tier.Type      `json:"performanceTier"`
-	Links           Links          `json:"links"`
-}
-
-func NewItem(id, type_ string, licenseTypes []license.Type, performanceTier tier.Type, links Links) Item {
-	return Item{
-		Type:            type_,
-		Id:              id,
-		LicenseTypes:    licenseTypes,
-		PerformanceTier: performanceTier,
-		Links:           links,
-	}
-}
-
-type Links = internal.Links
-type Paging = internal.Paging
-
-var NewLinks = internal.NewLinks
-var NewPaging = internal.NewPaging
diff --git a/client/model/cloudfmc/devicelicense/item_builder.go b/client/model/cloudfmc/devicelicense/item_builder.go
deleted file mode 100644
index d07de7b6..00000000
--- a/client/model/cloudfmc/devicelicense/item_builder.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package devicelicense
-
-import (
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/tier"
-)
-
-type ItemBuilder struct {
-	item *Item
-}
-
-func NewItemBuilder() *ItemBuilder {
-	item := &Item{}
-	b := &ItemBuilder{item: item}
-	return b
-}
-
-func (b *ItemBuilder) Id(id string) *ItemBuilder {
-	b.item.Id = id
-	return b
-}
-
-func (b *ItemBuilder) Type(type_ string) *ItemBuilder {
-	b.item.Type = type_
-	return b
-}
-
-func (b *ItemBuilder) LicenseTypes(licenseTypes []license.Type) *ItemBuilder {
-	b.item.LicenseTypes = licenseTypes
-	return b
-}
-
-func (b *ItemBuilder) PerformanceTier(performanceTier tier.Type) *ItemBuilder {
-	b.item.PerformanceTier = performanceTier
-	return b
-}
-
-func (b *ItemBuilder) Links(links Links) *ItemBuilder {
-	b.item.Links = links
-	return b
-}
-
-func (b *ItemBuilder) Build() Item {
-	return *b.item
-}
diff --git a/client/model/ftd/license/license.go b/client/model/ftd/license/license.go
index faacd71c..da0b2ce2 100644
--- a/client/model/ftd/license/license.go
+++ b/client/model/ftd/license/license.go
@@ -12,18 +12,15 @@ type Type string
 
 // https://www.cisco.com/c/en/us/td/docs/security/firepower/70/fdm/fptd-fdm-config-guide-700/fptd-fdm-license.html
 const (
-	// CDO terms
-	Base      Type = "BASE"
-	Carrier   Type = "CARRIER"
-	Threat    Type = "THREAT"
-	Malware   Type = "MALWARE"
-	URLFilter Type = "URLFilter"
-
-	// FMC terms
+	Base           Type = "BASE"
 	Essentials     Type = "ESSENTIALS"
-	URL            Type = "URL"
+	Carrier        Type = "CARRIER"
+	Threat         Type = "THREAT"
 	IPS            Type = "IPS"
+	Malware        Type = "MALWARE"
 	MalwareDefense Type = "MALWARE_DEFENSE"
+	URLFilter      Type = "URLFilter"
+	URL            Type = "URL"
 )
 
 var All = []Type{
@@ -38,20 +35,6 @@ var All = []Type{
 	URL,
 }
 
-var fmcToCdoLicenseNameMap = map[Type]Type{
-	Essentials:     Base,
-	IPS:            Threat,
-	URL:            URLFilter,
-	MalwareDefense: Malware,
-}
-
-var cdoToFmcLicenseNameMap = map[Type]Type{
-	Base:      Essentials,
-	Threat:    IPS,
-	URLFilter: URL,
-	Malware:   MalwareDefense,
-}
-
 var AllAsString = make([]string, len(All))
 
 var nameToTypeMap = make(map[string]Type, len(All))
@@ -71,7 +54,7 @@ func (t *Type) UnmarshalJSON(b []byte) error {
 	if len(b) <= 2 || b == nil {
 		return fmt.Errorf("cannot unmarshal empty tring as a license type, it should be one of valid roles: %+v", AllAsString)
 	}
-	deserialized, err := stringToLicense(string(b[1 : len(b)-1])) // strip off quote
+	deserialized, err := Deserialize(string(b[1 : len(b)-1])) // strip off quote
 	if err != nil {
 		return err
 	}
@@ -79,27 +62,35 @@ func (t *Type) UnmarshalJSON(b []byte) error {
 	return nil
 }
 
-// replaceFmcLicenseTermsWithCdoTerms is used to tell terraform how the licenses returned by FMC map to licenses expected by CDO
+// ReplaceFmcLicenseTermsWithCdoTerms is used to tell terraform how the licenses returned by FMC map to licenses expected by CDO
 // We need to tell Terraform during read that they are the same thing, so when reading it back, we need the conversion
-func replaceFmcTermWithCdoTerm(fmcLicense Type) Type {
-	cdoLicense, ok := fmcToCdoLicenseNameMap[fmcLicense]
-	if ok {
-		return cdoLicense
-	} else {
-		return fmcLicense
+func ReplaceFmcLicenseTermsWithCdoTerms(licenses []string) []string {
+	for i, l := range licenses {
+		if l == string(Essentials) {
+			licenses[i] = string(Base)
+		}
+		if l == string(IPS) {
+			licenses[i] = string(Threat)
+		}
+		if l == string(URL) {
+			licenses[i] = string(URLFilter)
+		}
+		if l == string(MalwareDefense) {
+			licenses[i] = string(Malware)
+		}
 	}
+	return licenses
 }
 
-func replaceCdoTermWithFmcTerm(cdoLicense Type) Type {
-	fmcLicense, ok := cdoToFmcLicenseNameMap[cdoLicense]
-	if ok {
-		return fmcLicense
-	} else {
-		return cdoLicense
+func MustParse(name string) Type {
+	l, ok := nameToTypeMap[name]
+	if !ok {
+		panic(fmt.Errorf("FTD License of name: \"%s\" not found, should be one of %+v", name, AllAsString))
 	}
+	return l
 }
 
-func stringToLicense(name string) (Type, error) {
+func Deserialize(name string) (Type, error) {
 	l, ok := nameToTypeMap[name]
 	if !ok {
 		return "", fmt.Errorf("FTD License of name: \"%s\" not found, should be one of: %+v", name, AllAsString)
@@ -107,39 +98,18 @@ func stringToLicense(name string) (Type, error) {
 	return l, nil
 }
 
-func LicensesToString(licenses []Type) string {
-	return strings.Join(LicensesToStrings(licenses), ",")
-}
-
-func LicensesToStrings(licenses []Type) []string {
-	return sliceutil.Map(licenses, func(l Type) string { return string(l) })
+func SerializeAllAsCdo(licenses []Type) string {
+	return strings.Join(sliceutil.Map(licenses, func(l Type) string { return string(l) }), ",")
 }
 
-// StringToCdoLicenses exists because CDO store license caps as one comma-sep string
-// but fmc store it as list of string, and they have different name for some licenses,
-// use this method to handle this special case by converting FMC representation to
-// CDO representation
-func StringToCdoLicenses(licenses string) ([]Type, error) {
+// DeserializeAllFromCdo exists because CDO store license caps as one comma-sep string
+// but fmc store it as list of string, use this method to handle CDO's special case
+func DeserializeAllFromCdo(licenses string) ([]Type, error) {
 	return sliceutil.MapWithError(strings.Split(licenses, ","), func(l string) (Type, error) {
 		t, ok := nameToTypeMap[l]
 		if !ok {
 			return "", fmt.Errorf("cannot deserialize %s as license, should be one of %+v", l, All)
 		}
-		t = replaceFmcTermWithCdoTerm(t)
 		return t, nil
 	})
 }
-
-func LicensesToFmcLicenses(licenses []Type) []Type {
-	return sliceutil.Map(licenses, func(l Type) Type {
-		return replaceCdoTermWithFmcTerm(l)
-	})
-}
-
-func StringToCdoStrings(licenses string) ([]string, error) {
-	licenseTypes, err := StringToCdoLicenses(licenses)
-	if err != nil {
-		return nil, err
-	}
-	return LicensesToStrings(licenseTypes), nil
-}
diff --git a/provider/examples/resources/ftd/cdo_ftd.tf b/provider/examples/resources/ftd/cdo_ftd.tf
index 70e9edba..192f2658 100644
--- a/provider/examples/resources/ftd/cdo_ftd.tf
+++ b/provider/examples/resources/ftd/cdo_ftd.tf
@@ -1,7 +1,7 @@
 terraform {
   required_providers {
     cdo = {
-      source = "CiscoDevnet/cdo"
+      source = "hashicorp.com/CiscoDevnet/cdo"
     }
     aws = {
       source  = "hashicorp/aws"
diff --git a/provider/internal/device/ftd/operation.go b/provider/internal/device/ftd/operation.go
index 7abdd6c7..455a2803 100644
--- a/provider/internal/device/ftd/operation.go
+++ b/provider/internal/device/ftd/operation.go
@@ -2,10 +2,10 @@ package ftd
 
 import (
 	"context"
-	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
 	"strings"
 
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/device/cloudftd"
+	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/license"
 	"github.com/CiscoDevnet/terraform-provider-cdo/go-client/model/ftd/tier"
 	"github.com/CiscoDevnet/terraform-provider-cdo/internal/util"
 	"github.com/hashicorp/terraform-plugin-framework/types"
@@ -45,19 +45,13 @@ func Read(ctx context.Context, resource *Resource, stateData *ResourceModel) err
 		return err
 	}
 
-	// handle licenses
-	licenseStrings, err := license.StringToCdoStrings(res.Metadata.LicenseCaps)
-	if err != nil {
-		return err
-	}
-
 	// map return struct to model
 	stateData.ID = types.StringValue(res.Uid)
 	stateData.Name = types.StringValue(res.Name)
 	stateData.AccessPolicyName = types.StringValue(res.Metadata.AccessPolicyName)
 	stateData.AccessPolicyUid = types.StringValue(res.Metadata.AccessPolicyUid)
 	stateData.Virtual = types.BoolValue(res.Metadata.PerformanceTier != nil)
-	stateData.Licenses = util.GoStringSliceToTFStringSet(licenseStrings)
+	stateData.Licenses = util.GoStringSliceToTFStringSet(license.ReplaceFmcLicenseTermsWithCdoTerms(strings.Split(res.Metadata.LicenseCaps, ",")))
 	if res.Metadata.PerformanceTier != nil { // nil means physical cloudftd
 		stateData.PerformanceTier = types.StringValue(string(*res.Metadata.PerformanceTier))
 	}
@@ -110,18 +104,12 @@ func Create(ctx context.Context, resource *Resource, planData *ResourceModel) er
 		return err
 	}
 
-	// convert licenses
-	licenseStrings, err := license.StringToCdoStrings(res.Metadata.LicenseCaps)
-	if err != nil {
-		return err
-	}
-
 	// map return struct to model
 	planData.ID = types.StringValue(res.Uid)
 	planData.Name = types.StringValue(res.Name)
 	planData.AccessPolicyName = types.StringValue(res.Metadata.AccessPolicyName)
 	planData.AccessPolicyUid = types.StringValue(res.Metadata.AccessPolicyUid)
-	planData.Licenses = util.GoStringSliceToTFStringSet(licenseStrings)
+	planData.Licenses = util.GoStringSliceToTFStringSet(strings.Split(res.Metadata.LicenseCaps, ","))
 	planData.Labels = util.GoStringSliceToTFStringSet(res.Tags.Labels)
 	if res.Metadata.PerformanceTier != nil { // nil means physical cloud ftd
 		planData.PerformanceTier = types.StringValue(string(*res.Metadata.PerformanceTier))
@@ -144,17 +132,10 @@ func Update(ctx context.Context, resource *Resource, planData *ResourceModel, st
 		return err
 	}
 
-	// convert tf license to go license
-	licenses, err := util.TFStringSetToLicenses(ctx, planData.Licenses)
-	if err != nil {
-		return err
-	}
-
 	inp := cloudftd.NewUpdateInput(
 		planData.ID.ValueString(),
 		planData.Name.ValueString(),
 		planTags,
-		licenses,
 	)
 	res, err := resource.client.UpdateCloudFtd(ctx, inp)
 	if err != nil {
@@ -164,7 +145,6 @@ func Update(ctx context.Context, resource *Resource, planData *ResourceModel, st
 	// map return struct to model
 	stateData.Name = types.StringValue(res.Name)
 	stateData.Labels = planData.Labels
-	stateData.Licenses = planData.Licenses
 
 	return nil
 }
diff --git a/provider/internal/device/ftd/resource.go b/provider/internal/device/ftd/resource.go
index b745d20b..fa2edf84 100644
--- a/provider/internal/device/ftd/resource.go
+++ b/provider/internal/device/ftd/resource.go
@@ -17,6 +17,7 @@ import (
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/setdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier"
 	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
 	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
 	"github.com/hashicorp/terraform-plugin-framework/types"
@@ -101,6 +102,9 @@ func (r *Resource) Schema(ctx context.Context, req resource.SchemaRequest, resp
 				ElementType:         types.StringType,
 				MarkdownDescription: "Comma-separated list of licenses to apply to this FTD. You must enable at least the \"BASE\" license. Allowed values are: [\"BASE\", \"CARRIER\", \"THREAT\", \"MALWARE\", \"URLFilter\",].",
 				Required:            true,
+				PlanModifiers: []planmodifier.Set{
+					setplanmodifier.RequiresReplace(),
+				},
 				Validators: []validator.Set{
 					setvalidator.SizeAtLeast(1),
 					setvalidator.ValueStringsAre(stringvalidator.OneOf(license.AllAsString...)),
diff --git a/provider/internal/util/togo.go b/provider/internal/util/togo.go
index 75833ba7..38e2be29 100644
--- a/provider/internal/util/togo.go
+++ b/provider/internal/util/togo.go
@@ -39,7 +39,7 @@ func TFStringSetToLicenses(ctx context.Context, s types.Set) ([]license.Type, er
 	if err != nil {
 		return nil, err
 	}
-	licenses, err := license.StringToCdoLicenses(strings.Join(licensesGoList, ","))
+	licenses, err := license.DeserializeAllFromCdo(strings.Join(licensesGoList, ","))
 	if err != nil {
 		return nil, err
 	}