Script that checks GCloud project before deploy - shell

So today I basically fumbled a huge amount of traffic because I deployed a gcloud project while having the wrong project set. As you know, when we deploy to gcloud we have to make sure we choose the right project using gcloud config set project [PROJECT_NAME], unfortunately this is sometimes hard to remember to do as multiple projects require quick deployments to be sent out when bugs arise.
I was wondering if anyone had a good solution for this that runs a predeploy shell script which makes sure that you are deploying the right project when deploying.
Thanks in advance,
Nikita

#Ajordat's answer is good but I think there's a simpler solution.
If you unset the default project, then you'll be required to explicitly set --project=${PROJECT} on each gcloud command.
gcloud config unset project
Then, every gcloud command will require:
gcloud ... --project=${PROJECT} ...
This doesn't inhibit specifying an incorrect ${PROJECT} value in the commands but it does encourage a more considered approach.
A related approach is to define configurations (sets of properties) and to enable these before running commands. IMO this is problematic too and I recommend unsetting gcloud config properties and always being explicit.
See:
https://cloud.google.com/sdk/gcloud/reference/config/configurations

As seen in the documentation, the gcloud tool has some flags that are independent of the subcommand (app deploy) that is being used, such as --account, --verbosity or --log-http. One of these gcloud-wide flags is --project, which will let you specify the project you are deploying to.
Now, to deploy you must use a project, in your case since you have to deploy to different projects you must specify it somewhere. There's no workaround to specifying the project because the service must have somewhere to be deployed to. You have two options:
You can set the default project to the one you want to use:
gcloud config set project <project-name>
gcloud app deploy
Notice that you would have to set the project back again to the one you were previously using.
Or you can use the --project flag in order to specify where to deploy.
gcloud app deploy --project=<project-name>
I would recommend you to use the --project flag as it's more deployment specific and doesn't involve changing the default project. Moreover, you can keep working on the previous project ID since it doesn't change the default values, it's just a deploy to another project.
Notice that in the past you could specify the project on the app.yaml file with the application tag, but this was deprecated in favor of the --project flag.

Related

Using Helm For Deploying Spring Boot Microservice to K8s

We have build a few Microservices (MS) which have been deployed to our company's K8s clusters.
For current deployment, any one of our MSs will be built as a Docker image and they deployed manually using the following steps; and it works fine:
Create Configmap
Installing a Service.yaml
Installing a Deployment.yaml
Installing an Ingress.yaml
I'm now looking at Helm v3 to simplify and encapsulate these deployments. I've read a lot of the Helm v3 documentation, but I still haven't found the answer to some simple questions and I hope to get an answer here before absorbing the entire doc along with Go and SPRIG and then finding out it won't fit our needs.
Our Spring MS has 5 separate application.properties files that are specific to each of our 5 environments. These properties files are simple multi-line key=value format with some comments preceded by #.
# environment based values
key1=value1
key2=value2
Using helm create, I installed a chart called ./deploy in the root directory which auto-created ./templates and a values.yaml.
The problem is that I need to access the application.properties files outside of the Chart's ./deploy directory.
From helm, I'd like to reference these 2 files from within my configmap.yaml's Data: section.
./src/main/resource/dev/application.properties
./src/main/resources/logback.xml
And I want to keep these files in their current format, not rewrite them to JSON/YAML format.
Does Helm v3 allow this?
Putting this as answer as there's no enough space on the comments!
Check the 12 factor app link I shared above, in particular the section on configuration... The explanation there is not great but the idea is behind is to build one container and deploy that container in any environment without having to modify it plus to have the ability to change the configuration without the need to create a new release (the latter cannot be done if the config is baked in the container). This allows, for example, to change a DB connection pool size without a release (or any other config parameter). It's also good from a security point of view as you might not want the container running in your lower environments (dev/test/whatnot) having production configuration (passwords, api keys, etc). This approach is similar to the Continuous Delivery principle of build once, deploy anywhere.
I assume that when you run the app locally, you only need access to one set of configuration, so you can keep that in a separate file (e.g. application.dev.properties), and have the parameters that change between environments in helm environment variables. I know you mentioned you don't want to do this, but this is considered a good practice nowadays (might be considered otherwise in the future...).
I also think it's important to be pragmatic, if in your case you don't feel the need to have the configuration outside of the container, then don't do it, and probably using the suggestion I gave to change a command line parameter to pick the config file works well. At the same time, keep in mind the 12 factor-app approach in case you find out you do need it in the future.

