Can You Set a Nested Environment Variable in Kubernetes? - kubernetes

I have a pod running dotnet that leverages an appsettings.json file. I have the following entry for RabbitMq:
appsettings.json
{
...
"RabbitMQ": {
"HostName": "localhost",
"UserName": "someuser",
"Password": "somepassword"
}
}
I am trying to update the RabbitMQ.HostName property within my deployment yaml like so:
env:
- name: "RabbitMQ:HostName"
value: "rabbitmq-cluster-deployment.rabbitmq.svc.cluster.local"
It doesn't work. I have tried different variations but nothing looks like it sets it.
Does Kubernetes have a way of setting the "nested property" or no? I am aware that the : character is not allowed. I have tried using . which didn't throw an error, but also didn't work. The reason I was thinking it was a : is because that is how you would do it with dotnet.
Example: _configuration["RabbitMQ:HostName"]
Other "non-nested" environment variables are set just fine.

Remove the quotes from the name field and replace : with double underscores __
Instead of
env:
- name: "RabbitMQ:HostName"
value: "rabbitmq-cluster-deployment.rabbitmq.svc.cluster.local"
use
env:
- name: RabbitMQ__HostName
value: "rabbitmq-cluster-deployment.rabbitmq.svc.cluster.local"

Related

AZP: Is there a best practice to be able to "namespace" script tasks in yaml templates for usage of variables?

In Azure Pipelines: my main problem is, if I create a yml template and have some logic inside that template in a script task where I want to set a variable, i need the
name: "pseudonamespace" to reference that variable further down in that template via
$(pseudonamespace.variablename)
An example, where the script part does nothing overtly useful, but should demonstrate my problem:
mytemplate.yml:
parameters:
- name: isWindowsOnTarget
type: boolean
default: true
steps:
- script: |
if [ "${{lower(parameters.isWindowsOnTarget)}}" == "true" ]; then
delimiter="\\"
else
delimiter="/"
fi
echo "##vso[task.setvariable variable=myCoolVariable;isOutput=true]$delimiter"
name: MyFakeNameSpace
...
- task: SomeTask#0
inputs:
myInput: $(MyFakeNameSpace.myCoolVariable)
This codeblock works; but only, if, in a job, I only instanciate it once:
- template: mytemplate.yml#templates
parameters:
isWindowsOnTarget: true
If I would need that template twice, differently parameterized, I get the error that the name of the script block needs to be unique.
Is there any useful possibility I'm not currently thinking about other than to have an extra parameter for the template that I could basically just call "UniqueNamespace"?
There is no much space to move. Your task needs a unique name as later as you mention for output parameters it works like a namespace. So the best and the only way you have is to provide another parameter which would be task name.
parameters:
- name: isWindowsOnTarget
type: boolean
default: true
- name: taskName
type: string
steps:
- script: |
if [ "${{lower(parameters.isWindowsOnTarget)}}" == "true" ]; then
delimiter="\\"
else
delimiter="/"
fi
echo "##vso[task.setvariable variable=myCoolVariable;isOutput=true]$delimiter"
name: ${{ parameters.taskName }}
...
- task: SomeTask#0
inputs:
myInput: $(MyFakeNameSpace.myCoolVariable)
and then:
- template: mytemplate.yml#templates
parameters:
isWindowsOnTarget: true
taskName: MyFakeNameSpace
- template: mytemplate.yml#templates
parameters:
isWindowsOnTarget: true
taskName: MyFakeNameSpace2
In fact when you do not provide a name Azure DevOps assign a unique name. However, in this way you don't know the name till runtime.

How to add entries to Pulumi output for environment variables?

I've created an Output for environment variables in Pulumi just like https://github.com/pulumi/examples/blob/master/aws-ts-airflow/index.ts#L61 but I need to add one entry to these env vars for one of the containers I'm spinning up.
I'd like to do something like when declaring a container similar to https://github.com/pulumi/examples/blob/master/aws-ts-airflow/index.ts#L79-L85
"webserver": {
image: awsx.ecs.Image.fromPath("webserver", "./airflow-container"),
portMappings: [airflowControllerListener],
environment: environment + {name: "ANOTHER_ENV", value: "value"},
command: [ "webserver" ],
memory: 128,
},
I've tried playing around with pulumi.all (pulumi.all([environment, {name: "FLASK_APP", value: "server/__init.py"}])) and environment.apply but haven't been able to figure out how to contact to an Output.
Is this possible? If so, how?
You should be able to
const newEnvironment = environment.apply(env =>
env.concat({ name: "ANOTHER_ENV", value: "value"}));
// ...
"webserver": {
image: awsx.ecs.Image.fromPath("webserver", "./airflow-container"),
portMappings: [airflowControllerListener],
environment: newEnvironment,
command: [ "webserver" ],
memory: 128,
},

Passing environment variables to NOW

