← All projects

Website & AWS migration

Infiniscope Migration

I rebuilt Infiniscope’s Angular website in React and Next.js and moved its hosting from DigitalOcean to AWS. The migration brought together the public resource catalog, Cognito sign-in, DynamoDB membership records, and a domain cutover. Returning members also needed a way to recover their accounts and keep access to existing tools.

  • AWS Amplify
  • Amazon Cognito
  • DynamoDB
  • Route 53
  • CloudFormation
  • IAM
  • AWS KMS
  • Systems Manager
  • React
  • Next.js
My part
I implemented the website and AWS deployment, built the member-import and recovery tooling, and handled the DNS cutover.
Released
The website and AWS cutover were released in October 2026. Legacy member-recovery tooling supports the transition.

Moving existing members

  1. Legacy sourcesCognito + Strapi
  2. ReviewIdentity + membership
  3. LinkNew login + member record
  4. ReturnReset when required + sign in
A returning member needs both a Cognito login and its DynamoDB membership link. Website hosting and DNS moved separately to Amplify and Route 53.

Rebuilding the website

The replacement carries forward the resource catalog, search, detail pages, and public media. I moved the application from Angular to React and Next.js, with direct checks for routes, content, keyboard interactions, and mobile behavior.

Build checks validate the published content and media hashes, check that Git LFS assets contain the actual files, and inspect the generated application for server-only configuration leaking into browser assets. This made the deployable output part of the migration review.

Hosting and account services on AWS

Amplify runs the Next.js application and serves its public assets. Cognito handles authentication, while DynamoDB stores member profiles, identity mappings, sessions, and migration records. I defined the retained member table, encryption key, and runtime permissions in CloudFormation templates.

The member table uses on-demand capacity, point-in-time recovery, deletion protection, and retention settings. Member and identity changes use conditional transactions so the application can reject conflicts without partially linking an account.

I separated the Amplify runtime role from build and operator access, with permissions scoped to the selected application branch and required resources. Client secrets stay in encrypted Systems Manager parameters. Session tokens are encrypted server-side using KMS, and the website session uses a Secure, HttpOnly cookie.

Connecting logins to member records

The old system held authentication in Cognito and member profiles and approval status in Strapi. A login in the new Cognito pool needed a link to the correct member record in DynamoDB before the website could resolve that person’s access.

For legacy recovery, matching uses the canonical username and original identity evidence. The member link is then bound to the new Cognito issuer and subject. Email alone is insufficient because more than one legacy identity can share an address; ambiguous matches stop for review.

The initial reviewed batch created and independently verified 3,523 approved member records for logins already imported into the destination pool. Two source accounts remained held for review. Approval was an explicit decision for that cohort, and the import granted no administrator permissions. It retained available identity and name data; reconstructing full historical profiles was separate work.

Applying a reviewed import

I built an operator tool that checks the destination AWS account, Cognito pool, and member table against a reviewed plan. A preview identifies records ready to apply, records already present, and conflicts requiring attention. The approved plan is bound to a checksum before writes begin.

Each member’s records are created together in a conditional DynamoDB transaction, including the identity mapping, membership-status record, audit entry, and migration receipt. Existing records cannot be silently overwritten. After an interruption, the tool verifies completed records before continuing, and separate read-only checks establish what was actually applied.

Later recovery preserves the source member’s approval and restrictions. A pending or blocked legacy account does not become an approved member merely because its login can be imported. Existing destination profiles and newer membership decisions take precedence over the archive.

Returning users to their accounts

Passwords were not copied into the new system. Imported users who require a reset receive guidance after attempting sign-in, request a recovery code, set a new password, and then sign in normally. Resetting the password does not itself create a session or change membership approval.

Hosted testing before the public-domain cutover included a real member completing that journey, launching the existing Tour It application, and opening their saved tours. The website’s tool handoff checks current approved-member access. The separate Tour It rebuild has its own integration work ahead.

Moving the domain to AWS

I prepared Route 53 with the website destinations and preserved the existing mail, verification, and unrelated service records. Amplify’s custom-domain association and certificate validation were checked before changing the registrar’s nameserver delegation.

The cutover changed the application’s configured origin to the final public hostname and rebuilt the reviewed source. Verification checked actual registry delegation and DNS answers, HTTPS, public pages and assets, protected API responses, and the root-to-www redirect with its path and query intact.

Legacy-service retirement was kept separate from the DNS switch so remaining consumers and recovery data could be reviewed before shutdown. The new hosting arrangement handles the website and redirect on AWS.

Supporting users beyond the first batch

I also built a member-recovery archive and support tool for legacy users missing from the new system. The archive preserves full Strapi profiles, original Cognito identity evidence, referenced profile-picture files, and checksums. Staff can use it without restarting the old Strapi service.

The workflow checks the archive’s integrity and the current destination records, previews the proposed changes, and records unfinished operations for reconciliation. Its purpose is member recovery; a full CMS/database backup and restore remains separate. Preserved preferences and media can also require adaptation where the new website differs from the old one.

What the release established

The migration has local server, component, content, and desktop/mobile browser verification, plus the recorded live member-recovery journey and AWS hostname checks. The website deployment and public DNS cutover completed in October 2026.

Those checks cover specific accounts and workflows. The cutover record leaves final-domain account and form-delivery acceptance, and legacy-service retirement, as separate follow-up work. The initial member batch and the recovery archive do not establish that every legacy user has signed in successfully.