Showing posts with label principles. Show all posts
Showing posts with label principles. Show all posts

Saturday, August 26, 2017

Principles and Practices of Cloud Applications

This article summarizes the essential principles, patterns, and practices of cloud application architecture and design that can increase organizational innovation and decrease long-term system maintenance costs.  My primary sources are the architecture teams at Amazon Web Services and Microsoft Azure as well as my professional experience daily applying these ideas to production systems.  Subsequent articles will focus on processes and technologies specific to AWS and Azure.

 

 

Principles

Patterns

Practices

Scalability

Decomposition

Partitioning

Stateless

Elasticity

Caching

CDN

Queue Worker

Pipes and Filters

Encapsulation

Materialized View

Eventual Consistency

Understand customer SLA for performance.

Measure and profile performance with load benchmarks.

Partition and decompose workloads into discrete units.

Partition around data, network, and compute limits.

Design for horizontal scalability (scaling out/in vs. up/down).

Ensure applications and services are stateless.

Avoid client affinity and server-side session state.

Minimize coordination and shared state.

Queue I/O and CPU intensive requests as background tasks.

Distribute background tasks across multiple workers.

Cache items that don’t change much.

Use CDN for caching static data.

Reduce chatty interactions between components.

Build golden component images using Docker.

Leverage PAAS auto-scaling features with golden images.

Consider compression and binary format for DTO transfer.

Optimize SQL indexes and queries.

Consider document DB or de-normalizing data model.

Avoid locking database  resources.

Prefer optimistic concurrency and eventual consistency.

Minimize time that connections and resources are in use.

Minimize number of connections required.

Resiliency

Redundancy

Load Balancing

Retry

Circuit Breaker

Replication

Healthchecks

Telemetry

 

Understand customer SLA for availability.

Analyze system to identify failures, impact, and recovery.

Use redundant components to minimize single point of failure.

Use load balancing to distribute requests.

Handle transient failures with limited retries and backoff.

Handle persistent failures with circuit breaker that falls back to reasonable action while dependency is unavailable.

Use multiple availability zones.

Monitor health of dependencies and endpoints.

Checkpoint long-running transactions.

Design for failure and self-healing.

Understand replication methods for data sources.

Automate persistent data backup.

Document failover/failback processes and test them.

Throttle excessively active clients.  Block bad actors (DDoS).

Perform fault injection testing to verify system resiliency.

Security

Defense in Depth

Least Privilege

Traceability

Federated Identity

Gatekeeper

Compartmentalize

Apply defense in depth; secure all resources - not just edges.

Secure weakest link. Trust reluctantly and verify. Fail securely.

Pay attention to data privacy and residency requirements.

Protect data at rest (storage encryption) and in transit (SSL).

Mitigate DDoS using cloud platform’s network layer.

Enforce ACL’s at network, application, and data layers.

Conduct vulnerability analysis and penetration tests.

Manage keys carefully and secure with hardware tokens.

Use SSO, multi-factor authentication, and federated identity.

Use anti-virus and anti-malware for network and host nodes.

Simplify BCDR through PaaS centric, automated backup and recovery.

Integrate diagnostics of network, application, and data layers to have monitor system and correlate enterprise intrusions.

Prefer connectivity from cloud to on-prem resources using dedicated, private WAN links vs. VPN tunnels over public links.

Application Design

High Cohesion

Loose Coupling

Single Responsibility

Open/Closed

Interface Segregation

Dependency Inversion

DDD

CQRS

RESTful Web API

Messaging

Design with the organization goals and end-user in mind.

Design for evolution and change.

Prefer loosely-coupled components whose communication is asynchronous that can evolve, heal, and scale smarter.

Separate infrastructure logic from domain logic.

Prefer RESTful Web API’s for external communication.

Prefer asynchronous messaging for internal communication.

 

Management

Telemetry

Automation

Source Control

Agile

Design for IT Ops (Deploy, Monitor, Investigate, Secure)

Document system release process and use change control.

Automate system build and deployment processes.

Implement logging and alerting into systems.

Instrument to analyze root cause of errors.

Instrument to monitor availability, performance, and health.

Standardize log formats and metrics. 

Inventory, inspect, and audit cloud assets.

Use distributed tracing (asynchronous, Correlation ID).

Version and control configuration like other system artifacts.

Use Agile project methodology for iterative development.

 

References

       https://aws.amazon.com/architecture/

       https://docs.microsoft.com/en-us/azure/architecture/

Monday, January 2, 2017

Principles and Practices | Web API

This article enumerates the best principles and practices for designing, deploying, and maintaining successful Web API’s that can drive organizational innovation forward.  This document has borrowed and consolidated ideas from Apigee (Bryan Mulloy), Microsoft, and Mulesoft (Mike Stowe); I highly encourage the reader to also review these primary sources.  I will use the fictional Acme company as an example throughout this article.

 

Category

Principles and Practices

Requirements

Understand your users.  What are the use cases? What technologies/services will be used?

