A Shiny New Vuejs v3 Web App Using & Deployed to Amplify/AppSync/Cognito

No cruft, let’s just start.

Prerequisites

These details plus yarn and a few other notes are available and derived from the Amplify Docs located here. What I’ve done is take those docs and add some specific details and information for this happy path. It includes additional references for the steps I took, and specifically what I’m running this on for this particular tutorial. As noted below, there is a section where this deviates from those steps and I get into next steps beyond the initial setup of the app, Amplify, and AppSync. I’ll note that part of this tutorial, or you can navigate directly to that part with this anchor thatPartiDeviate.

You’ll need the following for this specific tutorial. If you’re acclimate to various OSes and their respective needs around this software, you can get this sorted yourself and it’s mostly the same for each OS, but for this tutorial I’m rolling with MacOS Big Sur v11.6.2.

  • Your OS, as stated mine is Big Sur for this tutorial.
  • git. Probably any version released in the last decade will work just fine.
  • Node.js. Probably anything since v14 would work great but this tutorial is written against v16.11.1. As of this writing the LTS is 16.13.1 and current is 17.3.0.
  • Vue.js v3. For this tutorial I’m on a version of the v3 Preview. For the CLI a quick yarn global add @vue/cli does the job.
  • Amplify CLI. Version for this tutorial is 7.6.5. One can NPM install it with 🤙🏻 npm install -g @aws-amplify/cli or get it via cURL 👍🏻 curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL and of course, Windows has gotta be Windowsy with 😑 curl -sL https://aws-amplify.github.io/amplify-cli/install-win -o install.cmd && install.cmd.

A few first steps that only need done once. If you’ve already setup your amplify cli then this isn’t needed a second time.

First, get the Vue.js v3 base app skeleton running.

vue create mywhateverproject

Issuing this command will then provide prompts to select Vue.js v3 Preview (or likely just v3 when fully released, which will come along with other tooling as needed). Once this is done, following the standard steps of navigating into the directory cd myWhateverProejct , then executing the yarn command and finally yarn serve --open will open up the running web app in your default browser.

Next initialize the Vue.js App as an Amplify Project and get some defaults set and accepted. Executing amplify init and accepting the defaults will get this done. As displayed when done the Vue.js v3 App will now have multiple defaults and respective items selected.

Amplify Init

With the core Amplify folder and settings set, adding the Amplify libraries for use in user interface components is next up.

yarn add aws-amplify @aws-amplify/ui-components

Now navigate into the src/main.js file and add the Amplify and initial configure in the code, that will do the actual initialization execution when the app launches.

This is replacing this code…

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

with this code.

import { createApp } from 'vue'
import App from './App.vue'
import Amplify from 'aws-amplify';
import aws_exports from './aws-exports';
import {
	applyPolyfills,
	defineCustomElements,
} from '@aws-amplify/ui-components/loader';

Amplify.configure(aws_exports);
applyPolyfills().then(() => {
	defineCustomElements(window);
});
createApp(App).mount('#app')

This completes the steps we need for a running application. To cover full stack let’s cover the back end build out and schema construction. Then after that I’ll delve into thatPartiDeviate. Next up is getting the Amplify elements added.

npm install aws-amplify @aws-amplify/ui-components

Before even launching I went ahead and added the back end and database, GraphQL API, and related collateral.

amplify add api
amplify add api

Notice in the screenshot, once I selected to edit the schema now, it simply opened the file in the editor of my choice, which is Visual Studio Code for this tutorial. Since I’m executing this from the terminal in Visual Studio Code it simply opened the file in the active editor that I’m in, win win! The file that is opened by default for the schema includes the following GraphQL schema code.

# This "input" configures a global authorization rule to enable public access to
# all models in this schema. Learn more about authorization rules here: https://docs.amplify.aws/cli/graphql/authorization-rules

input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!

type Todo @model {
	id: ID!
	name: String!
	description: String
}

For now, I’ll just leave the comment, the input AMPLIFY and the Todo type just as it is. It’s important to note that this schema.graphql file is located at app/amplify/backend/schema.graphql. I’ll come back to this later in thatPartiDeviate.

Next I want to push the app, api, and backend to Amplify and AppSync.

amplify push

During this phase a lot of things happen. The GraphQL Schema is turned into an API and this is deployed along with the Database is deployed to DynamoDB.

