Ben Oram
Quick notes on tech, AWS, .NET & containers
| 1 min read
The dig command is incredibly useful for testing DNS. I use this all the time from Mac and Linux. Windows users, nslookup
may provide similar features, but you can always run Linux with WSL
Retrieve nameservers for domain
dig NS oram.co
And the address(es) for a particular server
dig oram.co
Force the resolution through Google DNS
dig oram.co @8.8.8.8
Pretent do be from somewhere else
Since Google DNS supports Client Subnet/EDNS we can pretend we are from somewhere else in the world. Let’s try Italy
dig oram.co +subnet=159.122.168.0/24 @8.8.8.8
Reverse DNS
These PTR records don’t always exist, but sometimes provide useful information
> dig -x 99.86.162.73
...
Response: "server-99-86-162-73.mxp64.r.cloudfront.net"
...
mxp64 in the record gives some confirmation that the IPs returned are from CloudFront Milan
References
| 1 min read
I haven’t had a chance to use Terraform lately, and was pleasantly surprised that you can now specify default tags for nearly all resources at the provider level.
provider "aws" {
alias = "ohio"
region = "us-east-2"
default_tags {
tags = {
Automation = "Terraform"
Repo = "Infrastructure.Network"
Project = "Sandbox"
Terraform_Workspace = "${var.ATLAS_WORKSPACE_NAME}"
}
}
}
References
| 1 min read
AWS Copilot currently doesn’t have support for leveraging docker buildx
to allow for multi-architecture docker builds. So the arm64 images created on your M1 Mac with Apple Silicon will not work on AWS Fargate which is based on amd64 today. The error I was seeing in the CloudWatch logs for my load balanced web services was…
standard_init_linux.go:219: exec user process caused: exec format error
As a workaround, specify an arm64 version/tag of your "from"
image in your Dockerfile. While this won’t create a multi-architecture image, it will force the creation of an images that will work with AWS Fargate.
An example is below for NGINX.
FROM amd64/nginx:alpine
EXPOSE 80
COPY . /usr/share/nginx/html
| 1 min read
I ran into an issue with my EC2 macOS setup where running docker login
from SSH resulted in the following error
Error saving credentials: error storing credentials - err: exit status 1, out: `User interaction is not allowed.`
Working around the issue involved running the following in my SSH session before running docker login
security unlock-keychain ${HOME}/Library/Keychains/login.keychain-db
In subsequent sessions you may see an unknown: Authentication is required
error. To avoid, run the unlock-keychain command again.
| 2 min read
I had a chance this week to run macOS on AWS EC2 . First impression, it is expensive and boot/reboot times are very slow. In my case I wanted some dev boxes to hand over to an engineer and I didn’t want to pull out my credit card. I was able to spin up an EC2 instance for each of the 3 most recent versions of MacOS in less than 30 minutes.
If you want to use VNC/Screen Sharing, you will need to run the following two commands to set a password and enable remote management.
# Set pasword
sudo passwd ec2-user
# Enable VNC access
sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart \
-activate -configure -access -on \
-restart -agent -privs -all
# Fixup the disk to make the full EBS volume available
PDISK=$(diskutil list physical external | head -n1 | cut -d" " -f1)
APFSCONT=$(diskutil list physical external | grep "Apple_APFS" | tr -s " " | cut -d" " -f8)
yes | sudo diskutil repairDisk $PDISK
sudo diskutil apfs resizeContainer $APFSCONT 0
Overall MacStadium is much more cost-effective, they know Macs and they have M1. But if you want something running within AWS, your VPC, or in regions where MacStadium doesn’t yet exist and you are ok with Intel, Mac on EC2 works just fine.
References
| 1 min read
Where possible, leverage the Alpine docker image for ASP.NET Code. Out of the box, the image is more secure than the default Debian buster image, and the Alpine images are a bit smaller.
docker pull mcr.microsoft.com/dotnet/aspnet:5.0-alpine
| 1 min read
| 1 min read
MinVer is a tool that you can use to generate a version number that is based on your git repository history.
The tool does require .NET, but there is no requirement that you develop your app in .NET
Within your GitHub Action workflow, you can run MinVer to generate the version number and store it in an environment variable for later use.
GitHub checkout and set fetch depth appropriately
- uses: actions/checkout@v2
with:
fetch-depth: 0
Retrieve version and store in env
- name: Set APP_VERSION based on repo w/MinVer
run: |
dotnet tool install -g minver-cli -v q
APP_VERSION=`minver`
echo "Adding version to GITHUB_ENV: APP_VERSION=$APP_VERSION"
echo "APP_VERSION=$APP_VERSION" >> $GITHUB_ENV
Example: Reference the variable in later steps
- name: Publish artifact to GitHub
uses: softprops/action-gh-release@v1
with:
files: artifacts.zip
tag_name: ${{ env.APP_VERSION }}
env:
GITHUB_TOKEN: ${{ github.token }}
References
| 1 min read
When launching a Windows instance via an AWS AMI, a password is automatically generated, and encrypted using the keypair associated with the instance.
As a best practice, this generated password should be changed. Many folks choose to create a new local administrator account with a unique username, and additionally many teams choose to join the instance to a domain, and let the domain handle authentication.
Finally, starting with Windows Server 2016, AMIs maintained by AWS are configured to allow generated passwords to expire.
References
| 1 min read
Storing secrets in source control is something to avoid. Secrets stored in git can easily be inadvertently shared though a fork or push to a public origin, and they are easily found in-bulk by anyone with read access to the repo.
For .NET developers that need secrets on their local machine, leverage dotnet user-secrets
to store secrets that can be easily retrieved through configuration. For Mac users, secrets are stored in ~/.microsoft/usersecrets
Prereq
From your project’s source directory, run this command. It only needs to be run once.
dotnet user-secrets init
Set a secret from command-line/terminal
From your project’s source directory
dotnet user-secrets set "db:password" "VerySecurePassword!0!"
Retrieve secret in code
var password = Configuration["db:password"];
References
| 1 min read
AWS managed keys are rotated automatically every 3 years. For these keys, there is not a way to manually trigger a key rotation, or change the rotation schedule. These are AWS Managed Keys after all :)
Customer managed keys in KMS have more flexibility. While key rotation is not required, they can be configured automatically rotate every year. In addition, key rotation may be triggered manually, or a rotation can be triggered manually or through API.
To enable manual rotation, make sure that all key references are through an alias. Aliases enable manual key rotation by allowing you to point the alias to a new key at any time.