I am trying to pass firebase environment variables for deployment with now.
I have encoded these variables manually with base64 and added them to now with the following command:
now secrets add firebase_api_key_dev "mybase64string"
The encoded string was placed within speech marks ""
These are in my CLI tool and I can see them all using the list command:
now secrets ls
> 7 secrets found under project-name [499ms]
name created
firebase_api_key_dev 6d ago
firebase_auth_domain_dev 6d ago
...
In my firebase config, I am using the following code:
const config = {
apiKey: Buffer.from(process.env.FIREBASE_API_KEY, "base64").toString(),
authDomain: Buffer.from(process.env.FIREBASE_AUTH_DOMAIN,"base64").toString(),
...
}
In my now.json file I have the following code:
{
"env": {
"FIREBASE_API_KEY": "#firebase_api_key_dev",
"FIREBASE_AUTH_DOMAIN": "#firebase_auth_domain_dev",
...
}
}
Everything works fine in my local environment (when I run next) as I also have a .env file with these variables, yet when I deploy my code, I get the following error in my now console:
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type undefined
Does this indicate that my environment variables are not being read? What's the issue here? It looks like they don't exist at all
The solution was to replace my existing now.json with:
{
"build":{
"env": {
"FIREBASE_API_KEY": "#firebase_api_key",
"FIREBASE_AUTH_DOMAIN": "#firebase_auth_domain",
"FIREBASE_DATABASE_URL": "#firebase_database_url",
"FIREBASE_PROJECT_ID": "#firebase_project_id",
"FIREBASE_STORAGE_BUCKET": "#firebase_storage_bucket",
"FIREBASE_MESSAGING_SENDER_ID": "#firebase_messaging_sender_id",
"FIREBASE_APP_ID": "#firebase_app_id",
"FIREBASE_API_KEY_DEV": "#firebase_api_key_dev",
"FIREBASE_AUTH_DOMAIN_DEV": "#firebase_auth_domain_dev",
"FIREBASE_DATABASE_URL_DEV": "#firebase_database_url_dev",
"FIREBASE_PROJECT_ID_DEV": "#firebase_project_id_dev",
"FIREBASE_STORAGE_BUCKET_DEV": "#firebase_storage_bucket_dev",
"FIREBASE_MESSAGING_SENDER_ID_DEV": "#firebase_messaging_sender_id_dev",
"FIREBASE_APP_ID_DEV": "#firebase_app_id_dev"
}
}
}
I was missing the build header.
I had to contact ZEIT support to help me identify this issue.

Get Lambda Arn into Resources : Type: AWS::Lambda::Permission

I have the following in my serverless yml file :
lambdaQueueFirstInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: ServiceLambdaFunctionQualifiedArn
Action: ‘lambda:InvokeFunction’
Principal: sqs.amazonaws.com
and I have the following in the Outputs section :
Outputs:
ServiceLambdaFunctionQualifiedArn:
Value:
‘Fn::GetAtt’: [ lambdaQueueFirst, Arn ]
this comes back with a message:
Template error: instance of Fn::GetAtt references undefined resource lambdaQueueFirst
Am I missing something and if so, what? since it is very little in terms of help or examples…
Also, is there a better of getting the lambda arn into the permissions code? if so, what is it?
You can use the environment variables to construct the ARN value. In your case, you can define a variable in your provider section like below. You might need to modify a little bit according to your application.
service: serverless App2
provider:
name: aws
runtime: python3.6
region: ap-southeast-2
stage: dev
environment:
AWS_ACCOUNT: 1234567890 # use your own AWS ACCOUNT number here
# define the ARN of the function that you want to invoke
FUNCTION_ARN: "arn:aws:lambda:${self:provider.region}:${self:provider.environment.AWS_ACCOUNT}:function:${self:service}-${self:provider.stage}-lambdaQueueFirst"
Outputs:
ServiceLambdaFunctionQualifiedArn:
Value: "${self:provider.environment.FUNCTION_ARN}"
See this and serverless variables for aws for example.
you can do this:
resources:
Resources:
LoggingLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: { "Fn::GetAtt": ["LoghandlerLambdaFunction", "Arn" ] }
Action: lambda:InvokeFunction
Principal: { "Fn::Join" : ["", ["logs.", { "Ref" : "AWS::Region"}, ".amazonaws.com" ] ] }
reference:
https://github.com/andymac4182/serverless_example

How to pass jenkins build environment into pod using kubernetes plugin?

Env: Jenkins 2.73.1 & Kubernetes plugin 1.0
Inside the container, I like to get the normal jenkins build environment variable like BUILD_NUMBER
podTemplate(label: 'mypod', containers: [
containerTemplate(name: 'python', image: 'python:2.7.8', ttyEnabled: true)
]) {
node("mypod") {
echo sh(returnStdout: true, script: 'env')
container('python') {
stage('Checkout') {
sh "env"
}
}
}
}
So far in the code above, inside python, it doesn't have the traditional build variable.
Any solution to get those variables inside container?
You can use env.BUILD_NUMBER
i.e.
node{
echo env.BUILD_NUMBER
}
Also if you want a list of all the env vars that are available you can run
node{
echo "${env.getEnvironment()}"
}
These are the default jenkins plugins env vars but you can also set env vars for your kubernetes plugin build pods in the pod template, for example..
envVars: [
envVar(key: 'GOPATH', value: '/home/jenkins/go')
]),
FWIW here's that code being used https://github.com/fabric8io/fabric8-pipeline-library/blob/3834f0f/vars/goTemplate.groovy#L27
More details here