Is it possible to avoid setting project_id explicitly when authing with service account?

I'm trying to authenticate in a bash script and enable my service account and I have cred.json. Here is what I tried:
gcloud auth activate-service-account --key-file=/etc/gcp-cred.json
The problem is that I have to set project explicitly:
gcloud config set project my_proj
Which is kind of redundant because gcp-cred.json contains this project already as a field:
"project_id": "my_proj"
Is there a way to avoid doing gcloud config set project explicitly and set it with gcp-cred.json?
No -- gcloud will not change your working core project when authenticating.
The trick here is that authenticating & setting your "default" working project for gcloud are separate concerns. You can set your project without authenticating, and you can authenticate without changing your project.
The logic here stems from the fact that an identity can have access to many projects. Even though a Service Account is homed to a particular project, it could very well be authorized to access any other project. So, the gcloud program makes no assumptions about which project you want your Service Account to act on.
Secondarily, in general you do not have to set your default working project for gcloud -- you can specify the project that is the target of your action with the flag --project PROJECT_ID. See docs for that gcloud flag here.

How do I deploy an Act framework app to Heroku?

There is no official support of Act on Heroku, however the Maven buildpack seems to do almost everything the app needs, except start it properly. Any recommended settings and/or Profiles to start the app properly?
The main two things to figure out were how to bind to the dynamically assigned port, and how to load from a different profile. This Procfile handles both of those things:
web: export act_env_http_port=$PORT && java $JAVA_OPTS -Dprofile=heroku -cp target/classes:target/dependency/* com.larvalabs.gifmsgbot.AppEntry
The environment variable that specifies the port is in a special (mostly undocumented format) that allows you to automatically override configuration settings. A tiny bit more info is the bug that contains the relevant changes: https://github.com/actframework/actframework/issues/636
Also note that I'm using a profile named heroku here, this is because I don't totally understand how the prod profile works yet, but I couldn't load settings from it when specifying -Dprofile=prod

Node (maven) to deploy the application to several environments

On Jelastic, I created a node for building an application (maven), there are several identical environments (NGINX + Spring Boot), the difference is in binding to its database and configured SSL.
The task is to ensure that after building the application (* .jar), deploy at the same time go to these several environments, how to implement it?
When editing a project, it is possible to specify only one environment, multi-selection is not provided.
it`s allowed to specify just one environment
We suggest creating a few environments using one Repository branch, and run updates by API https://docs.jelastic.com/api/#!/api/environment.Vcs-method-Update pushing whole code to VCS.
It's possible to use CloudScripting technology for attaching custom logic to onAfterBuildProject event and deploying the project to additional environments after build is complete. Please check this JPS as an example of the code syntax. Most likely you will need to use DeployProject API method.

gcloud automatic redeployment Golang app

I have a Golang app running on Google Cloud App Engine that I can update manually with "gcloud app deploy" but I cannot figure out how to schedule automatic redeployments. I'm assuming I have to use cron.yaml, but then I'm confused about what url to use. Basically it's just a web app with one main index.html page with changing content, and I would like to schedule automatic redeployments... how do I have to go about that?
If you want to automatically re-deploy your app when the code changes, you need what's called CI/CD (Continuous integration/deployment). What a CI does is, for each new commit to your repository, check out the new code and run a test script. If all the tests pass (or if you don't have any tests at all), the CI server can then deploy your code to App Engine, all automatically.
One free (for open-source projects) CI provider is Travis CI. To configure it, you need to make an account with Travis, and a file called .travis.yml in the root of your repository. To set up App Engine deploys, you can follow this guide to set up a service account and add the encrypted file to your repo. It will run a gcloud app deploy from a container on their servers, whenever you push code to a certain branch (master by default) in your repo.
Another option, which avoids setting up CI at all, is to simply change your app to generate the dynamic parts of the page when it gets requested. Reading the documentation for html/template would point you in the right direction.

Resources