We have recently completed a migration of our core marketing data warehouse infrastructure from Terraform to Pulumi (TypeScript). The primary motivation was to achieve tighter integration between our infrastructure definitions and our internal marketing operations application code, which is also written in TypeScript. We anticipated benefits in code reuse, type safety, and unified dependency management.
The migration itself was largely successful for stateless components like IAM roles, Lambda functions, and S3 buckets. However, we are encountering a persistent and critical issue with our stateful Aurora PostgreSQL RDS cluster. Following the migration and a successful initial `pulumi up` that imported the existing resource, every subsequent `pulumi preview` indicates that Pulumi wants to replace the entire RDS instance. This is a non-starter for a production database containing all our attribution modeling tables and aggregated campaign performance data.
Our Pulumi program's resource definition appears to be a direct translation of our prior HCL. We are specifying the engine, instance class, allocated storage, and other parameters explicitly to match the live AWS resource. We utilized `pulumi import` to bring the existing cluster under management, and the state file reflects the correct physical AWS resource ID. Yet, the drift detection on preview consistently flags a replacement. The output indicates changes to properties like `storageEncrypted` (which is set to `true` in both our code and the live resource) and `engineVersion` (which we have pinned).
This suggests a potential mismatch in how Pulumi's AWS provider calculates the diff versus the actual imported state or the live AWS API response. We have scrutinized the obvious culprits:
* We have ensured all computed/output properties from the import are not being inadvertently used as inputs in our code.
* We have compared the `pulumi stack export` state for the resource against the actual AWS CLI describe output.
* We have attempted to use `ignoreChanges` on all properties except essential ones, but this feels like a dangerous and unsustainable workaround that masks the root cause.
The core question for this community is whether this is a known hazard when importing complex, stateful AWS resources into Pulumi after an IaC migration. Specifically:
* Are there intrinsic properties of RDS clusters that are particularly prone to being misread after import, leading to perpetual replacement cycles?
* Beyond the basic import command, are there specific strategies for reconciling the provider's schema with the live resource's actual configuration to achieve a stable desired state?
* Was the operational risk and effort to retool our IaC ultimately negated by such state management issues with critical resources?
The business impact is significant. We cannot proceed with any other infrastructure updates while this replacement threat looms, as it blocks our CI/CD pipeline for the entire martech stack. Our attribution reporting and lead scoring models depend on this database's stability.
This is a classic import drift scenario. The initial import likely captured the resource's *current* state, but your Pulumi definition is specifying the *desired* state from your Terraform code. AWS often returns default or calculated values that differ from your explicit config.
The usual culprit for RDS is `storage_encrypted` or `performance_insights_enabled`. Even if you set them, the API might return them as `false` in a preview if they were never explicitly set before import. Check the detailed replacement diff in your preview output, line by line. Look for a property where your code says `true` but the state says `undefined` or `false`. You'll likely need to `ignoreChanges` on that specific property.
Also, verify the `engine_version`. Sometimes it's stored as "13.4" in your code but the state has the full version string like "13.4.r1".
Numbers don't lie