To get the backend shipped, i.e. deployed to AppSync, issue the amplify push command. Again, following through with the default choices. If amplify console is issued just after this a review of the API can be made.

amplify push

Ok, now it’s auth time. Adding that is somewhat mind boggling minimal, just amplify add auth. For this I chose Default config, then Username for the way users sign in, and then the No, I am done option followed by issuing another amplify push, confirmed that and let it go through its process.

After this next steps included adding the following code to the App.vue file to get the initial interations, security and related things into place for the todo app. Again, I feel it important to note that I’ll be changing all of this later in the post here. But it’s a solid way to start building an application and then looping back around after it is up and running, deployed before moving on to next steps.

<template>
  <amplify-authenticator>
    <div id="app">
      <h1>Todo App</h1>
      <input type="text" v-model="name" placeholder="Todo name">
      <input type="text" v-model="description" placeholder="Todo description">
      <button v-on:click="createTodo">Create Todo</button>
      <div v-for="item in todos" :key="item.id">
        <h3>{{ item.name }}</h3>
        <p>{{ item.description }}</p>
      </div>
    </div>
    <amplify-sign-out></amplify-sign-out>
  </amplify-authenticator>
</template>

<script>
import { API } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';

export default {
  name: 'App',
  async created() {
    this.getTodos();
    this.subscribe();
  },
  data() {
    return {
      name: '',
      description: '',
      todos: []
    }
  },
  methods: {
    async createTodo() {
      const { name, description } = this;
      if (!name || !description) return;
      const todo = { name, description };
      this.todos = [...this.todos, todo];
      await API.graphql({
        query: createTodo,
        variables: {input: todo},
      });
      this.name = '';
      this.description = '';
    },
    async getTodos() {
      const todos = await API.graphql({
        query: listTodos
      });
      this.todos = todos.data.listTodos.items;
    },
    subscribe() {
      API.graphql({ query: onCreateTodo })
        .subscribe({
          next: (eventData) => {
            let todo = eventData.value.data.onCreateTodo;
            if (this.todos.some(item => item.name === todo.name)) return; // remove duplications
            this.todos = [...this.todos, todo];
          }
        });
    }
  }
}
</script>

With this added now I could run yarn serve and check out the site. At this point I signed up just to have an account to use and added a todo item. Everything worked swimmingly at this point!

The final step before getting into a proper deviation from this todo example involves now getting the app properly published to Amplify. This is done by executing amplify add hosting. Accept Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment) and Manual deployment when prompted. Now, finally, issue the command amplify publish.

Boom, the todo app site is live!

thatPartWhereiDeviate

Now it’s time to get into the nitty gritty of deviations from the easy path!

New GraphQL Schema!

My schema that I want to add is around building out collections for a number of data sets. The first one is a data set that I routinely talk about on a regular basis, and yes, it is indeed centered around trains! If you’re uninterested in the trains part and schema and more interested in the changes skip down to the "Deploying The Changes" section of the post.

Alright, describing the data model that I want to have and use will start with the minimal part of just having a list of railroads. This would be a list, or more specifically a table of railraods, that we can add railroads to and collect peripheral information about them. For this table I’ll add the following fields, AKA columns of data to store. I would want to collect the following for a railroad:

  1. railroad name
  2. wikipedia URI
  3. map URI
  4. peripheral details of an unstructured nature
  5. founding year, month, and day of the railroad
  6. record stamp

In addition, I want to keep a list of trains – specifically named trains – that each railroad operates. This data would include:

  1. train name
  2. active – yes / no
  3. peripheral details of an unstructured type
  4. wikipedia URI
  5. route map URI
  6. time table URI
  7. train URI – i.e. like a website or something that might be dedicated to the particular train.
  8. record stamp

Deploying The Changes

Now it is time to deploy these additional database and schema changes. One of the easiest ways to make these changes is to use Amplify Studio, which has a great section for data modeling, which in turn puts together and ensures your schema is usable. Then it will enable you to deploy that new schema with changes to the database and the active service!

Navigate to the interface from here.

Opening Amplify Studio with the Launch Studio button.

Once I navigated to the interface I built out the additional tables like this.

Building a Schema with Amplify Studio

Then just click on Save and Deploy and then Deploy on the following modal dialog and Amplify will deploy the AppSync schema changes.

