happy-egg-47291
10/05/2018, 5:51 PMaws.lambda.Function
object with a cloud.API endpoint?busy-umbrella-36067
10/05/2018, 8:06 PM$ pulumi preview
Previewing update of stack 'XXXXXXXX/XXXXXXX-dev'
error: could not find plugin for provider 'XXXXXXXX-dev::XXXXXXX::pulumi:providers:kubernetes::default'
busy-umbrella-36067
10/05/2018, 8:09 PMbusy-umbrella-36067
10/05/2018, 8:09 PMcreamy-potato-29402
10/05/2018, 8:10 PMcreamy-potato-29402
10/05/2018, 8:11 PMfull-dress-10026
10/05/2018, 8:56 PMpulumi update
did not fail.full-dress-10026
10/05/2018, 8:59 PMname
to a new aws.cloudformation.Stack
and a CF stack with that name exists, will it use that CF stack?dazzling-scientist-80826
10/05/2018, 11:33 PMfailed to verify snapshot: resource .... refers to unknown provider ...
- but as far as i can tell, the provider is defined in the snapshotdazzling-scientist-80826
10/05/2018, 11:33 PMdazzling-scientist-80826
10/05/2018, 11:33 PMdazzling-scientist-80826
10/05/2018, 11:39 PMdazzling-scientist-80826
10/05/2018, 11:39 PMdazzling-scientist-80826
10/05/2018, 11:39 PMbig-piano-35669
10/05/2018, 11:42 PMdazzling-scientist-80826
10/05/2018, 11:48 PMdazzling-scientist-80826
10/05/2018, 11:48 PMdazzling-scientist-80826
10/05/2018, 11:48 PMdazzling-scientist-80826
10/05/2018, 11:49 PM"delete": true
and got an assertion failure:dazzling-scientist-80826
10/05/2018, 11:49 PMdazzling-scientist-80826
10/05/2018, 11:52 PMdazzling-scientist-80826
10/05/2018, 11:52 PMdazzling-scientist-80826
10/05/2018, 11:54 PMpulumi update
is finally successful again, but i’ll admit, i have zero confidence that this snapshot file matches reality 😛brave-angle-33257
10/06/2018, 12:16 AMgifted-island-55702
10/06/2018, 8:13 PMglamorous-printer-66548
10/07/2018, 12:40 AMinfrastructure-shared
repository which contains a few pulumi programs which setup the base infrastructure that is shared by many apps. this includes for example: GCP projects, GKE clusters, cluster-wide addons (i.e. cert-manager, kube external-dns). This repo contains multiple pulumi programs for different gcp projects and each of them usually just a single stack instance. They share a few parameters / constants which are defined as simple JS / TS files under a common
directory at the project root.
2. we have a single pulumi-util
repo which contains an internal reuse npm library (important: this is just a library, not a pulumi program itself) that codifies a couple of common pulumi patterns. E.g. it contains a common dockerfile to build a nodejs app, it contains a SolvvyApp
(solvvy is the name of my company) class which creates a docker Image, Deployment and depending on the configuration also a Service or Ingress resource. This is basically a much enhanced version of https://github.com/pulumi/examples/blob/master/kubernetes-ts-guestbook/components/k8sjs.ts#L9 . It also contains a few utilities to deal with GKE particularly.
3. We have multiple application repositories (7 or so) which contain the application code for those aforementioned 15-20 services (some of those repos are a mono-repo, so contain multiple services). In each of those app repos we have a subdirectory infra
which makes heavy use of our own pulumi-util library to build and deploy the app to the clusters that have been setup prior to that via the infrastructure-shared
repository. One important side note is that we even setup some core infrastructure like redis and rabbitmq inside the app repositories when they are not shared by most of the apps (which is the case for redis and rabbitmq which are really only used by one application each). Typically the code inside each app repository is very brief because it reuses abstractions from our pulumi-util library. E.g. this is how the code in one of our apps infra
directory:
import { SolvvyApp } from '@solvvy/pulumi-util';
const app = new SolvvyApp({
buildContext: __dirname + '/../',
service: {
internalHttpPort: 1337,
expose: 'VPCInternal'
},
env: {
NODE_ENV: 'k8s'
}
});
export const url = app.url;
This little code builds a docker image, pushes it to gcr, creates a k8s service of type load balancer which creates a GCP internal TCP load balancer, assigns a dns entry via kube external-dns. etc. The application name is inferred by reading the package.json under buildContext (solvvyapp contains that logic) and the environment name (which gets translated to a namespace) is inferred from the last segment of the stack name (the string after the last ‘-’ in the stack name).glamorous-printer-66548
10/07/2018, 12:40 AMconfig:
gcp:project: my-gcp-project
'@solvvy/pulumi-util:cluster': my-gke-cluster
This information is used by the pulumi-util library to dynamically create a pulumi k8s provider onto which the application will be deployed. Concretely the following code is used to create a k8s provider from the the cluster name: https://gist.github.com/geekflyer/b78adab2667d8526a1dd593bc5c844bf#file-gke-ts
SolvvyApp under the hood simply calls getK8sProviderFromInferredCluster()
(https://gist.github.com/geekflyer/b78adab2667d8526a1dd593bc5c844bf#file-gke-ts-L29) to get a k8s provider. Those gke utilities basically make use of the getCluster
function of pulumi https://pulumi.io/reference/pkg/nodejs/@pulumi/gcp/container/#getCluster to read in some stuff of existing cloud resources (that have been created by another program / stack).
In general pulumi has a lot of those get<Something>
functions to read in parameters of some cloud resource that has been defined elsewhere.
I’m honestly not sure how one can use stack outputs from one pulumi program as inputs to another (without manual copy and paste) and It’d be curious on some example for this too (@big-piano-35669?)glamorous-printer-66548
10/07/2018, 12:50 AMgcloud auth activate-service-account --project <project_of_service_account> --key-file=-
glamorous-printer-66548
10/07/2018, 12:59 AMglamorous-printer-66548
10/07/2018, 2:02 AMAt Solvvy we use pulumi to deploy and manage our infrastructure E2E.
Generally speaking we can divide our infrastructure into two kinds of “Resources”:
1. Low Level and Shared Resources, i.e. VMs, Kubernetes Clusters, Cluster-Wide services or addons (i.e. gitlab-runner, cert-manager, external-dns)
2. App Resources, i.e. for a service like the accounts-api. Typically each app is comprised of resources like a docker image and runtime container, some networking config, a service account, possibly a DNS name and optionally some app specific backing services, i.e. rabbitmq or redis.
Each application may have unique requirements for infrastructure, use unique libraries / frameworks and have an independent deployment lifecycle. Therefore we try to build a model where the app-specific infrastructure code (i.e. rabbitmq for app1, redis for app2) is held in the same location as the application, concretely in the repository of the application itself (i.e. github repo of app1). Only resources which are very common or shared between apps by technical necessity are defined in a central infrastructure-only repository (i.e. a kubernetes cluster). One advantage of this code organization is that in order to introduce a new app / service (or fit the infrastructure to new requirements of a drastically changed app), one has to only create a single Pull Request / Commit in the app repository and not an additional dependent PR in the shared infra repo. Philosophically speaking the idea behind putting infrastructure code into the app repo is to empower developers to develop and run their application end-to-end, delivering on the original goals of a “DevOps” culture vs. relying on strict division of labor and inefficient dependencies between Dev ←→ Ops in the old world. Pulumi and kubernetes are two very important ingredients to achieve this - they basically provide a common, approachable platform for consuming, building and sharing abstractions on top of low level infrastructure. I.e. Pulumi uses a general purpose language like TypeScript and npm libraries for defining infrastructure (vs an infrastructure-only DSL like Terraform’s Hashicorp Configuration Language) and with kubernetes you don’t need to be a bash + tmux superhero just to see the logs of all your app instances. This makes creating and managing infrastructure much more approachable for the average developer.
glamorous-printer-66548
10/07/2018, 2:02 AMAt Solvvy we use pulumi to deploy and manage our infrastructure E2E.
Generally speaking we can divide our infrastructure into two kinds of “Resources”:
1. Low Level and Shared Resources, i.e. VMs, Kubernetes Clusters, Cluster-Wide services or addons (i.e. gitlab-runner, cert-manager, external-dns)
2. App Resources, i.e. for a service like the accounts-api. Typically each app is comprised of resources like a docker image and runtime container, some networking config, a service account, possibly a DNS name and optionally some app specific backing services, i.e. rabbitmq or redis.
Each application may have unique requirements for infrastructure, use unique libraries / frameworks and have an independent deployment lifecycle. Therefore we try to build a model where the app-specific infrastructure code (i.e. rabbitmq for app1, redis for app2) is held in the same location as the application, concretely in the repository of the application itself (i.e. github repo of app1). Only resources which are very common or shared between apps by technical necessity are defined in a central infrastructure-only repository (i.e. a kubernetes cluster). One advantage of this code organization is that in order to introduce a new app / service (or fit the infrastructure to new requirements of a drastically changed app), one has to only create a single Pull Request / Commit in the app repository and not an additional dependent PR in the shared infra repo. Philosophically speaking the idea behind putting infrastructure code into the app repo is to empower developers to develop and run their application end-to-end, delivering on the original goals of a “DevOps” culture vs. relying on strict division of labor and inefficient dependencies between Dev ←→ Ops in the old world. Pulumi and kubernetes are two very important ingredients to achieve this - they basically provide a common, approachable platform for consuming, building and sharing abstractions on top of low level infrastructure. I.e. Pulumi uses a general purpose language like TypeScript and npm libraries for defining infrastructure (vs an infrastructure-only DSL like Terraform’s Hashicorp Configuration Language) and with kubernetes you don’t need to be a bash + tmux superhero just to see the logs of all your app instances. This makes creating and managing infrastructure much more approachable for the average developer.
quiet-wolf-18467
10/07/2018, 11:31 AMbrave-angle-33257
10/07/2018, 5:14 PMmake deploy-compute:
cd ${PWD}/network
NETWORK=$(pulumi output)
cd ${PWD}/data
DATA=$(pulumi output)
cd ${PWD}/compute
pulumi config set ${DATA}
pulumi config set ${NETWORK}
pulumi update
make deploy-all:
cd ${PWD}/network
pulumi update
NETWORK=$(pulumi output)
cd ${PWD}/data
pulumi config set {$NETWORK}
pulumi update
DATA=$(pulumi output)
cd ${PWD}/compute
pulumi config set ${DATA}
pulumi config set ${NETWORK}
pulumi update
no idea if it will work properly, but from what I see that's more or less how you'd have to do it.. would love to hear other opinionsglamorous-printer-66548
10/07/2018, 9:49 PMterragrunt apply-all
) and respect the dependencies between them for ordering: https://github.com/gruntwork-io/terragrunt#the-apply-all-destroy-all-output-all-and-plan-all-commands . I wonder if pulumi could introduce something similar @creamy-potato-29402 ? Should I open an issue?
In general currently I minimize the need to pass around outputs from one stack to another by simply using predictable resource identifiers (which is easy in GCP), shared TS libs / modules / constants and getting other data like the IP addresses of a GKE cluster, by using pulumi’s get<Resource>
functions (e.g. getCluster
).
Terraform btw also has the ability to query the state of another module directly https://www.terraform.io/docs/providers/terraform/d/remote_state.html#example-usage which is another way of sharing config between stacks. Maybe worth another pulumi feature request? 🙂brave-angle-33257
10/08/2018, 2:07 AM$ pulumi select deployment prod
$ pulumi stacks
pulumi:
mycompany-prod-network
mycompany-prod-security-group
mycompany-prod-rds-api
mycompany-prod-rds-app
mycompany-prod-asg-app
mycompany-prod-lambda
$ pulumi stack detail rds-app
aws:rds:postgres/AppTracking
aws:rds:mysql/AppUser
$ pulumi stack detail lambda
aws:lambda:function/Login
aws:lambda:function/Logout
aws:iam:role/LoginRole
aws:iam:role/LogoutRole
Furthermore, I could maybe create a group, and using the upcoming RBAC control allow users to deploy that group as one unit, or any of the individual items inside, like an app-compute group, that might be ASG and Lambda.
$ pulumi select deployment prod
$ pulumi create group app-compute --stack asg-app --stack lambda
$ pulumi group detail app-compute
mycompany-prod-asg-app
mycompany-prod-lambda
$ pulumi group update app-compute
(updating)...
I realize this is pretty different than what they have currently, but to me it makes a lot of sense for how I've been arranging things in the past using some internal tools. I'm going to spend some time seeing how feasible my make
approach would work.glamorous-printer-66548
10/08/2018, 2:53 AMmyawesomeapp-staging
and can include various things like: container image, k8s Service, Deployment, IAM service accounts and the role bindings to that account, backing services like the db, redis cache (if not shared by other apps), a supporting cloud function (lambda), alerting rules etc. To create or remove a new app I just want to touch one stack and not changing 5/6 stacks and then be super careful in which order I have to deploy them etc..
This is just my personal opinion, your project structure may work very well too, but as stated above my goal is to give developers a lot of control and responsibility about their application AND the application-specific infrastructure and not become the ops / devops gatekeeper.
In fact I had wednesday an internal pulumi demo in front of some team members incl. the CTO and now regular developers already start modifying their app specific pulumi code on their own which signals to me that this works.brave-angle-33257
10/08/2018, 4:03 AMglamorous-printer-66548
10/08/2018, 4:23 AMbrave-angle-33257
10/08/2018, 4:31 AMglamorous-printer-66548
10/08/2018, 4:43 AMimport .. from
, export, arrow functions etc. is just official JavaScript (its in the spec) that has been introduced in the JS language over the last couple of years and which is worth to learn anyways if you’re dealing somewhere with JS. When I first poached TS in my team some people were scared and argued that TypeScript is so different and “non-standard” compared to JS. I told and showed them then that almost all the code I’ve shown just uses standard modern JS syntax features that they should learn anyways about unless they’re just targeting IE10 …brave-angle-33257
10/08/2018, 4:46 AMpulumi update
it's erroring with missing packages. I'd just like to make sure there's not something extra I need in my tsconfig.json or similar.glamorous-printer-66548
10/09/2018, 12:55 AMbrave-angle-33257
10/09/2018, 2:03 AM"dependencies": {
"@pulumi/azure": "latest",
"@pulumi/pulumi": "latest",
"@types/js-yaml": "latest"
}
to the package.json, do a npm install
and then in my IDE it shows the package as available, but when i run via pulumi update
it says not found.. it's probably something stupid but so far kicking my butthttps://s3-us-west-2.amazonaws.com/billeci-screenshots/index.ts__Untitled_Workspace_2018-10-08_19-04-05.png▾
https://s3-us-west-2.amazonaws.com/billeci-screenshots/Development__Development__tmux_new_-s_pulumi__20567_2018-10-08_19-05-18.png▾
glamorous-printer-66548
10/09/2018, 2:20 AMlatest
in your package.json. Simply run npm install <package_name>
which will generate an entry in your package.json with the latest version. I usually also set npm config set save-exact true
in my environment which will generate strict semver entries instead of a range like ^<version>
. Also make sure to check-in the package-lock.json if one got generated.pulumi update
. Just use pulumi up
as seen in most examples. Using pulumi update
you will just confuse people like me that never have seen this command before 😄npm install
3. Where is your Pulumi.yaml
4. what value is in the “main” field of your package.json
5. What is the content of your Pulumi.yaml
6. In which working directory did you execute pulumi up?brave-angle-33257
10/09/2018, 2:29 AM#1 in the main root of the project
#2 from that folder
#3 same folder
#4 don't see a "main" (below)
#5 (below)
#6 same
$ cat package.json
{
"name": "core-rg",
"devDependencies": {
"@types/node": "latest"
},
"dependencies": {
"@pulumi/azure": "latest",
"@pulumi/pulumi": "latest",
}
}
$ cat Pulumi.yaml
name: core-rg
runtime: nodejs
description: A minimal Azure TypeScript Pulumi program
template:
description: A minimal Azure TypeScript Pulumi program
config:
azure:environment:
description: The Azure environment to use (`public`, `usgovernment`, `german`,
`china`)
default: public
$ pwd
~/projects/pulumi/core-rg
$ ls -l
total 120
-rw------- 1 me staff 309 Oct 8 16:06 Pulumi.yaml
-rw------- 1 me staff 1467 Oct 8 19:21 index.ts
drwxr-xr-x 74 me staff 2368 Oct 8 17:31 node_modules
-rw-r--r-- 1 me staff 42378 Oct 8 18:58 package-lock.json
-rw------- 1 me staff 265 Oct 8 18:58 package.json
drwxr-xr-x 3 me staff 96 Oct 8 16:52 src
-rw------- 1 me staff 522 Oct 8 19:19 tsconfig.json
glamorous-printer-66548
10/09/2018, 2:31 AMbrave-angle-33257
10/09/2018, 2:32 AMglamorous-printer-66548
10/09/2018, 2:32 AMjs-yaml
as dependency?brave-angle-33257
10/09/2018, 2:33 AMglamorous-printer-66548
10/09/2018, 2:33 AM@types/js-yaml !== js-yaml
brave-angle-33257
10/09/2018, 2:33 AM$ cat package.json
{
"name": "core-rg",
"devDependencies": {
"@types/node": "latest"
},
"dependencies": {
"@pulumi/azure": "latest",
"@pulumi/pulumi": "latest",
"@types/sprintf-js": "^1.1.0"
}
}
glamorous-printer-66548
10/09/2018, 2:33 AMbrave-angle-33257
10/09/2018, 2:34 AMDiagnostics:
pulumi:pulumi:Stack: core-rg-core-rg-dev
info: { greeting: 'hello', name: 'world' }
import * as jsyaml from "js-yaml";
let doc = jsyaml.load('greeting: hello\nname: world');
console.log(doc)
$ npm install js-yaml --save
$ npm install @types/js-yaml --save
glamorous-printer-66548
10/09/2018, 2:38 AM.d.ts
files with contain the types).
- some packages (for example lodash) don’t come with typescript type definitions out of the box, often because the original author doesn’t use typescript himself. What then happens is that often the typescript community writes seperate type definitions for those packages which are published with the prefix @types, e.g. @types/lodash. So in case of lodash the actual runtime code is in the package “lodash” but if you want better type checking and code completion you CAN (you don’t have to, your code will run nevertheless) include the community type definitions by adding @types/lodash in addition to your package.jsonbrave-angle-33257
10/09/2018, 2:41 AMrgname = '{}-{}-{}'.format(
resource_type,
env_id,
region['id']
)
glamorous-printer-66548
10/09/2018, 2:43 AMbrave-angle-33257
10/09/2018, 2:43 AMglamorous-printer-66548
10/09/2018, 2:43 AMrgname = `${resource_type}-${env_id}-${region.id}`;
brave-angle-33257
10/09/2018, 2:44 AMglamorous-printer-66548
10/09/2018, 2:45 AM.format
things always so ugly to see 😄 . Fortunately we use python 3.6 internally which has support for f strings which is similar to JS template literals.brave-angle-33257
10/09/2018, 2:46 AMglamorous-printer-66548
10/09/2018, 2:46 AMbrave-angle-33257
10/09/2018, 2:47 AMglamorous-printer-66548
10/09/2018, 2:48 AMbrave-angle-33257
10/09/2018, 2:48 AMglamorous-printer-66548
10/09/2018, 2:50 AMbrave-angle-33257
10/09/2018, 2:51 AMglamorous-printer-66548
10/09/2018, 2:53 AMbrave-angle-33257
10/09/2018, 2:53 AMglamorous-printer-66548
10/09/2018, 2:55 AMbrave-angle-33257
10/09/2018, 2:58 AMglamorous-printer-66548
10/09/2018, 3:00 AMbrave-angle-33257
10/09/2018, 3:01 AMglamorous-printer-66548
10/09/2018, 3:02 AMbrave-angle-33257
10/09/2018, 3:04 AMglamorous-printer-66548
10/09/2018, 3:12 AMbrave-angle-33257
10/09/2018, 3:16 AMglamorous-printer-66548
10/09/2018, 3:26 AM