What are the business resources that need to be managed? What are their entity relationships?

Acme Answer: Users are digital Builders and the key resources are Bricks

Design Strategy

Think long-term.  Not just release 1.  But think 2-3 years ahead.

Ensure the API is platform independent to maximize API portability and usage.

Be stateless to maximize scalability, increase cacheability, and reduce client/server dependencies.

Be consistent.

Be flexible.

Keep It Simple and minimize complexity throughout.

Prefer Nouns, not Verbs

Prefer plural nouns, instead of verbs.

http://acme.com/api/bricks [preferred] vs.

http://acme.com/api/getbricks [avoid, since this is more verbose and leads to complexity]

Use verbs if you are implementing calculations or transformations that are unrelated to resources.

Map CRUD to HTTP verbs

DELETE, GET, PUT, and POST requests should be idempotent.

http://acme.com/api/bricks

Create => POST

Read => GET

Update => PUT

Delete => DELETE

Map Errors to HTTP Status

Handle errors consistently, at least 5 of the 70-ish HTTP response status codes.

200 - OK

400 - Bad Client Request Format

401 - Unauthorized Client Request

404 - No Resource

500 - Server Error

501 - Not Implemented

503 - Service Unavailable

Map exception and detailed error messages into the response payload.

Version API

Never release the API without a version.  This is part of managing change and being flexible.

Prefer versioning in the base URI to be explicit instead of a request query or header parameter.

Prefer simple ordinal numbers over dot notation and timestamping.

Prefer v1 instead of v1.0 or v2016-01-01.

http://acme.com/api/v1/bricks

IO Formats

Default format for input and output should be JSON.

Support multiple input and output formats.

Optionally support XML for input and output as well CSV for output.

 

Support content types specified in the URI:

GET /api/v1/bricks.json

GET /api/v1/bricks.xml

 

Support content types specified in request header:

Content-Type: application/json

Collection Navigation

Provider filtering, sorting, field selection, and pagination of collections.

GET /api/v1/bricks/?color=red

GET /api/v1/bricks/?sort=model

GET /api/v1/bricks/?limit=50&offset=10

GET /api/v1/bricks/?fields=id,model,color

Consolidate

Consolidate all API services and requests into one domain.

Example: http://api.acme.com/v1/

Document

Document your API and publish the specification online.  Use Swagger or RAML.

Security

Authenticate and authorize all users.

Validate input requests.

Prefer declarative security on individual methods of service endpoints.

For private intranets using Active Directory, assign permissions to roles consisting of AD groups.

For public extranets, consider using OAuth 2 and SSL.

Throttle users that exceed API limits and generate 503 errors with Retry-After headers.

Deploy

Log requests for troubleshooting and customer metering.

Support multiple channels for customer feedback: email list, online forum, Slack channel, etc.

Monitor API health, activity, and usage in Production.

Consider using 3rd party products for enterprise API management and standardization.

 

References

       Apigee

       Microsoft

       Mulesoft

       Rest Cookbook

       Mathieu Fenniak Checklist

Thursday, December 15, 2016

Principles and Practices | SDLC

This article summarizes some of the core principles, best practices, and my common sense for governing the Software Development Life Cycle.  These SDLC ideas are applicable for both products and projects.  I look forward to discussing these ideas with the wider community.

 

Category

Principles and Practices

Feasibility

Identify the product/project investors, business sponsor, and key stakeholders.

Establish economic model with costs and benefits spanning average and best/worst cases.

Write a clear mission and vision statement.

Requirements

Document requirements for Minimum Viable Product (MVP).

Document user stories, data model, 3rd party constraints, as well as the why, not just the what.

Prototype UI and MVP concepts; get feedback from key users and domain experts.

Project Management

Define delivery of the project or product into large milestones and smaller iterations.

Use 3-4 weeks per iteration and sprint. Plan sprints as a team.

Schedule daily scrums and weekly meeting to review progress, obstacles, and scope.

Define change control process that connects stakeholders with cost/benefit tradeoffs of change.

Create work breakdown structure; define and sequence activities.

Get labor and material cost estimates from engineering - not management or marketing.

Establish a single point of accountability for technology, process, and business matters.

Plan and distribute communications.  Manage stakeholder expectations.  Report performance.

Identify top 10 project/product risks.  Monitor and communicate risk assessment throughout.

Identify core team of 3-5 people (e.g. size of large pizza) including business, engineering, and QA.

Publish planning documents for managing costs, risks, QA, team, procurement, and requirements.

Architecture

Define major building blocks including their responsibilities and interfaces (Miller’s Law: < 9).

Visualize the solution architecture for shared understanding using UML diagrams.

Design

Single Responsibility - components should have only 1 reason to change and exist.

Encapsulation - share only what is needed; hide the details.

Cohesion - gather and release related components, functions, and data together.

Dependency Inversion - depend on abstractions, not concretions to manage change.

Simplicity - make components/systems as simple as possible; minimize complexity.

