Component state migration
A component’s implementation can change substantially between versions. Its logical resource graph may move from N resources to M resources even though the physical cloud objects remain unchanged. For example AWS Bucket vs BucketV2 with sidecar resources. Another example is moving from AWSX components to plain AWS resources.
Aliases only handle one-to-one resource renames and reparenting and users currently need to edit state manually, do complicated imports or accept unnecessary replacements.
We want to introduce an API that allows these migrations. The initial version will provide an API allow raw state modifications. A follow up might provide a more declarative API.
Draft developer docs on how migrations work
AWSX -> AWS example
Version 1 uses awsx.ecr.Repository. Its state contains three resources:
awsx:ecr:Repository "repo"
├── aws:ecr/repository:Repository "repo"
└── aws:ecr/lifecyclePolicy:LifecyclePolicy "repo"Version 2 removes the AWSX dependency and registers the underlying resources directly:
aws:ecr/repository:Repository "repository"
└── aws:ecr/lifecyclePolicy:LifecyclePolicy "lifecycle-policy"The migration adopts the existing repository and lifecycle-policy states, preserving their provider IDs, turning the V1 state into V2:
def migrate_awsx_repository(args):
old_component, old_repository, old_policy = args.old_state
# Already migrated.
if old_component["type"] != "awsx:ecr:Repository":
return None
repository = copy.deepcopy(old_repository)
repository["urn"] = args.urn
repository["parent"] = old_component.get("parent")
policy = copy.deepcopy(old_policy)
policy["urn"] = lifecycle_policy_urn
policy["parent"] = args.urn
return pulumi.StateMigrationResult(
new_state=[repository, policy],
successors={
# The component and its repository child both become the new
# directly managed repository.
old_component["urn"]: args.urn,
old_repository["urn"]: args.urn,
# The old policy becomes the directly managed policy.
old_policy["urn"]: lifecycle_policy_urn,
},
)
# Register the AWS resources, with the migration attached to the `aws.ecr.Repository` resource
repository = aws.ecr.Repository(
"repository",
opts=pulumi.ResourceOptions(
aliases=[
pulumi.Alias(
name="repo",
type_="awsx:ecr:Repository",
),
],
state_migrations=[migrate_awsx_repository],
),
)
lifecycle_policy = aws.ecr.LifecyclePolicy(
"lifecycle-policy",
repository=repository.name,
policy=lifecycle_policy_json,
opts=pulumi.ResourceOptions(parent=repository),
)Source: pulumi/pulumi