Amplify Studio Save & Deploy

With that deployed, in the same Amplify Studio interface I then clicked on the GraphQL API tab section and then on the Resource name for mywahteverproject to open up the AppSync Console.

Opening an AppSync Schema.

Further down in the schema toward the bottom I can then find and confirm my types are in and ready for use. The Todo type is still there, since I didn’t need to really remove it yet and it acts as a good working reference. But more importantly you can see the other types and the correlative relationship that was added via the Amplify data modeling interface.

...more schema

type Todo @aws_iam
@aws_api_key {
	id: ID!
	name: String!
	description: String
	_version: Int!
	_deleted: Boolean
	_lastChangedAt: AWSTimestamp!
	createdAt: AWSDateTime!
	updatedAt: AWSDateTime!
}

type Train @aws_iam
@aws_api_key {
	id: ID!
	train_name: String!
	active: Boolean!
	peripheral_details: AWSJSON
	wikipedia_uri: AWSURL
	route_map_uri: AWSURL
	timetable_uri: AWSURL
	train_uri: AWSJSON
	record_stamp: AWSTimestamp
	_version: Int!
	_deleted: Boolean
	_lastChangedAt: AWSTimestamp!
	createdAt: AWSDateTime!
	updatedAt: AWSDateTime!
	railroads(
		railroadID: ModelIDKeyConditionInput,
		filter: ModelRailroadTrainFilterInput,
		sortDirection: ModelSortDirection,
		limit: Int,
		nextToken: String
	): ModelRailroadTrainConnection
		@aws_iam
@aws_api_key
}

type Railroad @aws_iam
@aws_api_key {
	id: ID!
	railroad: String!
	wikipedia_ur: AWSURL
	map_uri: AWSURL
	peripheral_details: AWSJSON
	founding_year: Int
	founding_month: Int
	founding_day: Int
	record_stamp: AWSTimestamp
	_version: Int!
	_deleted: Boolean
	_lastChangedAt: AWSTimestamp!
	createdAt: AWSDateTime!
	updatedAt: AWSDateTime!
	RailroadTrains(
		trainID: ModelIDKeyConditionInput,
		filter: ModelRailroadTrainFilterInput,
		sortDirection: ModelSortDirection,
		limit: Int,
		nextToken: String
	): ModelRailroadTrainConnection
		@aws_iam
@aws_api_key
}

...more schema

The relationship can be seen via the object connections here in the ModelRailroadTrainConnection and the keys associated.

Next steps to get this updated in the local repository from these changes that were just made out of sync via the Amplify Studio interface requires two quick commands, both of which are displayed on the screen of the GraphQL interface in the studio. It’s best to get the command, as it’ll have the appId already included in a copypasta option on the screen, which looks like this.

amplify pull --appId app-id-which-is-in-studio --envName dev

Executing that will get everything updated and pull in the remote GraphQL Schema to the local schema.graphql file located in the amplify/backend/api/ location. Next run this command.

amplify update api

This will update everything to synchronize things, which will also prompt me for code generation so that I can have the client side code ready for use whenever I build out the user interface later.

Next Up

Some of the things I’ll cover in the next article, as I continue this effort, is what has been done with all these steps from a project perspective. As one can see, some things might be a little confusing at this point, for example the above schema shown in AppSync, but after the synchronization if you look at the schema.graphql file locally it shows this.

type Train @model @auth(rules: [{allow: public}]) {
  id: ID!
  train_name: String!
  active: Boolean!
  peripheral_details: AWSJSON
  wikipedia_uri: AWSURL
  route_map_uri: AWSURL
  timetable_uri: AWSURL
  train_uri: AWSJSON
  railroads: [RailroadTrain] @connection(keyName: "byTrain", fields: ["id"])
  record_stamp: AWSTimestamp
}

type Railroad @model @auth(rules: [{allow: public}]) {
  id: ID!
  railroad: String!
  wikipedia_ur: AWSURL
  map_uri: AWSURL
  peripheral_details: AWSJSON
  founding_year: Int
  founding_month: Int
  founding_day: Int
  record_stamp: AWSTimestamp
  RailroadTrains: [RailroadTrain] @connection(keyName: "byRailroad", fields: ["id"])
}

type Todo @model @auth(rules: [{allow: public}]) {
  id: ID!
  name: String!
  description: String
}

