Professional Documents
Culture Documents
Steve Roberts
Seattle, WA, USA
This work is subject to copyright. All rights are solely and exclusively
licensed by the Publisher, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in
any other physical way, and transmission or information storage and
retrieval, electronic adaptation, computer software, or by similar or
dissimilar methodology now known or hereafter developed.
The publisher, the authors, and the editors are safe to assume that the
advice and information in this book are believed to be true and accurate
at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the
material contained herein or for any errors or omissions that may have
been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
This Apress imprint is published by the registered company APress
Media, LLC, part of Springer Nature.
The registered company address is: 1 New York Plaza, New York, NY
10004, U.S.A.
This book is dedicated to you, our readers.
Hopefully, we have saved you at least one bout of “Why isn’t this
working?”
Introduction
Cloud computing can be thought of as a way to deliver on-demand
computing services. These computing services can be as high level as
complete applications, such as Salesforce, or as low level as storage or
application processing. Access to these services is generally through the
public Internet. The concept of the cloud has taken off, and there is
research that says more than one third of all IT spending worldwide is
on cloud computing and that number will continue to grow. This book
is about a piece of that overall cloud computing pie, the combination of
one of the most popular software development frameworks, .NET, and
the first and largest cloud computing provider, Amazon Web Services
(AWS).
It sounds straightforward when you look at that previous sentence
until you really start to think through what that means; it sets the
expectation that we will talk about the union of .NET functionality and
AWS functionality. That is simply not possible as that union is huge and
writing about it would take several volumes and likely be out of date
before we even finished the second one. Instead, in this book, we are
trying to identify some of the most commonly identified development
scenarios, and we will use those to guide our journey.
Before we move into the juicy details of using .NET on AWS, let us
first go over some of the fundamental differences between working
with a cloud service and working with “your own servers.” There are
multiple different ways in which companies manage their “own
servers.” Some lease hardware from an infrastructure or hosting
provider and are responsible for everything above the iron, including
OS patches, systems drivers, installed applications, and everything in
between. If those companies want to run virtual machines, then they
have to purchase the management software and maintain that as well.
Other companies purchase the server hardware outright and thus add
details like network cards or other “pieces of metal” into the areas for
which they are responsible. Regardless of the approach that you take,
your company will have some system management responsibilities.
That does not necessarily change when you move to the cloud.
However, it becomes easier to define the responsibilities that each
party has. AWS calls this definition of responsibilities the Shared
Responsibility Model. This model defines what parts of the overall
operational burden will be owned by AWS and what parts of the burden
will be owned by the customer. This is important to consider when
building your applications as you should be building them in such a
way as to help minimize the operational burden that you, as a
developer/customer, have when working with AWS services. Not only
will this minimize your operational burden, it also, oddly enough, tends
to decrease your actual cloud service cost because it allows for a much
finer control over the various areas used by your application, such as
processing, memory usage, and storage. We promise there will be more
on this later when we go into the details of running your .NET
application on AWS!
We will be using a sample application through our journey. We
called it TradeYourTools, and it is a simple tool-sharing application that
is designed to help members of a neighborhood group document their
available hand and electrical tools and to provide a simple process to
reserve a tool and arrange their pickup and return. The application is
starting as an ASP.NET MVC v4.6 application that uses ASP.NET Identity
for registration. It has a Microsoft SQL Server back end that stores tool
data, including pictures, user information, and any uploaded pictures. It
works but be warned; it is not pretty – neither one of us claims to be a
UX expert!
We will be altering this application through our journey. We are
assuming that you are an experienced .NET developer and thus will not
be spending any effort talking about the fundamentals of what we are
doing. To take full advantage of the sample application, however,
requires that you have access to a .NET integrated development
environment (IDE). The most used IDE is Microsoft Visual Studio. There
are several versions of Visual Studio, each with differing sets of
functionality and price points. JetBrains offers a competing IDE, Rider,
and there is always the ubiquitous Visual Studio Code, a cross-platform
IDE that also supports .NET development. Most of the screenshots will
be using Visual Studio unless we are specifically talking about a
different IDE.
You will also enhance your experience if you have access to a
running SQL Server instance so that you can work with a local, fully
running application. The sample application will come with a database
creation script that will create all of the necessary tables and
relationships as well as load some sample data that will help you
understand the application and how all of the pieces go together. While
this will be useful, it is by no means required. If you must choose
between an IDE and a database, choose the IDE – you will spend more
time there!
You can download a trial version of JetBrains Rider at
www.jetbrains.com/rider/ . You can download both Visual
Studio and Visual Studio Code at
https://visualstudio.microsoft.com/ . The Community
Edition of Visual Studio is free and is our recommended choice if you do
not currently have access to a .NET IDE. You can download Microsoft
SQL Server Developer 2019, a full-featured free edition of SQL Server
that is licensed for use as a development and test database.
Any source code or other supplementary material referenced by the
author in this book is available to readers on GitHub. For more detailed
information, please visit http://www.apress.com/source-code.
Acknowledgments
Kudos to you, the reader, for deciding to learn and try something new.
Though, of course, for those of you experienced developers, this is not
something new. It’s amazing what we, the authors, learned while
writing this book – and we thought we were already experts. For those
of you that are just starting out your life in software development,
know that this is something you will need to continue to do for your
entire career as this field changes about as quickly as the water in a
river.
We would also like to thank Jonathan Gennick and Jill Balzano from
Apress who had the unenviable job of herding the cats. We would also
like to mention our appreciation to Brian Beach and Peter Himschoot
who had the onerous job of doing our technical review.
Lastly, but certainly not leastly (ha – let’s see if we can get it through
at least once), is the support for our wives, Jeanine and Deb, who
allowed us to spend way too much of our free time working on this
project.
Table of Contents
Part I: Getting Started
Chapter 1:The Core Essentials
The Essentials of AWS
Regions and Availability Zones
The AWS Free Tier
Hosting Your Code – Compute Services
Storage
Databases
Networking
Infrastructure As Code
Identity and Access Management
A Short Note for Enterprise Administrators
Introducing the AWS Management Console
Creating a User Account for Development
Creating the IAM User
Signing into the AWS Management Console
Introducing Credential Profiles
Summary
Chapter 2:AWS Tools for .NET
Integrated Development Environment (IDE) Toolkits
AWS Toolkit for Visual Studio
AWS Toolkit for JetBrains Rider
AWS Toolkit for Visual Studio Code
Command-Line Tools
AWS Extensions for .NET CLI
AWS Tools for PowerShell
AWS SDK for .NET
Summary
Chapter 3:Additional Tools
AWS Command Line Interface (AWS CLI)
AWS CloudFormation
Using the Console for Creating CloudFormation Stacks
Using the AWS Toolkit for Visual Studio for Creating
CloudFormation Stacks
AWS CloudFormation Project in Visual Studio
Deleting CloudFormation Stacks
AWS Cloud Development Kit
Understanding the CDK
Using the CDK
AWS Serverless Application Model (SAM) CLI
AWS Cloud9
Summary
Part II: Hosting Your Applications
Chapter 4:Virtual Machines
Virtual Machines and EC2
When Should You Consider EC2?
Key Components of EC2
Amazon Machine Images (AMIs)
Storage
Controlling Access with Security Groups
Customizing an Instance on Creation
Instance Role and Permissions
Creating and Configuring an EC2 Instance
Connecting to the Instance with the Management Console
Remote Desktop Connections to Windows Instances
Deleting the Instances
Summary
Chapter 5:Containers
Explaining Containers
Docker
Container Image
Container Registries
Example Container File
Immutability
Amazon Elastic Container Registry (ECR)
Pull Through Cache Repositories
Other Approaches for Creating an ECR Repo
Amazon Elastic Container Service (ECS)
Amazon Elastic Kubernetes Service (EKS)
Kubernetes
Kubernetes with Amazon EKS
AWS Fargate
AWS App Runner
What Container Offering Should Be Used?
Chapter 6:Serverless
Levels of Compute Abstraction
Serverless Compute with AWS Lambda
Your Function’s Compute Environment
Event-Driven Compute
Long-Term Support (LTS) vs.Non-LTS Runtimes
Tooling – dotnet CLI, SAM CLI, Visual Studio, Visual Studio
Code, or JetBrains Rider?Oh my…
Serverless Functions
Installing the Tools
Creating a Serverless Function
Writing the Function
Deploying the Function
Updating the Function Permissions
Invoking (Running) the Function
Debugging
The Mock Lambda Test Tool and Asynchronous Functions
Cleaning Up
Serverless Applications
Installing the Tools
Creating a Serverless Application
Writing the Application
Deploying the Application
Running the Application
Debugging
Cleaning Up
Choosing Between dotnet CLI Extensions and SAM CLI
Using Non-LTS .NET Runtimes
Custom Runtimes
Container Images
Summary
Part III: Storing Your Data
Chapter 7:S3 Object Storage
Object Storage in S3
Public or Private?
Object Versions
Object Metadata
Storage Classes
Reading and Writing Objects
Get and Put Object
Multipart Upload
The Transfer Utility
Presigned URLs
CDNs and Amazon CloudFront
Using S3 and CloudFront with Your Application
Summary
Chapter 8:Microsoft SQL Server
Unmanaged SQL Server on EC2
Microsoft SQL Server Licensing Limitations on EC2
Using SQL Server on EC2
Managed Services, SQL Server on Amazon RDS
Making an RDS SQL Server Instance Accessible from Outside
the VPC
Connect Your Application to a SQL Server Database on RDS
More About Using SQL Server on AWS
Chapter 9:Other RDS Databases
MySQL
MySQL and .NET
Setting Up a MySQL Database on Amazon RDS
MariaDB
MariaDB and .NET
Setting Up a MariaDB Database on Amazon RDS
Selecting Between MySQL and MariaDB
PostgreSQL
PostgreSQL and .NET
Setting Up a PostgreSQL Database on Amazon RDS
Selecting Between PostgreSQL and MySQL/MariaDB
Amazon Aurora
Creating an Amazon Aurora Database in RDS
Amazon Aurora and .NET
Oracle
Oracle and .NET
Setting Up an Oracle Database on Amazon RDS
Summary
Chapter 10:NoSQL Databases and AWS
Explaining NoSQL Databases
CAP Theorem
Data Storage Design
Different Types of NoSQL Databases
Deciding Between Relational and NoSQL
Amazon DocumentDB
MongoDB
Setting Up a DocumentDB Database
DocumentDB and .NET
Amazon DynamoDB
Setting Up a DynamoDB Database
DynamoDB and AWS Toolkit for Visual Studio
DynamoDB and .NET
Summary
Chapter 11:Purpose-Built Databases
Why Purpose-Built Databases Exist
In-Memory Databases
Amazon ElastiCache
Amazon MemoryDB for Redis
Time-Series Databases
Amazon Timestream
.NET and Amazon Timestream
Ledger Databases
Amazon QLDB
.NET and Amazon QLDB
Graph Databases
Amazon Neptune
.NET and Amazon Neptune
Summary
Part IV: Moving Existing Apps to AWS
Chapter 12:Moving to Virtual Machines
Virtual Machine Services on AWS
Introducing AWS Elastic Beanstalk
Elastic Beanstalk and .NET
Packaging Applications for Deployment
Deploying ASP.NET Applications
Deploying ASP.NET Core Applications
Using Publish to AWS to Deploy to Elastic Beanstalk
Customizing the Virtual Machines
Deploying to Elastic Beanstalk from Azure DevOps
A (Short) Word About HTTPS and Elastic Beanstalk
Deploying to Amazon EC2 Instances
Introducing AWS CodeDeploy
Working with CodeDeploy
Summary
Chapter 13:Containerizing
General Requirements
Containers and Networking
Amazon ECS
Amazon EKS
Containerizing a .NET Framework 4.x Application
Using Visual Studio
Containerizing Manually
Containerizing a .NET Core–Based Application
Using Visual Studio
Using JetBrains Rider
Containerizing a Running Application
What Is AWS App2Container?
Using AWS App2Container to Containerize an Application
Deploying New Container Using AWS App2Container
Summary
Chapter 14:Migrating Your Data
AWS Database Migration Service
How Does It Work?
Creating a Replication Instance
Creating Your Source and Target Endpoints
Creating Your Database Migration Task
AWS Schema Conversion Tool
Configuring the Source
Database Migration Assessment Screen
Configuring the Destination
Completing the Migration
Using the New Database
Summary
Chapter 15:Re-platforming and Refactoring
Assistive Tools for Re-platforming and Refactoring
Re-platform, Then Refactor?Or Refactor, Then Re-platform?
Re-platforming to .NET
Getting Started with the Porting Assistant for .NET
Determining the Compatibility of Your Application
File Modifications When Porting
Round and Round We Go – Porting the Application
What Did the Assistant Do for Us?
Refactoring to Microservices
Getting Started with the Microservice Extractor for .NET
Analyzing an Application
Visualizing an Application
Extracting a Microservice
What Did the Extractor Do for Us?
Summary
Part V: Building Cloud-Native Applications
Chapter 16:Events and Messaging
Modern Application Design
Evolving into Microservices
Deep Dive into Decoupling
Designing a Messaging or Event-Based Architecture
Messaging
Amazon Simple Notification Service (SNS)
Using AWS Toolkit for Visual Studio
Using the Console
.NET and Amazon SNS
Amazon EventBridge
.NET and Amazon EventBridge
Configuring EventBridge in the Console
Modern Event Infrastructure Creation
Infrastructure as Code
In-Application Code
Summary
Chapter 17:Monitoring and Observability
Why Do We Want to Monitor and Observe?
Instrumenting Code
The X-Ray Agent
AWS X-Ray and .NET
Amazon CloudWatch
Logging
Metrics and Alarms
Summary
A Final Word
Index
About the Authors
William Penberthy
has over 25 years’ experience in software development (almost 17 of
which is .NET) and brings a pragmatic approach to software
development. With much of that time spent in consulting, he has
worked on many different projects and used many different designs
and approaches. In 2021, he joined Unify Consulting where he works
with clients in optimizing their software development process and
building distributed systems for the cloud.
Steve Roberts
is a Senior Developer Advocate for .NET and PowerShell development
at AWS. Based in Seattle, Washington, Steve worked for eight years as a
Senior Development Engineer on the AWS tools for .NET before
switching focus to a developer advocacy role. He was the development
lead for the AWS Tools for PowerShell and the AWS Tools for Azure
DevOps and contributed to the AWS Toolkits for Visual Studio and
Visual Studio Code, and the AWS SDK for .NET. Prior to joining AWS,
Steve had over 20 years’ experience as a developer focused on IDE tools
and integrations.
About the Technical Reviewer
Peter Himschoot
works as a lead trainer, architect, and
strategist at U2U. He has a wide interest
in software development that includes
applications for the Web, Windows,
Clean Architecture, Domain-Driven
Design, and Security. He has trained
thousands of developers, is a regular
speaker at international conferences,
and has been involved in many web and
mobile development projects as a
software architect. He has been a
Microsoft Regional Director (from 2003
to 2019) and cofounded the Belgian
Visual Studio User Group (VISUG) in
2006, which is a group of trusted
advisors to developer and IT professional audiences and to Microsoft.
Part I
Getting Started
© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2023
W. Penberthy, S. Roberts, Pro .NET on Amazon Web Services
https://doi.org/10.1007/978-1-4842-8907-5_1
Getting started is always the hardest part of new systems, and AWS is no different. Approaching the breadth
of services and the functionality available in the AWS cloud can be a daunting prospect! What services
should you consider first for hosting your application? How do terms you may be familiar with, such as
virtual machines, map to services? How do you, as a developer, authenticate to provision and work with
resources? How does your application code authenticate to be able to call AWS services?
In this chapter, we’ll look at the essentials – what you really need to know about AWS to get started. We
are not going to go particularly deep – that’s for later sections of the book – but this chapter will give you an
overview of essential services and functionality that will be useful if you’ve never worked with AWS before.
In addition to core services, we will take our first look at the AWS Management Console and use it to set up a
“development user” identity as a recommended best practice. You’ll use this user identity to work with AWS
services, resources, and the tools (outlined in Chapters 2 and 3) during the remainder of the book.
You are responsible for keeping instances (and custom images) up to date with patches, etc. (AWS also
provides additional services that can help you do this). AWS operates a shared responsibility model , which
means that AWS protects the physical infrastructure and network but you are responsible for the security on
your resources.
How does your application get deployed onto an EC2 instance ? As with the virtual machine instance, you
have complete control here too. You can write scripts to download the application binaries and other
resources and place them onto the instance as it starts, or you can use services such as AWS CodeDeploy
(among others) to perform the deployment. In the case of CodeDeploy, you simply upload the built
application bundle and choose the instance(s) to be involved (by selecting the instance IDs, or some other
criteria such as tags or membership in a group), and CodeDeploy does the rest.
If managing running instances sounds like more work than you would like, but you still want to retain
some control, then consider services such as AWS Elastic Beanstalk or Amazon Lightsail. Both build on top of
EC2 to offer virtual machines under the hood but abstract away some or most of the management and
deployment aspects.
AWS Elastic Beanstalk is a service for deploying and scaling web applications and services and is the
fastest and simplest way to get your application up and running on EC2 virtual machines . As a developer,
your focus is on building and packaging your application. For .NET Framework applications, you use a Web
Deploy package . For .NET Core and .NET 5+, you use dotnet publish to build the deployment package.
In both cases, you upload the bundle to AWS and instruct Elastic Beanstalk to deploy it to the instance(s) in
your application’s environment. The environment contains the EC2 instance(s) and other resources
employed in hosting your application code. Elastic Beanstalk takes care of provisioning and managing your
infrastructure resources, and handling deployments, but you can still, if you wish, work with the underlying
resources. Should you need to, and network security settings permit, it’s possible to remote into the EC2
instances in the environment. Figure 1-3 shows an example of the resources and their chosen configuration
in a load-balanced auto-scaled Elastic Beanstalk environment .
Figure 1-3 Example Elastic Beanstalk environment and resources
Amazon Lightsail is another abstraction on top of EC2. Like Elastic Beanstalk, Lightsail takes care of the
provisioning of the underlying EC2 resources but takes a more simplified view of managing them. With
Elastic Beanstalk, you can tweak and adjust almost all the settings of the underlying resources (even though
the service created them for you). With Lightsail, fewer settings are exposed, but you can still remote into
the underlying instances if needed. Offering an even more managed experience than Elastic Beanstalk,
Lightsail is ideal for simple workloads, or just getting started on AWS, but provides the ability to “grow into”
the full EC2 experience later if you need to.
Next, we have the choice of using containers. AWS provides two container services: Amazon Elastic
Container Service (ECS) and Amazon Elastic Kubernetes Service (EKS) . In addition, each has a serverless
variant known as AWS Fargate, where AWS entirely operates the underlying container infrastructure on
your behalf.
ECS runs Docker containers with no changes and supports both Windows and Linux containers. Note,
however, that if you choose to use AWS Fargate, then currently only Linux containers are supported, so your
application will need to be based on .NET Core or .NET 5+. If your Docker images are hosted in a third-party
repository, you can still use ECS. Alternatively, you can upload your images to Amazon Elastic Container
Registry (ECR) . As with EC2 virtual machines , you can take advantage of AWS CodeDeploy to minimize
downtime when updating applications by using blue/green deployments, with full support for deployment
monitoring and rollback.
If you’re using Kubernetes , then EKS will be of interest. With EKS , the Kubernetes control plane is run
across multiple AZs, and it automatically detects and replaces unhealthy nodes. As with ECS, Windows is
supported – first for worker nodes and for scheduling Windows containers. It’s also possible to run
Windows and Linux worker nodes together in the same cluster. As you might expect, EKS manages the
availability and scalability of the control plane nodes for you, freeing you from infrastructure management
and allowing you to focus on your application code and deployment topology. We will go deeper into the
container offerings in a later chapter.
Finally, AWS offers a serverless compute service known as AWS Lambda . Lambda enables you to run
your code without provisioning or managing servers – all of that is handled fully by AWS on your behalf.
This allows you to focus entirely on your code, which can run in response to events such as an object being
created in storage, or a request being received on a web API endpoint, and lots more (your code in Lambda
can be triggered from a variety of events across 140 AWS services). You can also configure your code to run
on a cron schedule, you can call it directly from within your own application code, or you can even invoke
functions from the command line. You might find this latter feature useful in automation scripts, for
example.
Note Lambda uses Linux as the underlying operating system host, so your code must target .NET Core
3.1 or .NET 5+; .NET Framework is not supported for writing Lambda functions.
Storage
Now that you have some idea of the range of compute options available to host your application code, let’s
move on to another common need of applications – storage.
When people think of storage in conjunction with AWS, Amazon Simple Storage Service, or S3 as it’s more
commonly referred to, is usually what springs to mind. S3 is a service for object storage in the cloud. We use
the term “object storage” to distinguish it from “file storage ” – it’s important to know that S3 is not a file
system so it doesn’t have a “real” directory structure or well-defined metadata such as the file name and
date it was last modified. Obviously, it can store files, but as far as S3 is concerned, objects are just opaque
blobs of data of varying lengths. To work effectively with S3, the key elements to understand are buckets,
objects, and keys.
Buckets are the top-level organizational unit and are URL addressable – this means that buckets must
conform to DNS name rules and, most importantly, they must have a globally unique name. If I have a bucket
named myapplicationbucket in my account, you cannot have another bucket with the same name in
your account.
Objects exist solely within buckets and represent the data you want to store. Objects can be any size up to
5 terabytes currently. You can add metadata tags to objects, as well as various types of access controls.
Furthermore, it’s possible to add life cycle policies to objects. One example of this would be a policy where
older or less frequently accessed objects are automatically moved to different storage classes to take
advantage of lower pricing.
A key is used to identify the different objects within a bucket. At its core, S3 is a key-value store operating
at massive scale. Keys are probably what cause most people to think S3 is a file system when they first
encounter it – object keys do in fact look like Linux file system paths. For example, consider the following
key: application.images/frontpage/logo.jpg. Notice the / delimiter in the key – this divides the
key into prefixes that resemble, but are not, subfolders. S3 keys are a flat structure, and there is no concept of
sub-buckets or subfolders. However, using prefixes can help infer a logical structure. In fact, the AWS
Management Console and the tools we’ll meet in Chapter 2 and beyond use the prefixes to emulate a file
system when working with S3. Figure 1-4 shows an example of object keys and prefixes in a bucket (note too
that the console uses the term “Folder” for a prefix).
Another random document with
no related content on Scribd:
“‘How stupid!’ said the Gräfinn. ‘At present she is a Madame de St.
Croix, an Englishwoman, nevertheless, and a widow, but not likely to
remain so long.’ And with a mischievous laugh she gave me her
hand as I left the box, bowing to Madame de St. Croix and also to
the Hungarian, who in his happy pre-occupation was perfectly
unconscious of my politeness.
“I saw them again in the crush-room. The Gräfinn had picked up
an attaché to some legation, who put her dutifully into her carriage.
The Hungarian was still completely engrossed with Madame de St.
Croix. I have not yet forgotten the look on his handsome face when
she drove off with her friend. ‘He’s a fool,’ I said to myself; ‘and yet a
woman might well be proud to make a fool of such a man as that.’
“I left London in the middle of the season and thought no more of
Madame de St. Croix. I had seen a pretty picture, I had heard a
strain of sweet music, I had turned over the page of an amusing
romance—there was an end of it.
“The following winter I happened to spend in Vienna. Of course I
went to one of the masked balls of The Redouten-Saal. I had not
been ten minutes in the room when my ears thrilled to the low,
seductive accents of that well-remembered voice. There she was
again, masked, of course, but it was impossible to mistake the slim,
pliant figure, the graceful gestures, the turn of the beautiful head,
and the quiet energy that betrayed itself, even in the small, gloved
hand. She was talking to a well-known Russian magnate less
remarkable for purity of morals than diplomatic celebrity, boundless
extravagance, and devotion to the other sex. To be on terms of
common friendship with such a man was at least compromising to
any lady under sixty years of age; and it is needless to say that his
society was courted and appreciated accordingly.
“Madame de St. Croix seemed well satisfied with her neighbour;
and though in her outward manner the least demonstrative of
women, I could detect through her mask the same cruel glitter in her
dark eyes that had so fascinated me, six months before, in the
Gräfinn’s opera-box. The Russian talked volubly, and she leaned
towards him, as those do who are willing to hear more. Château qui
parle furls its banner, femme qui écoute droops her head. Directly
opposite, looking very tall and fierce as he reared himself against the
doorway, stood Count V——. The Hungarian was pale as death. On
his face, so worn and haggard, so cruelly altered since I saw it last,
was set the stamp of physical pain, and he gnawed the corner of his
brown moustache with that tension of the muscles about the mouth
which denotes a paroxysm bravely kept down. As friends accosted
him in passing, he bowed his head kindly and courteously while his
whole face softened, but it was sad to see how soon the gleam
passed away and the cloud came back, darker and heavier than
before. The man’s heart, you see, was generous, kindly, and full of
trust—such a heart as women like Madame de St. Croix find it an
interesting amusement to break.
“I think he must have made her some kind of appeal; for later in
the evening I observed them together, and he was talking earnestly
in German, with a low pleading murmur, to which I thought few
women could have listened unmoved. She answered in French; and
I was sorry for him when she broke up the colloquy with a little
scornful shrug of her shoulders, observing in a hard, unfeeling tone
not like her usual voice, ‘Que voulez-vous? Enfin, c’est plus fort que
moi!’
“The Russian put her into her sledge, for there was a foot of snow
in the streets, and Count V—— walked home through it, with a smile
on his face and his head up, looking strangely elated, I thought, for a
man, the last strand of whose moorings had lately parted and left
him adrift.
“I had not then learned there is no temporary stimulant so powerful
as despair, no tonic so reviving as a parti pris.
“Next day, lounging into the Chancellerie of the Embassy for my
usual gossip, I found little Hughes, an unpaid attaché (who earned,
indeed, just as much as he received), holding forth with considerable
spirit and energy.
“‘Curse him!’ said this indomitable young Briton. ‘If it had been
swords, I should like to have fought him myself. I hate him! I tell you.
Everybody hates him. And V—— was the best chap between here
and Orsova. He was almost like an Englishman. Wouldn’t he just
have polished him off if they’d had swords. That old muff,
Bergheimer of the Cuirassiers, ought to be hanged. Do you think, if
I’d been his second, I’d have put him up with pistols against the best
shot in Europe?—and at the barrier too! It’s not like at home, you
know. I never knew such a mull as they made of it amongst them.
This cursed Calmuck gets the pull all through, and poor V——, who
had lost his fortune already, loses his lady-love and his life. What a
rum world it is!’
“Here the orator rolled and lit a cigarette, thus affording me a
moment to inquire into the cause of his indignation. I then learned
that, in consequence of a trifling dispute after last night’s ball, a duel
had been fought at daybreak, in the snow, between Count V—— and
a Russian nobleman, in which the former was shot through the heart.
“‘Never got one in at all!’ said Hughes, again waxing eloquent on
his friend’s wrongs. ‘I’ve seen both the seconds since. They were to
walk up to a handkerchief, and the Russian potted him at forty yards
the first step he made. They may say what they like about the row
originating in politics—I know better. They quarrelled because
Madame de St. Croix had left V—— and taken up with this snub-
nosed Tartar. First, she ruined my poor friend. I know all about it. He
hadn’t a rap left; for if she’d asked him for the shirt off his back, he’d
have stripped like beans! Then she broke his heart—the cheeriest,
jolliest, kindest fellow in Europe—to finish up by leaving him for
another man, who kills him before breakfast without a scruple; and if
the devil don’t get hold of her some fine day, why he’s a disgrace to
his appointment, that’s all! and they ought to make him Secretary of
Legation here, or pension him off somewhere and put him out of the
way! Have another cigarette!’
“Ten years afterwards I was sitting in the gardens of the Tuileries,
one fine morning towards the middle of May, wondering, as English
people always do wonder, on a variety of subjects—why the cigars
were so bad in Paris, and the air so exhilarating—why the tender
green leaves quivering over those deep alleys should have a
sunshine of their own besides that which they reflected from above—
why the bonnes and nursery-maids wore clean caps every day—why
the railings always looked as if they had been re-gilt the same
morning, and why the sentry at the gate should think it part of his
duty to leer at every woman who passed, like a satyr?
“Indeed I believe I was almost asleep, when I started in my chair,
and rubbed my eyes to make sure it was not a dream. There, within
ten paces of me, sat Madame de St. Croix, if I was still to call her so,
apparently not an hour older than the first time we met. The face was
even paler, the lips redder, the cruel eyes deeper and darker, but in
that flickering light the woman looked more beautiful than ever. She
was listening quietly and indolently, as of old, to a gentleman who sat
with his back to me, telling his own story, whatever it might be, in a
low, earnest, impressive voice. I raised my hat when I caught her
eye, and she bowed in return politely enough, but obviously without
recognition. The movement caused her companion to turn round,
and in two strides he was by my chair, grasping me cordially by the
hand. He was an old and intimate friend, a colonel in the French
army, by whose side I had experienced more than one strange
adventure, both in Eastern Europe and Asia-Minor—a man who had
served with distinction, of middle age, a widower, fond of society,
field-sports, speculation, and travelling; essentially bon camarade,
but thoroughly French in his reflections and opinions. The last man in
the world, I should have thought, to be made a fool of by a woman.
Well, there he was, her bounden slave! Absurdly happy if she
smiled, miserable when she frowned, ready to fetch and carry like a
poodle, perfectly childish about her, and utterly contemptible. If she
had really cared for him, the temptation must have been irresistible,
and she would have bullied him frightfully. But no, there was always
the same repose of manner, the same careless kindness, the same
melancholy, the same consciousness of an unquestionable
superiority. One of his reasons, he soon confided to me, for being so
fond of her was, that they never had an angry word! For a week or
two I saw a good deal of them. Paris was already empty, and we did
our plays, our Opéra Comique, and our little dinners pleasantly
enough. She was always the same, and I found myself, day by day,
becoming more conscious of that nameless charm about her, which I
should despair of being able to describe. Yet as often as I met the
glance of those deep, dark, unearthly eyes, a shudder crept over me,
such as chills you when you come face to face with a ghost in your
dreams. The colonel, I have said, was devoted to her. He was rarely
absent from her side, but if by chance alone with me, would talk of
her by the hour.
“He had found, he declared, fortunately before he was too old to
appreciate it, the one inestimable treasure the earth contained. He
had cherished his fancies, committed his follies, of course, tout
comme un autre, but he had never experienced anything like this. It
was his haven, his anchorage, his resting-place, and he might glide
down into old age, and on to death, perfectly happy, because
confident, that with her heart and her force of character, she would
never change. He could not be jealous of her. Oh no! She was so
frank, so confiding, so sincere. She, too, passé par là, had told him
so; unlike other women, had confessed to him not only her last, but
her many former attachments. He knew all about poor V——, who
was shot in a duel, and the Russian general, banished to Siberia.
How fortunate she had broken with him before his disgrace,
because, in the loyalty of her nature, she would surely have followed
him into exile, although she never cared for him in her heart, never!
No, nor for any of the others; never had been fairly touched till now.
Him, the colonel, she really did love. He had proved his devotion so
thoroughly (I found out afterwards, though not from him, that my
friend had been fool enough to sacrifice both fortune and profession
for her sake), he was so reliable, she said, so kind, and so good. In
short, he was perfectly happy, and could see no cloud in his horizon,
look which way he would.
“When I left Paris they accompanied me to the railway station; and
the last I saw of them was their two heads very close over a railway
guide, projecting a trip into a lonely part of Switzerland, where they
would have no society but their own.
“Six months afterwards ‘Galignani’ informed me that my friend the
colonel had been reinstated in the French army and appointed to a
regiment of Chasseurs d’Afrique then serving in Algeria, where,
before the Tuileries Gardens were again green, I learned from the
same source he had already solved the great problem in an affair of
outposts with the Khabyles. Long years elapsed, and there were
streaks of grey in my hair and whiskers ere I saw Madame de St.
Croix again. I had heard of her, indeed, at intervals both in London
and Paris. I am bound to say her name was always coupled with
those who were distinguished by birth, talent, or success. She was
very choice, I believe, in the selection of her victims, despising
equally an easy conquest and one of which the ravages could be
readily repaired. The women hated her, the men said she was
charming. For my part I kept out of her way: we were destined to
meet, nevertheless. I had embarked in a Peninsular and Oriental
steamer at Marseilles very much indisposed, and retiring at once to
my berth never quitted it till we were entering the Straits of Buoni-
faccio. Here I came on deck, weak, exhausted, but convalescent,
drinking in the sunshine and the scenery with that thirst for the
beautiful which becomes so fierce after the confinement of recent
illness. I literally revelled in the Mediterranean air, and basked in the
warmth of those bright colours so peculiar to the shores of that
summer sea. I was approaching middle age; I had ventured body
and mind freely enough in the great conflict; and yet, I thank heaven,
had hitherto been spared the crushing sorrow that makes a mockery
of the noblest and purest enjoyments of earth, causing a man to turn
from all that is fairest in sight and sense and sound with the sickness
of a dead hope curdling at his heart. But then I had kept clear of
Madame de St. Croix.
“When my eyes were at last sated with the gaudy hues of the
coast and the golden glitter of the water, I was a little surprised to
see that lady sitting within three paces of me reading a yellow-bound
French novel. Great heaven! what was the woman’s secret? She
looked younger than ever! Even in the searching glare of a southern
noon not a line could be detected on the pure, pale forehead, not a
crease about the large, wistful, glittering eyes. That she was gifted
with perennial youth I could see for myself; that she was dangerous
even to the peace of a grey-haired man, I might have found out to
my cost had our voyage been retarded by contrary winds or any
such unavoidable delay, for she was good enough to recognise me
on this occasion, and to give me a large share of her conversation
and companionship. Thus it was I learned to own the spell under
which so many had succumbed, to appreciate its power, not to
understand, far less describe, its nature. Fortunately for me, ere its
work could be completed, we arrived at Athens, and at Athens lay a
trim, rakish-looking English yacht, with her ensign flying and her
foretopsail loosed, waiting only the steamer’s arrival to spread her
wings and bear off this seductive sorceress to some garden of
paradise in the Egean Sea.
“The owner of the yacht I had often heard of. He was a man
remarkable for his enterprise and unfailing success in commerce as
for his liberality, and indeed extravagance, in expenditure. He chose
to have houses, pictures, horses, plate, everything of the best, was
justly popular in society, and enormously rich.
“I never asked and never knew the port to which that yacht was
bound. When we steamed out of the harbour she was already hull-
down in the wake of a crimson sunset that seemed to stain the
waters with a broad track of blood; but I saw her sold within eighteen
months at Southampton, for her late owner’s name had appeared in
the ‘Gazette,’ and the man himself, I was told, might be found,
looking very old and careworn, setting cabbages at Hanwell,
watching eagerly for the arrival of a lady who never came.
“You may believe I thought more than once of the woman whose
strange destiny it had been thus to enslave generation after
generation of fools, and to love whom seemed as fatal as to be a
priest of Aricia or a favourite of Catharine II. Nevertheless, while time
wore on, I gradually ceased to think of her beauty, her heartlessness,
her mysterious youth, or her magic influence over mankind.
Presently, amongst a thousand engrossing occupations and
interests, I forgot her as if she had never been.
“I have driven a good many vehicles in my time, drags, phaetons,
dogcarts, down to a basket-carriage drawn by a piebald pony with a
hog-mane. Nay, I once steered a hansom cab up Bond Street in the
early morning, freighted with more subalterns than I should like to
specify of her Majesty’s Household Troops, but I never thought I
should come to a bath chair!
“Nevertheless I found myself at last an inside passenger of one of
these locomotive couches, enjoying the quiet and the air of the
gardens at Hampton Court in complete and uninterrupted solitude.
The man who dragged me to this pleasant spot having gone to ‘get
his dinner,’ as he called it, and the nursery-maids, with their
interesting charges, having retired from their morning, and not yet
emerged for their afternoon stroll, I lay back, and thought of so many
things—of the strength and manhood that had departed from me for
ever; of the strange, dull calm that comes on with the evening of life,
and contents us so well we would not have its morning back if we
could; of the gradual clairvoyance that shows us everything in its true
colours and at its real value; of the days, and months, and years so
cruelly wasted, but that their pleasures, their excitements, their sins,
their sorrows, and their sufferings, were indispensable for the great
lesson which teaches us to see. Of these things I thought, and
through them still, as at all times, moved the pale presence of an
unforgotten face, passing like a spirit, dim and distant, yet dear as
ever, across the gulf of years—a presence that, for good or evil, was
to haunt me to the end.
“Something in the association of ideas reminded me of Madame
de St. Croix, and I said to myself, ‘At last age must have overtaken
that marvellous beauty, and time brought the indomitable spirit to
remorse, repentance, perhaps even amendment. What can have
made me think of her in a quiet, peaceful scene like this?’
“Just then a lady and gentleman crossed the gravel walk in front of
me, and took their places on a seat under an old tree not a dozen
yards off. It was a lovely day in early autumn; the flowers were still
ablaze with the gaudiest of their summer beauty, the sky was all
dappled grey and gold, earth had put on the richest dress she wears
throughout the year; but here and there a leaf fell noiseless on the
sward, as if to testify that she too must shed all her glories in due
season, and yield, like other beauties, her unwilling tribute to decay.
“But there was nothing of autumn in the pair who now sat opposite
my couch, chatting, laughing, flirting, apparently either ignoring or
disregarding my proximity. The man was in all the bloom and beauty
of youth; the woman, though looking a few years older, did not yet
seem to have attained her prime. I could scarcely believe my eyes!
Yes, if ever I beheld Madame de St. Croix, there she sat with her
fatal gaze turned on this infatuated boy, leading him gradually,
steadily, surely, to the edge of that chasm into which those who
plunged came to the surface nevermore. It was the old story over
again. How well I remembered, even after such an interval, the
tender droop of the head, the veiling eyelashes, the glance so
quickly averted, yet, like a snapshot, telling with such deadly effect;
the mournful smile, the gentle whisper, the quiet confiding gesture of
the slender hand, all the by-play of the most accomplished and most
unscrupulous of actresses. There was no more chance of escape for
her companion than for a fisherman of the North Sea, whose skiff
has been sucked into the Maëlstrohm, with mast unshipped and oars
adrift half a mile astern. By sight, if not personally, I then knew most
of the notabilities of the day. The boy, for such I might well call him in
comparison with myself, seemed too good for his fate, and yet I saw
well enough it was inevitable. He had already made himself a name
as a poet of no mean pretensions, and held besides the character of
a high-spirited, agreeable, and unaffected member of society. Add to
this, that he was manly, good-looking, and well-born; nothing more
seemed wanting to render him a fit victim for the altar at which he
was to be offered up. Like his predecessors, he was fascinated. The
snake held him in her eye. The poor bird’s wings were fluttering, its
volition was gone, its doom sealed. Could nothing save it from the
destroyer? I longed to have back, if only for a day, the powers which
I had regretted so little half-an-hour ago. Weak, helpless, weary, and
worn-out, I yet determined to make an effort, and save him if I could.
“They rose to go, but found the gate locked through which they
had intended to pass. She had a way of affecting a pretty wilfulness
in trifles, and sent him to fetch the key. Prompt to obey her lightest
wish, he bounded off in search of it, and following slowly, she passed
within two paces of my chair, bending on its helpless invalid a look
that seemed to express far less pity for his condition than a grudging
envy of his lot. I stopped her with a gesture that in one more able-
bodied would have been a bow, and, strange to say, she recognised
me at once. There was not a moment to lose. I took courage from a
certain wistful look that gave softness to her eyes, and I spoke out.
“‘We shall never meet again,’ I said; ‘we have crossed each
other’s paths at such long intervals, and on such strange occasions,
but I know this is the last of them! Why time stands still for you is a
secret I cannot fathom, but the end must come some day, put it off
however long you will. Do you not think that when you become as I
am, a weary mortal, stumbling with half-shut eyes on the edge of an
open grave, it would be well to have one good deed on which you
could look back, to have reprieved one out of the many victims on
whom you have inflicted mortal punishment for the offence of loving
you so much better than you deserve? Far as it stretches behind
you, every footstep in your track is marked with sorrow—more than
one with blood. Show mercy now, as you may have to ask it
hereafter. Life is all before this one, and it seems cruel thus to blast
the sapling from its very roots. He is hopeful, trustful, and fresh-
hearted—spare him and let him go.’
“She was fitting the glove on her faultless little hand. Her brow
seemed so calm, so soft and pure, that for a moment I thought I had
conquered, but looking up from her feminine employment, I
recognised the hungry glitter in those dark, merciless eyes, and I
knew there was no hope.
“‘It is too late,’ she answered, ‘too late to persuade either him or
me. It is no fault of mine. It is fate. For him—for the others—for all of
us. Sometimes I wish it had not been so. Mine has been an unhappy
life, and there seems to be no end, no resting-place. I can no more
help myself than a drowning wretch, swept down by a torrent; but I
am too proud to catch at the twigs and straws that would break off in
my hand. I would change places with you willingly. Yes—you in that
bath chair. I am so tired sometimes, and yet I dare not wish it was all
over. Think of me as forbearingly as you can, for we shall not cross
each other’s path again.’
“‘And this boy?’ I asked, striving to detect something of
compunction in the pitiless face that was yet so beautiful.
“‘He must take his chance with the rest,’ she said. ‘Here he comes
—good-bye.’
“They walked away arm-in-arm through the golden autumn
weather, and a chill came into my very heart, for I knew what that
chance was worth.
“A few months, and the snow lay six inches deep over the grave of
him whose opening manhood had been so full of promise, so rich in
all that makes youth brightest, life most worth having; while a woman
in deep mourning was praying there, under the wintry sky; but this
woman was his mother, and her heart was broken for the love she
bore her boy.
“His death had been very shocking, very sudden. People talked of
a ruptured blood-vessel, a fall on his bedroom floor, a doctor not to
be found when sent for; a series of fatalities that precluded the
possibility of saving him; but those who pretended to know best
affirmed that not all the doctors in Europe could have done any
good, for when his servant went to call him in the morning he found
his master lying stark and stiff, having been dead some hours. There
was a pool of blood on his carpet; there were ashes of burnt letters
in his fireplace; more, they whispered with meaning shrugs and
solemn, awe-struck faces—
“The African Magician never minded all their scoffs and holloaings,
or all they could say to him, but still cry’d Who’ll change old Lamps for
new ones? which he repeated so often about the Princess
Badroulbondour’s Palace, that that Princess, who was then in the Hall
with the four-and-twenty Windows, hearing a Man cry something, and
not being able to distinguish his Words, by reason of the holloaing of
the Mob about him, sent one of her Women Slaves down to know
what he cry’d.
“The Slave was not long before she return’d, and ran into the Hall,
laughing so heartily, that the Princess could not forbear herself. ‘Well,
Gigler,’ said the Princess, ‘will you tell me what you laugh at?’ ‘Alas!
Madam,’ answered the Slave, laughing still, ‘who can forbear laughing
to see a Fool with a Basket on his Arm, full of fine new Lamps, ask to
change them for old ones, which makes the Children and Mob make
such a Noise about him?’”
What a fool they thought him, and no wonder. Yet surely a magician
need not come all the way from Africa to teach the public this
strange rate of exchange. In Europe, Asia, and America too, as far
as it has yet been colonised, such one-sided bargains are made
every day.
Old lamps for new, kicks for halfpence—“Heads I win, Tails you
lose”—such are the laws of equity by which man deals with his
neighbour; and so the contest goes on, if, indeed, as Juvenal says,
that can be called a contest—
The slave of the princess with the long name had passed more of
her life in the palace than the streets, or she would not have found
the magician’s cry so strange: would have felt uncomfortably
conscious that the day might come when she, too, would barter new
lamps for old, perhaps humbly on her knees, entreating permission
to make the unequal exchange. In all the relations of life, but chiefly
in those with which the affections are concerned, we constantly see
gold for silver offered with both hands.
That “it is better to give than to receive” we have Scriptural warrant
for asserting. That—