Javascript to Elm

Jesse Tomchak

A podcast about using Elm coming from Javascript and other languages

  • 17 minutes 3 seconds
    Elixir Fundumentals
    Covering the basics
    • Elixir has truthy and falsy Boolean conditionals. I feel right at home
    • Variable assignment can only happen on the left side of the equal

    For a match to succeed, the LHS and RHS must have the same shape, and each value on the right must match the corresponding value on the left. If the thing on the left is an unbound variable, Elixir binds that variable to the value being matched.

    • The LHS cannot contain any calculations or function calls
    • Using _ for ignoring values. Helpful in getting a RHS and LHS match
    • All variables on the LHS of a match are unbound before the match is made.
    • Solution is to use the pin up arrow, *^ to prefix the variable
    Only your posts
    • users should only see their posts.
    • all posts will show on the home page
    Resources

    Dave Thomas the Coding Gnome

    calling an external idp api

    get all entries by user id

    Travis CI and a VPS

    Realworld App

    Follow

     

    9 August 2019, 10:00 am
  • 27 minutes 25 seconds
    Elixir Ecto Models
    Deploy Missing Piece
    • Need for distillery to run migrations on deploy

      • We need to create release tasks that will go in the root of lib.
        • That will have a migration and / or seed function in it.
      • Then in the rel/config.exs we a list of tuples that have the task command, what we want to refer to it as, and the the shell script that we want it to run.
      • Remember mix isn't installed on the prod machine!
      • the shell script just calls bin/postit command Elixir.Postit.ReleaseTasks migrate
      • Then we, to run migration on app launch for new builds, back in rel/config.ex we add set post_start_hooks: "rel/hooks/post_start" to env prod. in this directory we have a single shell script that will use nodetool to ping when the, not app, but BEAM? is up and running, and then run the migration.
      #!/usr/bin/env bash set +e while true; do nodetool ping EXIT_CODE=$? if [[ ${EXIT_CODE} -eq 0 ]]; then echo "Application is up!" break fi done set -e echo "Running migrations" bin/postit command Elixir.Release.Tasks migrate echo "Migrations run successfully"
    • It's great that I had the command correct in the this write up.

      • bc i didn't in the post_start script or the set commands script
      • currently it's in both to see which if both run?

      Custom commands give you a lot of power to express potentially complex operations as a terse statement. I would encourage you to use them for these types of tasks rather than using the raw rpc and eval tasks!

    • App Engine to remove old instances

      • save that for another day, i'm all dev ops out.
    • Force SSL

      • we figured out that we'd forgotten the force_ssl : [] part all together. 🤦‍♂️
    • We are pretty bad at CSS. In a perpetual cycle kind of way. So we need to be better. This is definitely an area where we need to improve on.

    Missing Model Features
    • Posts will need to be a many-to-one to users or 'authors'
    • mix ecto.gen.migration update_posts_with_user_relationship
      • why? so we can list posts by author. 🤦‍♂️
      • post's are not editable. once published, it's done
      • auto saving versions for undo?
        • would that be a Postgres implementation? Where would that line be?

    build_assoc(struct, assoc, attributes \ %{}) Builds a struct from the given assoc in model.

    If the relationship is a has_one or has_many and the key is set in the given model, the key will automatically be set in the built association / Ecto Documentation

    def change do alter table("posts") do add: user_id, :uuid end
    • We're adding a column to our posts table user_id with data type uuid, as it should be a unique identifier? But I don't really know, bc it's coming from auth0. Still happy I didn't role my own.
    • Option B is we could reallocate the user table from auth0 i believe to be in our own database and then create a user scheme to get the info we need from it. That might be an option for another day?
    • Search: elixir pattern match 2 string keys
    def create(conn, %{"post" => post_params}) do case Posting.create_post(post_params) do {:ok, post} ->
    • if I understand it I need to leverage pattern matching to get the user_id out of conn and into a map to pass to create_post which takes a single argument.
    • protocol String.Chars not implemented for oh noes
    • We want a profile page for users

      • can add 3rd party API Tokens
      • update display name
      • how does that work with auth0 as a user table
      • should we move the storage table of users from auth0 to gcloud?
    Resources Follow
    3 August 2019, 4:27 am
  • 28 minutes 1 second
    Elixir Phoenix Plugs

    The layout and details

    • Routes

      • /
      • root of the app will eventually be an aggregate of incoming from Micro.Blog + our own feed (maybe)
      • /profile
      • 'Settings'
      • this is where we'll be able to add targets for our re-posting feature 'echo'
      • add token keys and incorporate 3rd party API's
      • /profile/posts
      • list of current users posts
      • /posting
      • this is the 'editor' with fields for title and content
      • Successful 'post' returns the user to an updated list of posts
    Authorization
    • now that we have authentication out of the way. Let's deal with only that user can post to that users account.

    Just do it already!

    MB:postit> mix phx.gen.html Posting Post posts title:string content:text * creating lib/postit_web/controllers/post_controller.ex * creating lib/postit_web/templates/post/edit.html.eex * creating lib/postit_web/templates/post/form.html.eex * creating lib/postit_web/templates/post/index.html.eex * creating lib/postit_web/templates/post/new.html.eex * creating lib/postit_web/templates/post/show.html.eex * creating lib/postit_web/views/post_view.ex * creating test/postit_web/controllers/post_controller_test.exs * creating lib/postit/posting/post.ex * creating priv/repo/migrations/20190717045929_create_posts.exs * creating lib/postit/posting.ex * injecting lib/postit/posting.ex * creating test/postit/posting_test.exs * injecting test/postit/posting_test.exs Add the resource to your browser scope in lib/postit_web/router.ex: resources "/posts", PostController remember to update your repository by running migrations: $ mix ecto.migrate MB:postit>

    That didn't take long. Our first error. 😭

    assign @current_user not available in eex template.
    • so it looks like we've hit an error in the form that is created when we ran the generator.
    • we'd forgotten to add the security plug to get for auth and the conditional in our Navbar is looking for current_user in order to render the login or logout buttons. happy that was simple.

      • The question is now, I have defined the secure function twice for both events and posts. Is there a place for those types of functions that i will be using in multiple controllers?
      • Option 1 seems to be helpers
      • Option 2 as found in Chris Bell Sharing Methods between controllers
      • Turns out the web.ex file has this cool macro __using__
    def controller do quote do use Phoenix.Controller, namespace: PostitWeb import Plug.Conn import PostitWeb.Gettext alias PostitWeb.Router.Helpers, as: Routes end end
    • Create a controller helper and add it in here!

      • I ended up with a 'controller helper' and accidently build a plug
    Plugs: what did i learn [dot] info
    • plugs feel conceptually a lot like express middleware, where it takes the connection or request and does a function on it, then returns the conn / request for the next plug or middleware
    • There are two types of plugs in the Phoenix. They are module plugs and function plugs. We are going to cover both of them in this article.

      • module has init and call
      • HAHAH we had a function plug, I just had no idea that is what it was or called
    • Where do we want the plug triggered?
    • having stumbled into it in an effort to 'DRY' out our code. And really, there will probably be more controllers in our app over time and I feel like I have really hit the sweet spot of learning

      • question - how do i reuse a function in multiple controllers
      • start with a helper
      • add it to the web.ex for controller that is called as a macro for every controller to import the helper
      • use that helper function on a plug for the controller,
      • just make it a plug function or module
    Alias vs Import
    • What is the difference between alias and import ?

      • Docs! straight to the point doc alias
      • they are referred to as directives
      • alias use shorter name instead of the fully qualified name or prefix

        • is also lexically scoped, so it's only available in the block / function you define it
        • "An alias in Elixir is a capitalized identifier (like String, Keyword, etc) which is converted to an atom during compilation. For instance, the String alias translates by default to the atom :"Elixir.String":"
      • require require this module in order to use it's macros
      • import import functions from module so you don't have to use the prefix
      • (macro) use invokes the custom code defined in that module as an extension point
    Terms
    • changeset

      • possibly an ecto term?
    @doc false def changeset(post, attrs) do post |> cast(attrs, [:title, :content]) |> validate_required([:title, :content]) end
    • conn

      • Short for … connection
    • defp

      • Inside a module, we can define functions with def/2 and private functions with defp/2. A function defined with def/2 can be invoked from other modules while a private function can only be invoked locally.
    Picks Resources

    Elixir Casts Pheonix Contexts

    Alchemist Camp

    Elixir Phoenix Realworld

    Pheonix Conn CheatSheet

    indieweb

    Micro [dot] Blog

    Follow

     

    25 July 2019, 10:00 am
  • 32 minutes 31 seconds
    Elixir with Auth0
    Auth

    I have no desire to roll my own. While a lot can be learned from this type of exercise, it is not something I want to get hung up on. Plus it's a MONSTER subject. Not one to be taken lightly, so we'll outsource the safe keeping of user info and the authentication mechanics. So we can focus on the implementation of it.

    auth0 authenticated app

    Adding some event counter for sampling

    mix phx.gen.html Events Event events title due:datetime I've never been a fan of generators like this before, but I am also tired of hand carving the same things over and over in my React apps. So I'm all in.

    Add the resource to your browser scope in lib/postit_web/router.ex: resources "/events", EventController Remember to update your repository by running migrations: $ mix ecto.migrate
    • plus the cli is super nice and very informative
    • Add a route events to the router under lib/postit_web/router.ex within the scope of PostitWeb
    • Run migration. This I like. I know enough sql to find my way in the dark, but I much prefer to model in the API language I'm using, rather than back and forth. For JS I'm found of knex for that sort of thing. I do like the migration and rollbacks are generated with the phx.gen command. it always struck me as laborious and error prone to try and build those by hand. Also kinds gross.
    • In the Events Context we'll add a list_future_events query
    defmodule Postit.Events do @moduledoc """ The Events context. """ ... @doc """ Returns the list of future events based on UTC ## Examples iex> list_future_events() [%Event{}, ...] """ def list_future_events do query = from e in Postit.Events.Event, where: e.due >= ^DateTime.utc_now Repo.all(query) end
    • Then add these queried events to the homepage controller.
      • getting used to where things go
    • Binding query information for the template and what's alais keyword for?
    • Edit in the page/index.html.eex to add the template to apply the data from the controller to the markup in the template. Curious about action binding. Not a huge fan of 2 way binding. So we'll see.
    • Drop in the 'Flipclock' and jQuery to make it work,
    • CSS and JS are in assets. it's a bit of a funny feeling to see them, not in the make lib of an application I'm working on. Bit odd really.
    • Sign up for auth0

      1. Create New App as 'Regular Web App'
      2. Allowed Callback URLs under settings will need our urls to redirect back to our app, once the user has been authenticated. http://0.0.0.0:4000/auth/auth0/callback for local dev. We'll also want to add https://postit.blog/auth/auth0/callback for our deployed system.
      3. Add social systems. For now we'll leave that. We'll want to add github, twitter, and we'll need to wrap our own for Micro.Blog sooner rather than later.
      4. Authenticated versus Authorized
        1. Who are you versus What are you able to do?
    • Add Ueberauth as a dependency and an extra_application <- What does that even mean to have extra applications?
      1. Add Ueberauth configurations to /config/confix.exs
      2. Feel pretty good to remember where things are after taking a short break.
    • Create a user model
      1. read/map user info from multiple sources
      2. I like that we are manual building the user model, rather than using the generate cli, doing this a couple times manually I feel like I'll better know what it's doing when I generate these down the road. Also, Where is everything?
      3. I don't know what alias is ?
      4. Currently no model folder in "postit_web" so we'll make the folder and the file?
    Compiling 18 files (.ex) warning: variable "auth" does not exist and is being expanded to "auth()", please use parentheses to remove the ambiguity or change the variable name lib/postit/user_from_auth.ex:27 warning: variable "auth" does not exist and is being expanded to "auth()", please use parentheses to remove the ambiguity or change the variable name lib/postit/user_from_auth.ex:28 warning: function avatar_from_auth/0 is unused lib/postit/user_from_auth.ex:26 == Compilation error in file lib/postit/user_from_auth.ex == ** (CompileError) lib/postit/user_from_auth.ex:27: undefined function auth/0 (elixir) src/elixir_locals.erl:107: :elixir_locals."-ensure_no_undefined_local/3-lc$^0/1-0-"/2 (elixir) src/elixir_locals.erl:107: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3 (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6 (elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
    1. Nothing beats debuging after typeing it out.

    2. Create an auth controller

      1. handles callback
        1. successful callback with then call the find_or_create that we made earlier and handle any failures on it's part
      2. logout
        1. removed session
        2. redirect to home page
      3. helpers
        1. not totally sure what Ueberauth.Strategy.Helpers or Router.Helpers are for that matter
    3. Add endpoints for the controller to the Router
      1. need to understand the order of the router
        1. HTTP Type, domain path, Controller, and then controller function?
    4. Secure endpoints with Plug
      1. this will check our current session for a verified user
      2. writing our own plug,
      3. what's halt?
      4. the idea of the plug is to be called by the controller prior to every endpoint.
    5. Adding current_user property allowing us to access it elsewhere ?
    [error] #PID<0.554.0> running PostitWeb.Endpoint (connection #PID<0.553.0>, stream id 1) terminated Server: localhost:4000 (http) Request: GET /auth/auth0/callback?code=v06g_ILWwJvcOOOK ** (exit) an exception was raised: ** (ArgumentError) argument error (postit) lib/postit/user_from_auth.ex:27: UserFromAuth.avatar_from_auth/1 (postit) lib/postit/user_from_auth.ex:34: UserFromAuth.basic_info/1 (postit) lib/postit/user_from_auth.ex:19: UserFromAuth.find_or_create/1 (postit) lib/postit_web/controllers/auth_controller.ex:23: PostitWeb.AuthController.callback/2 (postit) lib/postit_web/controllers/auth_controller.ex:1: PostitWeb.AuthController.action/2 (postit) lib/postit_web/controllers/auth_controller.ex:1: PostitWeb.AuthController.phoenix_controller_pipeline/2 (phoenix) lib/phoenix/router.ex:280: Phoenix.Router.__call__/2 (postit) lib/postit_web/endpoint.ex:1: PostitWeb.Endpoint.plug_builder_call/2 (postit) lib/plug/debugger.ex:122: PostitWeb.Endpoint."call (overridable 3)"/2 (postit) lib/postit_web/endpoint.ex:1: PostitWeb.Endpoint.call/2 (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2 (cowboy) /c/Users/jtomc/Documents/Elixir/postit/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2 (cowboy) /c/Users/jtomc/Documents/Elixir/postit/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3 (cowboy) /c/Users/jtomc/Documents/Elixir/postit/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3 (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3 Resources

    basic blog tutorial

    tutorial repo

    Follow
    18 July 2019, 10:00 am
  • 23 minutes 14 seconds
    Elixir with AppEngine
    AppEngine

    Remember what started us down the path of managing a kubernetes cluster in the first place? No, it wasn't our own sadistic desire to to devops in an effort to avoid building an actual project, but close. We want to be able to leverage 'live view' in our project, that requires websockets, which all signs pointed to not available on appengine. But wait, what's this? App-Enggine WebSocket Support As of Feb 2019, it looks like we're good to go. That coupled with the $30/month bill we would incur when our gcp credits ran out, this switch seems to make a lot of sense.

    Clean up
    • Tearing down services
      • kubectl delete service postit-web
      • gcloud compute forwarding-rules list use this to check that the loadbalancer is also removed
      • and finally the cluster of 2 VM's gcloud container clusters delete --zone=us-central1-a postit-cluster
      • then just the database. and we're all set to startup with app-engine
    App Engine
    • update KMS key/value on key for beta app. remember we tore everything down and needed to create a smaller db instance

    • run mix ecto.create to instantiate new db and mix ecto.migrate

    • we can see that the app in prod was able to connect and create the db by the right name in the gcp console.

    • so we've got a new connection name and db name. I left the others the same, so I didn't have to create all new keys for it.

    • Create app.yaml file

      env: flex runtime: gs://elixir-runtime/elixir.yaml runtime_config: release_app: postit beta_settings: cloud_sql_instances: [CONNECTION-DB]
    • and then just gcloud app deploy

      • but wait - had to remove the dockerfile and the cloudbuild from the directory so it would run

      • mmmm, no env's for database name or password?? grrrrr 😡

        GenServer #PID<0.1713.0> terminating ** (RuntimeError) connect raised KeyError exception: key :database not found. The exception details are hidden, as they may contain sensitive data such as database credentials. You may set :show_sensitive_data_on_connection_error to true when starting your connection if you wish to see all of the details
        • we knew it was coming.
        • with hard coding the env variables in we got it running in record time!!
        • BEHOLD IT WORKS!
    • So if we update the cloudbuild to publish the docker image we've been making to app deploy instead of kubectl, then it will have all the compile time variables from KMS in it and run from the could build instead of locally, right?

    • update docker and cloudbuild to use the newest KMS key's for database name and variables. printenv from the docker build to confirm.

    • do i need a custom start command?

    • enable App Engine Admin API 🤦‍♀️ you'd think i'd know that by now

    • change the sql directory to /cloudsql/[CONNECTION_NAME] that's just removing the tmp/ from our KMS. Which i can just update and replace the base64 string in the cloudbuild file. so that's rad.

    At this point. For someone who is pretty vocal about not liking the devops side of things, you sure spend a lot of time working on those details.

    • you make a fair point. it's hard to argue that.
    • so maybe instead i'll try to Justify it?
    • what good is a side project if you can't get it out there?
    • or if you have to manually deploy it when my make changes. How often will you actually deploy new stuff?
    • Answers to these questions might be different for you, but they are a real barrier to entry for me.
    • I want to as it's most basic level, work on my project, and then pull it up on my phone after I commit changes.
    • I don't want to be building new releases locally, waiting around to manually do steps 2 and 3. I want just one step, git push that for me is the only sure fire way I will have a current release out there for me to play with on my phone.
    • Then there is the sharing aspect. I want to share this project. To have other's see it, and provide feedback, that's a lot easier to shorten the feedback cycle when it's out there and updated on every commit. Auto-magicly

    Ok where'd we leave off?

    • we've got cloudbuild creating our custom build. with env variables so no secrets in the code
    • We hit "18:07:59.579 [error] Postgrex.Protocol (#PID) failed to connect: ** (Postgrex.Error) FATAL 53300 (too_many_connections) remaining connection slots are reserved for non-replication superuser connections"
    • connection limits. lol
    • which is really poetic, if you remember we struggles for days getting the unix socket connected on our local machine. LOL and this point you can't help but laugh.
    • And we're in business. 🎉 Post it on App Engine
    • well, almost. there's an error on "number of connections", gigalixir made note if you're on the free tier, then set your poolsize to 2. so we did.

    And what'd we get for all that effort?

    • domain mapping
    • SSL
    • continuous integration on git commit
    • a whole crap ton of knowledge around the gcp ecosystem and for a small part we know a lot about debugging an elixir app with distillery.
    • Now on to OAuth?

    Postit Blog With SSL

     

    Follow We cannot render the preview. If you use HTML tags, check if these are valid.

     

    11 July 2019, 10:00 am
  • 30 minutes 5 seconds
    Elixir Deployment
    Cuts
    • ipv6:

      • this was in the
    • When to set config

    • AWS is a jungle

    • So.. I guess I need docker 🙄

    • GCP cloud_sql connection

    • Creating docker image

    • Can I test this image?

    • Debug in prod?

    • SQL Admin API access

    • Where'd PORT go?

    • Docker build is gonna need more RAM

      • docker build -t gcr.io/post-it-243617/postit:v0.4.0 . Sending build context to Docker daemon 523.8kB Error response from daemon: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
    • Docker Args

      • pass the arg
      • declare the arg
      • use the arg $DB_NAME NO CURLY BRACES
      • ok working
    • GCP Secrets?

    • Google KMS (Cloud Key Management)

      • enable KMS. we learned that from the last API, cloud sql
      • using the gcloud kms key XXXXX manual add keys one by one
      • update txt file, get back encrypted file
      • convert encrypted file to base64 and add as a variable to the cloudbuild.yaml
      args: [ '-c', 'docker build -t gcr.io/post-it-243617/postit:$REVISION_ID --build-arg DB_PASSWORD=$$db_password --build-arg DB_NAME=$$db_name --build-arg DB_SOCKET_DIR=$$db_socket_dir --build-arg DB_USERNAME=$$db_username --build-arg SECRET_KEY_BASE=$$secret_key_base .' ] secretEnv: ['db_password', 'db_name', 'db_socket_dir', 'db_username', 'secret_key_base']
    "Unusable Erlang runtime system! This is likely due to being compiled for another system than the host is running"
    • Building with alpine-elixir:1.7.1 and then serve with alpine:latest
      • there is then a mismatch of erlang versions.
      • checked the distillery examples and locked in the alpine-elixir:1.8.2 and alpine:3.9 Both having the erlang version ERLANG_VERSION=22.0.4
    • Loadbalance and HTTPS

      • kubectl expose deployment DEPLOYMENT --type=LoadBalancer

      The key thing here is to specify the type and your deployment's name. This will expose your deployment through a service and set up a Load Balancer on Google Cloud Platform.

      • OH??? Ingress is a kubernetes thing. I could figure out what "Ingress" was 🙄

    Websockets for AppEngine

    Resources

    Distillery

    Best Practices for deploying Elixir

    PHX on kube gcp

    win 10 docker more member

    Docker ENV passed with -build-arg

    how to KMS

    Distillery with Docker

    Using KMS with cloudbuild

    kubectl cheetsheet

    gcloud kube https

    Follow

     

    28 June 2019, 10:00 am
  • 28 minutes 56 seconds
    Elixir with Phoenix
    Building it locally
    1. Easy enough to get it running with the instructions from Elixir and Phoenix
    2. Problems with Postgres install and running

      1. postgresql install ubuntu
      2. sudo su - postgres pg_ctlcluster 11 main start
      3. Getting default postgres running required the pg_ctlcluster
      4. Finally running local db, not my strong suit
    Package it up for deployment
    1. Add Distillery {:distillery, "~> 2.0"}

    2. Hex Package Manager for the BEAM ecosystem

      1. About Six Colors AB

        Hex was started as an open-source project early 2014, it is still an open-source project but today it is operated by the Swedish limited company "Six Colors AB". The company was founded in 2018 by the creator of Hex, Eric Meadows-Jönsson, Six Colors supports the development of Hex and operates all services required to run Hex.

        By charging for private packages we can fund free open-source development and run reliable services for both paying customers and the open-source community.

    Get it out there
    1. Setup a VM on Azure

      1. tyBasic Ubuntu VM 1 CPU, 1GB RAM
      2. $ 8 bucks a month
    2. Setup the Postgres

      1. CPU 1 & 5GB Storage
      2. $ 27 Bucks a month!
    3. OK…now what?
    4. I can ssh into the VM 👍
    5. Probably need to get the postgres creds into the prod build for my app?

      1. set the env vars to be able to run MIX_ENV=prod mix release
    $ mix deps.get --only prod $ MIX_ENV=prod mix compile $ npm run deploy --prefix assets $ mix phx.digest

    npm run deploy --prefix assets && MIX_ENV=prod mix do phx.digest, release --env=prod

    1. Let's try this without an Nginx proxy 🤷‍♀️

      1. Port Forwarding with iptables
      2. Tried Ubuntu ufw. But it wasn't enabled on the VM by default,
      3. So I went with port forwarding iptable style
    2. Getting the DB connection is a struggle

      1. How do I do mix ecto.create for prod? Since, you know, there isn't any mix?
      2. Ecto Migrations
      3. edeliver writeup from plataformatec
    Attaching to /home/meowAdmin/hello-meow/var/erl_pipes/[email protected]/erlang.pipe.1 (^D to exit) iex([email protected])1> path = Application.app_dir(:hello_meow, "priv/repo/migrations") "/home/meowAdmin/hello-meow/lib/hello_meow-0.1.0/priv/repo/migrations" iex([email protected])2> Ecto.Migrator.run(HelloMeow.Repo, path, :up, all: true) 22:08:49.855 [info] Already up [] iex([email protected])3>
    1. OH SHIT IT'S ALIVE
    Continuous Delivery

    One option

    Digital Ocean Option

    AWS Option

    Next Try

    Let's go with the AWS option, and we're going to roughly follow a couple guides to get what we what. And what's that?

    1. Continuous Deployment 1. Whatever I git commit to Master is built and deployed to the running instance. Whether that's a hot upgrade, or a deploy and drain of an EC2. Whatever, I'm not too concerned with the details at this point. I want to be able to build locally, test it out, and then trigger a deploy by doing what I already do, a git commit and / or merge 2. Wanta be able to rollback easily. That might be aws cli, or even a click on the aws console. Either would be fine, I have no idea how this will work in practice with automatic build and deploy yet. 3. Build fail if tests fail.

    Elixir on AWS

    or this one Elixir w/ Docker on AWS

    1. AWS install cli and get signed in.

      1. setup ssh for code commit
      2. config cli with AMI account
      3. Be sure to have permissions for our new AMI user to cloudformation (this might be hairy)
      4. Skipping cloudformation bc 😱
    2. Get the project up on git up

    3. Create the RDS postgresql and get the address, username, and password,

    4. Create an encrypted S3 bucket for secrets

    5. Spin up 2 EC2 instances of the default linux and ssh into them with the *.pem that you download from the console

      1. not sure how with a PEM ? yeah me either aws ec2 ssh
      2. turns out you can just the PEM in the ssh command
    6. ssh into ec2 instance and install codedeploy mmmmmmm. with a list of 8 commands ?

      1. ummmm, ok 🤷‍♀️ codedeploy agent install
      2. rando site for install package by s3 region
      3. wget https://aws-codedeploy-us-east-2.s3.us-east-2.amazonaws.com/latest/install
      4. is your agent running ? sudo service codedeploy-agent status
      5. at this point I haven't seen codedeploy in action, but i have the agent running.
      6. Repeat on the 2nd instance
    7. That seemed to be the easy part. I've now got code deploy agent running on my instances, Now it appears I need an appspec.yaml oh boy do I love YAML files.

      1. Have YAML file
      2. slowly try and refine
      3. uploaded secrets to secure S3 bucket with no public access.
      4. Scripts pull them down and export them before build
    8. Current cycle:

      1. Update code config
      2. git push
      3. get commit hash
      4. run codedeploy
      5. READ ERRORS
    9. Now on 8 failed deploys

    10. Then it occurs to me. Even if I get it running.

      1. THERE IS NO ELIXIR / ERLANG ON THE VM
      2. 😡
    11. So over to codebuild as a product.

      1. deploying to aws from hex:distillery

      2. Mess with codebuildfor a couple hours

      3. Realize that pipeline is really what I want and that some options aren't available unless you start from there

      4. Build a pipeline

        1. detour from aws to CircleCI for another couple hours

        2. Even within a project I will bounce when I hit a wall, rather than taking a 10 minute break and coming back to it. I was trying to be super good at time tracking, but it's gone out the window for this project.

        3. Got it building and testing on CircleCI, then aws orbs showed up when I went to figure out how to get the build from the CI to S3 so finally get it to the EC2 instances to run

        4. That seems like a real chore, using the same aws-cli that I was using in the aws interface !!!!

        5. Back to aws 😭

        6. At least there is gobs of documentations and help articles

        7. Cool I like VPC (Virtual Private Cloud)

        8. loadbalancers need 2 subnets in different available zones

        9. both need to have an internet gateway ? which means the routing table for both public subnets created need to have internet gateway … i think

        10. ok. got past that step. now

        AWS Certificate Manager (ACM) is the preferred tool to provision and store server certificates. If you previously stored a server certificate using IAM, you can deploy it to your load balancer. Learn more about HTTPS listeners and certificate management.

        1. so many steps

        2. ok. so have a cert for the domain.

        3. Use NameServe from aws to populate the 'nameserve' on hover.

        4. Now. Now we can set up the loadbalancer with a target 'group'

        5. Remember we need to actually deploy the code from S3 to the EC2.

        6. Need to ssh in and install codedeploy again

        7. had to swipe ec2 instances and start again

        8. Need Blue/Green so 2 ? 🤷‍♀️

        9. Also remember there is no codedeploy agent on the ec2's anymore

        10. AND they are not publicly accessible so I can't ssh into them and run the commands

        11. so that leads me to AWS System Manger 🤦‍♂️

          1. after fighting with AIM to get the ec2's to show up,
          2. I might have out outdated agent to get to the instance, to run what I need ?

          The version of SSM Agent on the instance supports Session Manager, but the instance is not configured for use with AWS Systems Manager. Verify that the IAM instance profile attached to the instance includes the required permissions. Learn more

          1. I didn't even know what a bastion instance was

     

    14 June 2019, 11:05 pm
  • 20 minutes 56 seconds
    Elm Community

    Elm In the Spring Videos are up LINK

    Announcing Elm UI-Explorer

    I was gonna steer clear of this topic after initially reading the post by Chris Gregori Elm and why its not quite ready yet , and the follow up by Lucas Payr How Can the Elm Coummity Imporve , but it sort of festered on my mind, which listening to this reason behind this weeks tardy release. I have another episode in the cooker, one that was a lot more fun to work on, but there was something about this open conversation that I just can't shake.

    There is no answer here, only those searching

    That's my disclaimer.

    Summary

    I think both articles from Chris and Lucas where thoughtful, articulate and constructive. I didn't get any sense of trolling, flaming, or even so much as a hint of rudeness.

    Chris wrote on article titled 'Elm and Why it's Not Quite Ready Yet' where he outlines several points that he believes makes Elm, as the title suggests, not ready for prime time. To be fair, he does list a fair amount of good points and things that he likes in the language too. What I'm trying to get at, it's more than just a fly by gripe list, which is why it stuck with me.

    - Debugging looks awful and is largely unhelpful - You cannot install Elm packages from anywhere other than the official package repository. - Most of the tutorials / examples online are out of date due to v0.19 - The docs are incomplete
    • Elm core development lives in a walled garden that you can't touch, even if you wanted to - This one centers on the 'native code' ability removed in 0.19

      • Pull requests being open for 2+ years
      • Runtime errors can happen
      • Missing key features (SSR, web sockets, local storage)
    • Lacks the ecosystem of its siblings - refer to the 'awesome list'

      • What if you want transparency in what's going on with the future of the language you're using?

    So that's quite a list. And to be frank with you. I have had each and everyone of these thoughts at one time or another. I would venture to say it's a pretty accurate list. Now do they repel me from Elm? Not really, I'm still here sharing with you and trying to get better. But I do think about them from time to time.

    Now the other reason I wanted to talk about this is because Lucas came up with, what I thought was a great perspective, it's not a bullet for bullet rebuttal, what would be the purpose of that? Convincing Chris that his opinion is wrong, that Elm is better than sliced bread, that he should feel bad for thinking such things? So many of the comments and rebuttals online are exactly this, "you're wrong and here's why". But as I noted, this is not what Lucas did, instead

    What are problems in Elm that the community can solve? And how can we solve them?

    He goes on to layout out community resource points, the news letters available, this very podcast ☺ and equally as awesome Elm Town, conferences, and ecosystem. It's a great list, I didn't even know about Elmfinder !!! Seriously look through this list Lucas put together, I am sure there is something on it you didn't know was out there.

    • Documentation

    • Good Practices Elm Cookbook

    • Conclusion

      • Elm, like everything, is not perfect
      • We can bring the different platforms closer together. If we have just posted something on one platform, we should tell the other communities as well.
      • We can share the podcasts as well as the newsletter more often. Let newcomers know of all these awesome things that we made.
      • We can continue to share talks. Actually I feel like this is already happening a lot and its one of the greatest things about Elm.
      • We can improve awesome-elm more. This is the first introduction to the community for a lot of people, so let's make the first contact count.
      • We can improve the docs and write guides. If Evan has problems keeping his guide up to date, maybe we should help out: Write our own open source book. It does not need to be perfect but at least it should improve the parts that Evan guide lacks.

    So now what? Head over to discourse and let's work on it, together.

    Resources

    How Can the Elm Community Improve

    Elm and why its not quite ready yet

    "The Hard Parts of Open Source" by Evan Czaplicki

    Announcing Elm UI-Explorer

    Follow

     

    7 June 2019, 10:00 am
  • 19 minutes 44 seconds
    Open Source Support

     

    Covering the current state of open source support both monetarily and emotionally to those that put in so much work and effort that everyone benefits from.

     

    Links

    Actions is to contribute to the Gatsby project and Babel?

    Let's start with becoming a contributor and go from there. By, say next week. 

     

    30 May 2019, 3:42 pm
  • 24 minutes 12 seconds
    Yearly Themes Check-in

    We set out this with a theme this year. Not a resolution, but an idea of something tangible that wanted to accomplish or do better in our efforts here. If you're not super familiar with themes, as I was not, I'd encourage you to listen to Cortex on Relay FM, of course they are in the show notes.

     

    Cortex #79: 2019 Yearly Themes - Relay FM

     

    Cortex #62: 2018 Yearly Themes - Relay FM

     

    Actual Reddit thread gives a good rundown of yearly themes, but for me it's really something you can ask yourself when you're doing something, or you're looking at your to do list, or list of projects you want to work on. Whether those are side projects, or maybe they are part of your business in the case of Myke and Grey. (Those are the peeps from the show Cortex)

     

    So what was my theme? Creating Content and Simple Automation. Episode #64 Aptly titled 'Themes' goes into both in pretty good detail, and I thought since it's nearly the 1/2 way point of the year, how am I doing?

     

    The idea, whenever I start in on something overly complex or silly. I'm not looking for a Rube Goldberg machine, the exact opposite. I can think, "does this fit in my theme of create content with simple automation?" and if the answer is not a resounding YES then I can skip it.

    Me from Episode #64

     

    Score card

     

    Creating Content

     

    • Podcast - still going strong
    • Newsletter - not yet, but we're getting closer ... soon
    • Conference talks - hell yes!
    • Conference rejections
    • Video or ScreenCasting ... soon
    • Daily / Weekly Blog .. 🤔 Blog https://jessetomchak.com

     

    Simple Automation

     

    • WordPress - yep
    • Gatsby - yep
    • Permission to skip or just not get started on something - less so
    • New Indie.web specifically Micro.blog

     

    And this was a very powerful idea. I have dozens if not a hundred started projects. Notice that I said started. Not finished, not even abandoned. Just started.

     

    I always have good intentions of coming back to a project, ignoring the others that I have yet to return to.

    Me

     

    Can't say I've enjoyed WordPress a lot. I understand more why people do like it. I've found a plugins for markdown, adding code snippets without having to make functions in the themes, that then get overridden when it inevitability needs to be updated. Which is a bit miserable when it's hosted on Cent OS with selinux turned on. 🤷‍♀️ But those are all things I know now.

     

    Cortex #44: Existential Time Tracking

     

    Elmstatic by Alex Korban

     

    23 May 2019, 4:07 pm
  • 20 minutes 4 seconds
    Out of the Wilderness
    CFP for Elm-Conf
    • You have sometime to get a proposal in. I'd love to hear what you have to say about your latest Elm or functional related adventures. I've submitted one of a couple of my ideas, I encourage you to do the same.
    Lost in Routing
    • if you listened last week, and were a bit confused, you are not alone. I too am trying to unlearn a lot of habits good and bad that I baked into my mental model of an SPA.
    • Prop passing is muscle memory at this point, and I'm having a hard time not picturing the model of my application that way.
    • First things first - THROW OUT THE COMPONENTS NAMED FILE
    • Better? cool. Let's start again. Views are functions, they are composable together. I am not entirely sure what _main was referencing in the components file. And it's even harder to google something for which you don't have a name to describe it with.
    Back to basics Resources Follow We cannot render the preview. If you use HTML tags, check if these are valid.
    9 May 2019, 9:00 am
  • More Episodes? Get the App