type RailroadTrain @model(queries: null) @key(name: "byRailroad", fields: ["railroadID", "trainID"]) @key(name: "byTrain", fields: ["trainID", "railroadID"]) @auth(rules: [{allow: public}]) {
  id: ID!
  railroadID: ID!
  trainID: ID!
  railroad: Railroad! @connection(fields: ["railroadID"])
  train: Train! @connection(fields: ["trainID"])
}

Obviously this is very different than what is shown from one place to another, so I’ll discuss this and other things. So subscribe (over on the right side of the blog), follow (@Adron), and you’ll be updated on the next post when it’s published.

SITREP (Situational Report)

Alright, what have I wrapped up so far? Here’s a bullet list of the things finished:

  • Vue.js App created.
  • Vue.js Form put together for todo entries.
  • Authentication added with Cognito.
  • An AppSync GraphQL created and published.
  • Additional types added to the AppSync GraphQL API.
  • Updates and code regenerated for our API.

What’s next to do? This is the short list, there will be after that, much more to do!

  • Get the Vue.js app spified up, get some nice design put together for it, add some reasonable CSS, graphics, etc to make the interface pop. But above all, it needs to feel usable and be usable.
  • Add the forms for each of the respective interfaces to manipulate the data. This could amount to lots of different things, adding navigation, routing, and other menues and the like.
  • Add screens that can provide some nice reports on the data that I’m putting together. For example, it’d be nice to get a list of the actual named trains or the railroads and have their images, maps, and other respective elements shown.

…and the list goes on. Until next session, enjoy your thrashing code! 🤘🏻

References

AWS Amplify Release, GraphQL, and Recent Curated Links

This release kicked off this week in time for re:Invent and I put together a quick write up. Any questions, feel free to ping me via my contact form or better yet, just pop a question at me via the Twitters @Adron.

Authenticator

Amplify’s new Authenticator

Docs here

The new authenticator is a component that adds a full authentication flow for your app with coordinated boilerplate. This covers vue.js, angular, and react frameworks. The component has a customizable UI (as you’d expect), includes social logins for Google, Facebook, Apple, and Amazon. The initial setup is zero-configuration, and does have password manager support, along with show/hide confirm password forms.

The zero configuration works based on your Amplify CLI setup. To use this component grab the latest version of Amplify 6.4.0.

npm

npm install -g @aws-amplify/cli@latest

yarn

yarn global add @aws-amplify/cli@latest

Once that runs it will update your aws-exports.js with the latest backend configuration for the Authenticator. So, zero configuration you have to add, but there’s configuration back there if you need to or want to dig in.

There is then an initial state for the component that sets a user up for sign in, sign up, or resetting their password. You might start with some code to get the component in your page like this.

