Executive Summary: This whitepaper outlines Barbaricum’s experience modernizing a legacy .NET application to a cloud-native architecture on Amazon Web Services (AWS), leveraging leading technologies including React, DynamoDB, and Amplify.
Points of Contact
Matt Webster, Chief Technology Officer
Matt Webster has 25 years of experience in software engineering, architecture, and management. He specializes in cyberwarfare, big data and cloud technologies, having transformed and delivered innovative and secure solutions to the Department of Defense, Intelligence Community, Federal Law Enforcement, healthcare, and commercial clients.
David Curry, Data and Software Technologist
David Curry has 25 years of industry experience. He has fostered engineering excellence through technical leadership, aligned teams and technology to meet business needs, and delivered systems that transform organizations.
Kimberly Manherz, Senior Portfolio Manager
Kimberly Manherz is a data professional with a unique background traversing the Department of Defense intelligence community, military operations, and healthcare. Her extensive knowledge in open and closed source intelligence, risk assessments, due diligence, cyber threat, signature reduction, sensitive activities and travel awareness helps Barbaricum better understand the threat and OSINT landscape.
Introduction
Barbaricum harnesses the power of technology to remain competitive and responsive to changing customer needs. Legacy applications built on outdated architectures severely inhibit agility, innovation, and efficiency. As business demands evolve rapidly, applications must be modernized or find themselves constrained by manual processes, fragility, and lack of scalability.
The Barbaricum Application Modernization White Paper outlines our experience migrating a legacy .NET application using traditional hosting to a cloud-native architecture leveraging AWS Amplify, AWS DynamoDB, and React. This modernization enables us to deliver capabilities faster, reduce cost, and strengthen resilience.
The migration transformed our application from a standalone system requiring manual intervention to an agile, scalable, and stable platform powered by the same AWS cloud technologies Barbaricum uses on contract. This new infrastructure-as-code approach boosts developer productivity, accelerates release cycles, optimizes infrastructure costs, and enhances operational resilience.
The key insights from our application modernization journey detail the challenges with our legacy system, analyze how we selected target technologies, review our migration process, and summarize lessons learned.
The Barbaricum application modernization efforts delivered meaningful improvements in our capabilities. Our goal is to provide recommendations for other organizations looking to modernize their applications. The strategies below can prepare organizations to modernize technology stacks that align with today’s cloud-native, API-driven landscape. Furthermore, our approach highlights opportunities for organizations to evolve internal skills and processes, where they rapidly deliver innovations that meet business needs.
Assessing the Current State
Our legacy .NET application was built years ago as a standalone system hosted on an AWS EC2 virtual machine running Windows Server 2012. This traditional hosting approach was common and preferred over running on-premise systems. Over time, the limitations of this approach, including the need to actively defend the cybersecurity attack surface, intermittent issues with applying Windows patches to live application environments, and the inability to securely share data with other systems, have become apparent.
Additionally, the monolithic nature of the application made it challenging to update portions of the code independently. As a result, even small changes required redeploying the entire application and the manual process slowed down development cycles. This application was the first of many Media Monitoring applications. As issues were discovered in the deployed copies, those issues remained in the initial application, causing the code bases to diverge and limiting the ability of developers to quickly patch issues.
The virtual machine hosting model also contributed to stability issues. Any disruption in the infrastructure could bring down the application. These failures were hard to predict and trace due to multiple points of failure across network, virtual machine, operating system, and application layers.
The .NET code base required patching due to a reliance on the Telerik framework and associated Kendo UI libraries. While these licensed libraries originally accelerated our initial development, we found ourselves unnecessarily locked-in to the Telerik ecosystem as issues and vulnerabilities were discovered. Because the web application was not updated frequently, each update or fix required either licensing newer versions or working through outdated documentation to understand and then remediate. The license, hosting model, and platform dependencies created tight coupling, therefore making the integration of new technologies challenging.
The backend datastore relied on MongoDB, which provided schema flexibility but lacked native redundancy and resiliency capabilities. Because of the application’s monolithic nature, upgrading MongoDB as its versions progressed was considered too risky and cost-prohibitive to continue. As a result, even connecting with the database for data inspection or migration involved downloading archived tools.
Overall, the legacy architecture lacked agility and became fragile, leading to slow release cycles. It became evident that modernizing the application was critical to unlock our development teams’ productivity and deliver better capabilities to customers.
Strategic Migration Plan and Outcomes
Strategic Migration Process
Recognizing challenges within our legacy architecture, we crafted a modernization strategy that emphasizes cloud-native solutions. Our key objectives and their respective outcomes include:
- Adopting Event-Based Cloud Architecture:
- Scale specific system components as needed.
- Enhance system parts without disruption to others.
- Boost resilience to ensure the system remains operational even if a component fails.
- Implementing Monorepo Approach: Simplify the management of multiple customer sites.
- Opting for AWS Cloud Hosting: Elevate system resilience and stability.
- Utilizing AWS Amplify Infrastructure-as-Code:
- Streamline deployment processes.
- Deliver AWS Amplify apps in half the time compared to React with a custom backend.
- Embracing CI/CD: Achieve 10x faster delivery for bug fixes and enhancements compared to monolithic .NET.
- Promoting Agile Development: Establish Development, Staging, and Production environments.
- Engaging with AWS Amplify Support: Access direct developer support via a public Discord channel.
- Deepening AWS Infrastructure Knowledge: As Barbaricum’s primary cloud infrastructure provider, enhance our proficiency with AWS solutions.
To modernize our data layer, we migrated the MongoDB database to AWS DynamoDB. This fully-managed NoSQL database provides high availability, scalability, and durability without the overhead of managing infrastructure. Additionally, using DynamoBD with GraphQL enabled the development of a fully privileged administration app and a read-only customer-facing app both sharing the same DynamoDB tables.
We re-architected the front-end code base from .NET to React. With its component-driven approach, React enabled easier feature development aligned with our event-based architecture direction. The vibrant React community also ensured access to up-to-date documentation, tutorials, and feedback from GitHub Pilot’s and OpenAI ChatGPT’s artificial intelligence to quickly remedy issues and provide insights into how to approach development.
Finally, we used the AWS Amplify built-in DevSecOps code deployment pipelines, allowing development and staging environments to be validated before deploying changes to production.
Strategic Migration Result
This combination of technologies allowed us to adopt a cloud-native, API-first approach for the new architecture. The plan addressed our key constraints around monolithics, fragility, and lack of agility while positioning us well for the future.
Legacy Application Migration
Executing a successful legacy application migration requires careful planning, stakeholder collaboration, and an iterative phased approach. We partnered closely with business analysts and end-users to migrate a legacy .NET application to a cloud-native architecture on AWS.
The first priority was deeply understanding the capabilities and pain points of the existing system. Through interviews and working sessions, we gathered requirements from the analysts who used the system daily. This allowed us to design the new architecture directly addressing their needs.
With requirements defined, we built a minimum viable product focused on core functionality and user authentication. By bringing in analysts early and often for feedback, we refined the UI/UX iteratively before moving to the backend systems. Short two-week sprints enabled rapid refinement of the frontend component library.
Once the MVP took shape, comprehensive user acceptance testing was conducted. The analysts validated all key workflows and functionality prior to launch. This confirmation that the new application was ready was a critical milestone clearing the path to production.
With the frontend hardened, we transitioned focus to the backend migration. Legacy data was moved from MongoDB to DynamoDB, enabling next-generation access patterns. Extensive tests post-migration identified any issues needing resolution.
A controlled launch to production came next. Our team was on standby, responding rapidly to any issues uncovered by real-world usage. The launch went smoothly with only minor tweaks needed.
Post-launch, we employed agile processes to continuously improve and enhance the application based on user feedback and analytics. This iterative approach resulted in ongoing optimization.
The combination of upfront requirements gathering, phased development, and collaboration with end users ensured a smooth transition to the new platform. The modernized application provides a scalable foundation for future initiatives.
AWS Amplify Experience
AWS Amplify is a suite of tools and services that enables developers to build full-stack, scalable applications. With its declarative interface and command-line toolchain, Amplify allows developers to quickly create and connect to cloud services. This enhances application development workflow and drastically reduces development time. The platform supports popular frameworks such as React, Angular, Vue.js, and mobile platforms like iOS and Android, extending its versatility across different technology stacks.
AWS Amplify Considerations
We chose AWS Amplify based on the following considerations:
- AWS Team Capability: Barbaricum is focused on AWS partnership and our team is knowledgeable in AWS services and cloud computing concepts.
- Scalabile Requirements: If the application needs to scale rapidly, AWS Amplify can provide robust and reliable scalability.
- Reduced Cost: Amplify ties-in with multiple AWS services and allows us to closely monitor usage to manage costs effectively.
Amplify Capabilities
At its core, Amplify is a platform that makes it easy for developers to create software without the need to manually manage back-end services. Amplify is split between hosting and back-end. The hosting allows for CI/CD, connected directly to our repo. The backend can be managed via the Amplify console or through a configuration file that resides in code.
The Amplify backend platform is an orchestration of services, including Cloud Formation, AppSync, DynamoDB, Lambda, S3, and Cognito. The real power of Amplify is its ability for the developer to configure backend services without the need to manually create those services individually. Backend services management is abstracted from the developer and configured through the Amplify Studio interface or a configuration file that resides in code. Although the backend services management is abstracted, the developer can still find the backend services in the AWS console, such as an S3 bucket, Lambda function, or Cognito user pool.
DynamoDB
Amplify abstracts away much of the complexity associated with setting up a new database. With the Amplify CLI, we provisioned new DynamoDB tables with just a few commands. With Amplify’s GraphQL Transform library, we defined your data model using GraphQL schema definition language. The library then translates these definitions into CloudFormation templates that provision the necessary AWS resources, including DynamoDB tables.
Amplify provides out-of-the-box support for real-time data synchronization using directives. This means we can easily set up subscription-based real-time updates from our DynamoDB tables to the frontend application. Amplify comes with pre-configured authentication flows, making it easy to secure DynamoDB data with directives for access controls based on user roles or ownership.
AppSync
We found that AWS AppSync was one of the biggest time-saving features of Amplify. Once a back-end service is created for the project, an AppSync service is automatically associated with DynamoDB tables. AppSync automatically creates GraphQL API calls for each DynamoDB table, including queries, mutations, and subscriptions. Any time a change is made to the data model, those changes are automatically updated and reflected in AppSync. This allowed developers to focus on building the UI and not have to build and maintain the API.
Additionally, AppSync and the Amplify platform work well with our agile development cycle, with its automated ability to update backend services with a single change in Amplify Studio or the Amplify configuration file.
Cognito
Utilizing AWS Cognito through Amplify was another time-saving feature. Adding Cognito to the Amplify project automatically creates a user pool and React sign-up and login UI components. The complete signup process is managed by Cognito, including signup confirmation email and password reset. We were able to enhance the signup process with additional business logic by attaching a Lambda function to specific Cognito processes, such as limiting signup to a specific domain.
Additional Features
Frontend Libraries and UI Components
Amplify automatically creates CRUD react components for each DynamoDB table. These components are added to the project via the Amplify CLI and can be used directly in the project.
Amplify CLI
The Amplify CLI is the engine that powers AWS Amplify, enabling developers to add features and tie their apps to AWS services. The CLI leverages AWS CloudFormation to provision and manage resources which ensures scalability and security.
Amplify Console
Amplify Console is a full-stack hosting service that automatically deploys and hosts our web application. It offers features like continuous deployment from our repository, instant cache invalidation, and atomic deployments, simplifying the process of hosting and maintaining applications.
Offline Data Access
Amplify DataStore provides capabilities for managing shared and distributed data amongst users and devices online and offline, ensuring data integrity and consistency, and integrating seamlessly with DynamoDB.
AWS Amplify Results
Overall, we found that Amplify’s unified ecosystem allowed developers to build a complex application with easy integration with AWS services. Amplify’s automated nature allowed our team to ship the product in half the time it would take if we had to build and configure the backend services manually.
10 Lessons Learned
- Engage End Users Early and Often: We conducted two-week sprints with regular touchpoints and reviews by the business analysts. This ensured we stayed aligned.
- Form an Integrated Team: Close collaboration between developers, analysts, and QA drove success. More lead time for testing would have been beneficial.
- Architect for Change: Our shift to an event-driven, component-based architecture enables easier enhancements and scaling.
- Leverage Cloud Expertise: Tapping into AWS resources and support accelerated our learning curve.
- Demonstrate Business Value: The 10x faster delivery and 5x lower costs we achieved showcase the benefits of modernization.
- Celebrate Small Wins: We highlighted milestones met along the way to keep stakeholders motivated.
- Expect the Unexpected: Our timeline and budget buffered for surprises that did arise during migration.
- Invest in Continuous Training: Dedicate resources for retaining cloud and modern development skills.
- Take an Iterative Approach: Regular delivery of working functionality obtained user feedback rapidly.
- Embrace a Holistic View on Infrastructure Integration: Ensuring every component, from front-end to security protocols, works harmoniously for efficiency, security, and scalability.
For any modernization initiative, focusing on these lessons will streamline the project while avoiding missteps. Overall, securing engaged users, forming an integrated team, and leveraging cloud provider resources were key to our success. Contact Barbaricum for an expanded version of the AWS Amplify Experience Lessons Learned.
Conclusion
The modernization of our project underscores the tangible benefits of transitioning from legacy systems to cloud-native architectures. By forging strong collaborations with stakeholders and integrating forefront technologies such as AWS and React, we transformed a bulky application into an agile and robust platform. This overhaul resulted in discernible enhancements: quicker deployment times, cost savings, and heightened reliability. Furthermore, our developers were empowered with advanced skills, paving the way for subsequent innovations. Our iterative strategy ensured the delivery of a modern, tailored application aligned with stakeholder expectations.
Our upgraded infrastructure not only positions us to leverage upcoming breakthroughs in AI/ML and automation but also serves as a base for developing more portal-based apps and platforms for disseminating information. While cloud modernization presents challenges like bridging skill deficits, adapting to new security paradigms, and evolving company culture, the enduring advantages surpass the transient and manageable hiccups. With well-orchestrated planning, a cohesive cross-functional team, and a visionary approach, successful modernization is well within reach for any organization grappling with antiquated system limitations.
For more information, please contact us.