Stability - use stable abstractions, dependencies, and interfaces.

Consistency - use consistent naming conventions, code styles, etc.

DRY - Do not Repeat Yourself.

YAGNI - You Ain’t Gonna Need It.  Things Change. Plans change. Avoid gold plating.

KISS - Keep It as Simple as poSsible.  But no simpler.

Refactor during maintenance iterations.  Design does not end in one phase.

Consider domain specific languages to represent flexible logic and rules.

Consider reflection, attribute-based programming for dynamic feature surfaces.

Consider microservices to reduce monolithic system into modular components.

Consider concurrency and scaling to multiple processors and machines.

Consider portability and migration to other platform/infrastructure environments.

Consider localization and internationalization.

Security

How is the solution secured?  Consider users, data, and system itself.

How are users authenticated and authorized?

Does data need to be encrypted in storage and transmission?

Grant minimum privileges to users and service accounts.

Use enterprise identity management systems (e.g. Active Directory, ) that federate.

Avoid inventing your own user/group/password management and encryption systems.

Database

Is ACID necessary?  Then perhaps SQL/RDBMS.  Or does scalability suggest NoSQL?

Visualize logical entities and their relationships using diagrams.

Use primary keys and foreign keys for referential integrity.

Use default and check constraints for column data integrity.

Use indexes for large tables (1M+) and partitions for larger data sets (1B+). 

Use NoSQL, document oriented databases for very large data sets (1T+).

Avoid cursors, triggers, and dynamic SQL.  Use them sparingly and consciously.

Secure access through groups and roles.

Plan for growth and disaster recovery.  Stress test for performance and reliability.

Artifact Control

Manage source code, binary references, and documentation using Version Control System.

Prefer GIT; TFS and Subversion are OK though.

Secure access to artifacts through groups and roles.

Plan for several people working on system over time, perhaps at same time.

Source code is not owned by one person; it is collectively owned by the team.

Quality Control

Code defensively. Check parameters. Use assertions. No broken windows.

Are there tests for Correctness? Integration? Performance?  Security?  UX?

Define automated unit tests such as MSTest, NUnit, jUnit, or RUnit.

Assign manual beta testing driven by checklists to independent group of power users.

Review designs before coding. 

Review code before production deployment.

Devops

Where will the solution run? desktops?  Mobile?  On Prem?  Cloud?

How will you deliver system updates and changes over time?

Maintain separate environments for Development, Test, and Production.

How do you log system activity especially errors and end-user usage?

Automate builds and deployments using VSTS, Chef, Octopus, PowerShell, bash, etc.

Support

How will users contact you regarding features and defects?

Track past, present, and future work in an online backlog

Use JIRA, VSTS, or a similar system.   Avoid spreadsheets and email.

Customers

Delight users. Under promise and over deliver.

Prioritize system feedback from power users who influence others and are passionate.

Key users should be part of project and product teams and available - onsite, daily.

Peopleware

Align team member interests with work assignments.

Create workspaces that support thoughtful, focused, un-interrupted work.  Avoid open offices.

Establish accountability and responsibility for decisions by making people put skin in the game.

Take time to celebrate achieving milestones and performing post-mortems.

Metaphors

Cone of uncertainty - explore risk areas and learn to reduce uncertainty over lifecycle.

Triangle of constraints - cost, scope, and quality. Pick 2 out of 3; it’s tough to have it all.

Tracer bullets - use prototypes and feature spikes to find the moving target in the dark.

Microstones - track progress on smaller units work to keep team focused within milestones.

Proverbs

Work with users to think like a user.

Don’t gather requirements like scattered seeds; dig for them like buried treasure.

You will fail, if there is no plan, no one following plan, and no change to plans when things change.

Abstractions live longer than details.

Test early, often, and automatically.

Provide options; don’t give lame excuses.

The word of someone else’s mouth sells better than opening yours.

Good architectures with conceptual integrity should manage complexity and change.

Do not assume something to be true; try to prove it.

Sign your work; take pride in quality and craftsmanship.

If you found it painful more than twice, then automate it.

The cost of “quick and dirty” often lasts longer and gets dirtier than the quick win’s benefit.

The best and the perfect are the enemy of the good.

You don’t make money by developing software, but by delivering and selling software.

Leverage 80/20 rule - finish 80% of requirements before design and 80% of design before coding.

 

References

       Feasibility/Requirements

       Lean Enterprise by Humble, Molesky, and O’Reilly

       Design/Construction

       Extreme Programming by Kent Beck

       Pragmatic Programmer by Andrew Hunt and Dave Thomas

       Code Complete by Steve McConnell

       Design Patterns by GoF

       DevOps

       Release It by Michael Nygard

       Project Management

       Essential Scrum by Ken Rubin

       PMBOK by Project Management Institute

       SDLC

       Software Project Survival Guide by Steve McConnell

       Peopleware by Tom DeMarco and Tim Lister

       12 Steps to Great Code by Joel Spolsky

       Principles and Practices of SDLC