export default function App() {
  return (
    <Authenticator>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

Then to set the initial state add the following parameter.

export default function App() {
  return (
    <Authenticator initialState="signUp">
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

Setting many of the other options to your needs includes adding additional parameters to the Authenticator component like;

Social providers

export default function App() {
  return (
    <Authenticator socialProviders={['amazon', 'apple', 'facebook', 'google']}>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

Sign up attributes

export default function App() {
  return (
    <Authenticator signUpAttributes={[]}>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

Login mechanisms

export default function App() {
  return (
    <Authenticator loginMechanisms={['username']}>
      {({ signOut, user }) => (
        <main>
          <h1>Hello {user.username}</h1>
          <button onClick={signOut}>Sign out</button>
        </main>
      )}
    </Authenticator>
  );
}

There are lots of other features too, give the docs a quick read for the full details. For more details on the overall authentication worflow check out these docs.

In-App Messaging

In App Messaging

This library is, sadly for my vue.js app, only available for react native. A quick install will get you started.

npm install -E aws-amplify@in-app-messaging aws-amplify-react-native@in-app-messaging amazon-cognito-identity-js @react-native-community/netinfo @react-native-async-storage/async-storage @react-native-picker/picker react-native-get-random-values react-native-url-polyfill

Then install pod dependencies for iOS.

pod install

An example looks like this.

import 'react-native-get-random-values';
import 'react-native-url-polyfill/auto';

import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);

Then import the awsconfig vis aws.exports.js.

import Amplify from 'aws-amplify';
import awsconfig from './src/aws-exports';

Amplify.configure(awsconfig);

Then integrate the Amplify React Native UI component if your app’s root component.

import {
  InAppMessagingProvider,
  InAppMessageDisplay
} from 'aws-amplify-react-native';

const App = () => (
  <InAppMessagingProvider>
    {/* Your application */}
    <InAppMessageDisplay />
  </InAppMessagingProvider>
);

re: from the docs, here’s an app.jsx example.

import React, { useEffect } from 'react';
import { SafeAreaView, Button } from 'react-native';
import { Analytics, Notifications } from 'aws-amplify';
import {
  InAppMessagingProvider,
  InAppMessageDisplay
} from 'aws-amplify-react-native';

const { InAppMessaging } = Notifications;

// To display your in-app message, make sure this event name matches one you created
// in an In-App Messaging campaign!
const myFirstEvent = { name: 'my_first_event' };

const App = () => {
  useEffect(() => {
    // Messages from your campaigns need to be synced from the backend before they
    // can be displayed. You can trigger this anywhere in your app. Here we are
    // syncing just once when this component (your app) renders for the first time.
    InAppMessaging.syncMessages();
  }, []);

  return (
    <SafeAreaView>
      <InAppMessagingProvider>
        {/* This button has an example of an analytics event triggering the in-app message. */}
        <Button
          onPress={() => {
            Analytics.record(myFirstEvent);
          }}
          title="Record Analytics Event"
        />

        {/* This button has an example of an In-app Messaging event triggering the in-app message.*/}
        <Button
          onPress={() => {
            InAppMessaging.dispatchEvent(myFirstEvent);
          }}
          title="Send In-App Messaging Event"
        />

        <InAppMessageDisplay />
      </InAppMessagingProvider>
    </SafeAreaView>
  );
};

export default App;
In App Messaging

Custom Resources w/ AWS CDK or Cloudformation

René (@renebrandel) wrote a blog post on extending the Amplify backend with custom AWS resources using AWS CDK or CloudFormation. The post is avilable here but I’ll give you a quick summary.

The new CLI comand amplify add custom will get almost any of the AWS services added to an Amplify backend. The core tech here is backed with AWS Cloud Development Kit (CDK) or CloudFormation. For example if you want to pull in AWS SNS as custom resource, this is a very quick and concise way to do just that.

Again, check out René’s post to really get into it and check out some of the possibilities.

Overriding Amplify Backend Resources with CDK

Amplify sets up various capabilities out of the box in many situations such as project-level IAM roles, Cognito Auth, or S3 resources. As with the previous section, this one I’ll keep short as René (@renebrandel) has wrote a great blog post about this capability too titled “Override Amplify-generated backend resources using CDK“. If you’re interesting in nixing (overriding) any of these features and using another choice, this is your go to.

Prototype a Fullstack App without an AWS Account

Not specifically related to the release, this capability that Christian Nwamba AKA Codebeast wrote up in a blog post will show you how to do just that. The docs focused around what he details in the post are avilable here.

GraphQL Transformer v2

This I saved for last, it’s in my wheelhouse after all. Some of the features of the new v2 drop include; deny-by-default auth, lambda authorizer, customizable pipeline resolvers, and OpenSearch aggregations and use-scoped queries. The accomplished blogger, as mentioned in this very blog post, blogging legend René continues with “AWS Amplify announces the new GraphQL Transformer v2. More feature-rich, flexible, and extensible.“.

The first thing René brings up in the post is more explicit data modeling. I’ve stolen two of the screen shots from that post as examples and motivation to click through and check out the post. But I’ll also elaborate.

Adding primary and secondary indexes.

With the new explicit data modeling options, we’ve got @primaryKey and @index added as directoves to configure primary and secondary indexes from schema for your Dynamo Database. The directives in AppSync GraphQL really makes for a powerful schema definition capability to push via code first or to map from database to GraphQL scehma.

Adding relational directives.

The other part that is hugely important is the ability in schema to draw relationships that add referential integrity to your schema and the inherent data. There are now @hasOne, @hasMany, @belongsTo, and @manyToMany directives. I’m really looking forward to some data schema and modeling build outs in the near future. I’ll be sure to put together some tutorials and content detailing some of the design considerations and where and how to get all the schema hacks working best for your particular app data builds.

Thanks & Curated Follows

That’s it for this post. I’m always endeavoring to bring interesting tech and blog about it, but another way to get the quickest updates, links, details, and information about these releases is to follow the following people in the Twittersphere. They’re all in the cohort I run with at AWS with the Amplify team. I owe thanks to each for helping me find the following information and details included in this blog entry.

I Joined AWS, It’s Surreal, and Why

TLDR I joined Amazon Web Services on the 11th of October – i.e. AWS – and it rocks.

When you join Amazon you are signing up to learn a lot of things about the company and the ways in which the company gets things done. Before I get into all that, I’m going to tell you a bit about my career and what led me to Amazon. After all, it is surreal and unexpected for many that know me that I’m here. This relationship has definitely been a 2-way story, and one where it finally fit in a mutually beneficial way.

My First Years in Tech

Years ago, I jumped into the nascent tech industry from the state of Mississippi, where I grew up. Mississippi is quintessentially one of the most regressive, least advanced, disadvantaged, poor, and poorly run states in the entire United States. For most Mississippians life starts rough and continues that way throughout. However there are shining little slivers where tech lives and thrives in the state, and I lucked out in a massive way by cutting my teeth at Stennis Space Center (yes, a part of NASA).

When I got into tech I had no high school diploma and no college. I would eventually attend college but I couldn’t attend yet as I was only 13. I fumbled my way into some coding by taking a programming class. The class used the "Basic" programming language taught by a smart and creative woman that did well to keep the attention of a moderately bored "metal head" 13 year old.

Just a few years later I picked up a C++ book, because one didn’t have the internet to just google their way into learning a new language. That was quickly followed by learning Visual Basic 4, which landed me an opportunity to build a video rental tracking application. I got paid too, a massive $300 bucks! In the next several years I ended up getting into networking, systems administration, more programming and scripting and doing work for doctor’s offices, hospitals, trucking dispatches, junk yards, and a number of other businesses.

I loved the independence this life I’d gotten into gave me. Eventually college came up and I attended some courses, mostly about music and music theory more than programming. But out of a desire to learn faster and cover more topics I left college to advance in the industry.

Fast forward over that following decade and I tore into a plethora of technologies, started working for some giant companies like Bank of America, Citigroup, and Fidelity with hundreds of thousands of people, Government agencies, and some smaller startup like companies.

The famous mythical man-month!

Through all of this experience, and traumatic death march styled work, I came to two decisions that have shaped my career for many years and benefited me in a very significant way.

  1. I was going to cease working for the Government, after years of consulting and related work with the Federal and States Governments I just couldn’t take the lack of control, inability to really effect change, and the general laggard nature of the work. I promised myself I’d stop working in this sector entirely. At this point in my life, I’ve held 100% to that promise, it’s been a rewarding and very effective decision.
  2. I decided I would, likely, stay away from big corporations and also likely stick primarily to small (i.e. SMBs) that allowed me the most impact within an organization. If I were to shift back to a large corporate entity it would have to be with some type of rogue group or segmented team within that organization that fell outside of the general organization itself. So far only one team fit that mold, at Home Depot, but outside of that group I’ve stayed my course and stuck to small business, SMBs, and startups.

Hello Amazon Web Services

"Every day is Day 1." - Corporate Training, but coined per Jeff Bezos

This line in the embarkation of working at AWS stuck out. Which is saying something, because when you join AWS there’s about ~80-120 hours of training videos and culture related content to consume for the coder, techie, project, product, and leader related type of work.

It stuck out because, really, in very real terms this is day 1 of a new career direction for me. I’ve shifted and mutated my 2nd declaration above, in a significant way. I’ve joined AWS to work with the Amplify, AppSync, and surrounding teams to move forward work in GraphQL, data, flows related to, and projects and services around that data space. I’m stoked, but I didn’t join just because of the tech.

Why AWS?

Why join AWS? Even though I’d promised myself not to join anymore big corp companies I got to a point and looked at several of the big companies because I wanted more scope. What I mean by scope is the range of topics, tech, and people that I could work with on a daily basis that were involved in a wide space instead of just a singular narrow space. Startups and small business, by their very nature, work in a singular and narrow space. I still had intent and wanted to work with GraphQL and tech immediately tangential to GraphQL, but I wanted more access, more range, and options to expand the interactions of the tech and expand into access to interactions with people in the industry. So I began a search that eventually led me to join AWS.

That search started with several companies, including AWS. I was looking for several key characteristics that would dictate where I landed.

  1. Involvement in the space, specifically the open source space I wanted to work in. That included several key technologies, depending on what matched best, I’d go that direction: Kubernetes, GraphQL, and general open source development (like Github, etc). This made the options basically Google, Microsoft, AWS, or Facebook!
  2. What company would trigger the least ethical dilemmas for me. Yes, this was indeed part of the criteria I was looking at and discussing. Facebook was already on the shit list considering their political meanderings and inability to fix them. I also just wasn’t sure considering the conflation between actions vs. words. Google was in a moderately ok space, as was AWS, and Microsoft has been doing pretty good on the ethical front as of late. There’s always some questions about things, but I basically wanted to make sure I wasn’t working on things directly helping to cage kids or bomb other countries that are in the stone age back to the stone age!
  3. What company has culture (i.e. specifically good behaviors around meetings, people, etc) that I would appreciate and would work well for me. I’m a rather disciplined, driven, yet ADHD afflicted soul so sometimes, a company’s culture can destroy me or burn me out at 10x the rate of others. I want to join an effort and stick around for some time to really drive home some impact!
  4. How would the team I’m on and teams of people I’d work with, mesh with me. Obviously they’d interview me but I am more than aware, and 100% interview them at the same time. Interviews are absolutely a 2-way relationship and I, as with the last decade plus of my career, have chosen only to work with teams of people that I know are top tier, diverse, open minded, and have a good heart in their efforts.

How It Came Together

I started my search with the premise that I wanted to gain the above four characteristics in which company I joined. I had the privilege and due diligence to choose the company that I could gain all of these, not just a one or a couple of these characteristics. I won’t focus on the companies that didn’t make the cut or why, but I will elaborate on why AWS, and Amazon in general, did indeed make the cut.

  • Leadership principles: One of the things Amazon as a company lives and dies by is the leadership principles. There are a whole host of folks that like to complain, denigrate, nit pick, and come up with reasons why these are bad, but I’ll just cut that off with – when intent is good – they’re all awesome. Full stop. To break down each and personally elaborate:
    • Customer Obsession: yeah, I literally do this work with a priority on who will use it. It’s one of the reasons I focus on minimizing ethical concerns. It then insures that I too can truly be invested in supporting my customers in their efforts. Check.
    • Ownership: I already live by this principle, not just in work life, but personal as well! It’s something I staunchly believe in. Long term over short term, take accountability, act on behalf of not only yourself but others. Step up, there’s a lot that needs to be done in this world! Check.
    • Invent and Simplify: The mantra I’ve basically lived my whole programming career by. If I can’t build things to work myself out of work, and I can’t find a better way to do something after doing it for a while, I’ve started to fail at what I’m doing. I work in this field to make things easier, better, and more resilient for the users’ of the things I build and help others build. Check.
    • Are Right, A Lot: Nuff’ said.
    • Learn and Be Curious: Just scroll through and read the posts on this blog, follow me @Adron or streaming @ThrashingCode. You know I’m all about this. Check.
    • Hire and Develop the Best: Well, I haven’t hired anybody yet at AWS, but I’ve hired a lot of people in my career so far. I don’t hire you if you won’t or can’t be the best, thus, if I ever do hire you, you can rest well knowing I vouched for you and know you can kick ass and take names! 🤘🏻
    • Insist on the Highest Standards: We can talk about the pedantic nature of this leadership principle in the future and joke about tablets later. Check.
    • Think Big: Always. Check.
    • Bias for Action: People’s lives continue today because of my bias for action. If you know me, you”ll understand this comment. If not, feel free to ask, I’ve just summarized it with this statement for this post. Check.
    • Frugality: At work, yup. At home, no comment. Albeit I would own a plane or launch rockets in a frugal way too if I had the financial resources. Check.
    • Earn Trust: I’m always working to earn trust among those I trust and respect. I hope we all are, it’s a remarkably good way to live. Check.
    • Dive Deep: I’m on it. Check.
    • Have Backbone; Disagree and Commit. Thanks brutally, caustic, and toxic southern upbringing, and thanks west coast for helping me tone that down to an effective level of having backbone, disagreeing and committing in life. Check.
    • Deliver Results: I’ll admit, this one I’m a little afraid to ask why it even needs to be listed. Check.
    • Strive to be Earth’s Best Employer and Success and Scale Bring Broad Responsibility: I’ll do my part but I’ll leave these as is for today. There’s work to be done! Check.
  • The team and members on the periphery of that team checked all the boxes (good job!), were friendly, easy to converse with, and are top tier people in this industry! During my initial loop I got to speak with, meet, and I highly recommend following each of these people if you don’t already, and more benefit if you are interested in the work we’re doing:
    • Bill Fine -> @billfine
    • Brice Pellé -> @bricepelle
    • Ed Lima -> @ednergizer
    • Robert Zhu -> @rbzhu
    • Ali Spittell -> @ASpittel
    • Mohit Srivastava -> @mohit
    • I also met and spoke with Aleksej Trefilov and Ben Snellings, but we can’t discuss all the cool secret thigns they’re working on, so I’ll just leave it at – awesome to meet them, if you get a chance to work with them sign up!
    • Big shout out too to Adam Desai and Mashayla too! Adam is the recruiter that I worked with and got all of the loops lined up, and Mashayla joined in to make sure everything got coordinated and scheduled! Great experience and good workflow y’all have!
  • Around the culture aspect, as I spoke to the team and others in the immediate teams I dove into a number of culture questions. One of the things that summarizes the drive and energy at AWS is the principled and organized nature of meetings starting with a document read – everybody reads the document – then the meeting resumes around discussion of the document, the details, data, and the participants take actions based on that. It’s a very effective way to run meetings. Beyond that however, the general readiness of the team, the approach and interactions of everybody involved, was excellent. The conversations during the interview, the tests and challenges, all were great fun and I got a lot of information (and I got the job, so I suspect I provide good information!) and enjoyed the interactions. I got a solid feeling we’d mesh well. Another criteria, check!

Now all of this didn’t go off without a hitch, because of certain things I got to do a second short loop and my role switched from Developer Advocate DA to Product Manager Technical. This worked out very well however, as now I’m positioned to have impact from work as a developer advocate and product management efforts.

There were other competing offers from Google, Microsoft, and other companies I interviewed with at the same time. In the end though the responsiveness, effective flexibility from the team and Adam led to AWS coming out the winner. With everything wrapped up and questions answered, all criteria met, I gave AWS and the team a solid YES!

With that I’ve joined AWS! Ready for new challenges and bringing a simpler, faster, more usable Amplify, AppSync, and Cloud environs to every coder out there! Let’s do this! 🤘🏻

The Conversations and Samples of Multi-Cloud

Over the last few weeks the I’ve been putting together multi-cloud conversations and material related to multi-cloud implementation, conversations, and operational situations that exist today. I took a quick look at some of my repos on Github and realized I’d put together a multi-cloud Node.js sample app some time ago and should update it. I’ll get to that, hopefully, but I also stumbled into some tweets and other material I wanted to collect a few of them together.

Some Demo Code for Multi-Cloud

Conversations on Multi-cloud

  • Mitchell Hashimoto of HashiCorp posted a well written comment/article on what he’s been seeing (for some time) on Reddit.
  • A well worded tweet… lot’s of talk per Google’s somewhat underlying push for GKE on prem. Which means more clouds, more zones, and more multi-cloud options.

  • Distributed Data Show Conversations

 

 

 

Leave a comment, tweet at me (@adron), let me know your thoughts or what you’re working on re: multi-cloud. I’m curious to learn about and know more war stories.

Top 4: “Nobody Reads Blogs… Except Everybody Read Blogs”

I know I know, the marketers say it’s all about the single articles now. Nobody reads blogs. Nobody subscribes to blogs. Ya know, except of course for that small percentage of people that do.

…marketing, it’ll make you insane if you’re not careful.

But seriously, here’s a few blogs that are actually worth reading. They’re worth subscribing to and surprisingly, they’re blogs that businesses organize and write. Yes, I have and might be writing for some of them in the future. But I’m honestly basing this list on a few specific criteria:

  • The blog has to include some technical content that is important to getting kick started with their product and getting kick started with other tooling around their space.
  • The blog has to include articles that have industry information that is relevant to conferences, meetups, and other community related activities.

Here’s my list of reads lately:

Continue reading “Top 4: “Nobody Reads Blogs… Except Everybody Read Blogs””