azbuilder / terrakube Goto Github PK
View Code? Open in Web Editor NEWOpen source IaC Automation and Collaboration Software.
Home Page: https://docs.terrakube.io
License: Apache License 2.0
Open source IaC Automation and Collaboration Software.
Home Page: https://docs.terrakube.io
License: Apache License 2.0
Currently the Terraform module needs to be stored on a Storage Account.
Add support for GIT repo as a source option.
To facilitate deployment in kubernetes it would be nice to have a helm chart, to deploy all the components
Add support in API to manage Providers
/api/v1/organization/{{organizationId}}/provider
Request example
{
"data": {
"type": "provider",
"attributes": {
"name": "Sample Provider Name",
"description": "Sample Provider Description"
}
}
}
And add ability to manage different provider versions
/api/v1/organization/{{organizationId}}/provider/{{providerId}}/version
{
"data": {
"type": "version",
"attributes": {
"name": "1.0.0"
}
}
}
And each version should support different platforms
/api/v1/organization/{{organizationId}}/provider/{{providerId}}/version/{{versionId}}/platform
{
"data": {
"type": "platform",
"attributes": {
"os": "linux",
"arch":"amd64"
}
}
}
Sometimes refreshing bitbucket token fails with the following error
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689) ~[spring-aop-5.3.14.jar:5.3.14]
at org.azbuilder.api.plugin.vcs.TokenService$$EnhancerBySpringCGLIB$$ae52833.refreshAccessToken(<generated>) ~[classes/:1.7.3]
at org.azbuilder.api.plugin.scheduler.ScheduleVcs.execute(ScheduleVcs.java:39) ~[classes/:1.7.3]
at org.azbuilder.api.plugin.scheduler.ScheduleVcs$$FastClassBySpringCGLIB$$5fb5ebcb.invoke(<generated>) ~[classes/:1.7.3]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783) ~[spring-aop-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.14.jar:5.3.14]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.14.jar:5.3.14]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.14.jar:5.3.14]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753) ~[spring-aop-5.3.14.jar:5.3.14]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698) ~[spring-aop-5.3.14.jar:5.3.14]
at org.azbuilder.api.plugin.scheduler.ScheduleVcs$$EnhancerBySpringCGLIB$$130a8af5.execute(<generated>) ~[classes/:1.7.3]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.2.jar:na]
... 1 common frames omitted
Suppressed: java.lang.Exception: #block terminated with an error
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99) ~[reactor-core-3.4.10.jar:3.4.10]
... 22 common frames omitted
Caused by: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 10000ms in 'flatMap' (and no fallback has been configured)
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.handleTimeout(FluxTimeout.java:295) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.publisher.FluxTimeout$TimeoutMainSubscriber.doTimeout(FluxTimeout.java:280) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.publisher.FluxTimeout$TimeoutTimeoutSubscriber.onNext(FluxTimeout.java:419) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.propagateDelay(MonoDelay.java:271) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.publisher.MonoDelay$MonoDelayRunnable.run(MonoDelay.java:286) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) ~[reactor-core-3.4.10.jar:3.4.10]
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28) ~[reactor-core-3.4.10.jar:3.4.10]
at java.base/java.util.concurrent.FutureTask.run(Unknown Source) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:na]
at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]
2022-01-14T14:00:10.479545126Z
In order to enable authentication in the open registry and allows to use terraform login azbserver.com
is required to implement Terraform login protocol
{
"login.v1": {
"client": "terraform-cli",
"grant_types": ["authz_code"],
"authz": "/oauth/authorization",
"token": "/oauth/token",
"ports": [10000, 10010],
}
}
Refresh token for bitbucket sometime fails with timeout error
[id:6c2ba171-2, L:/10.1.0.7:34082 - R:bitbucket.org/18.205.93.2:443] The connection observed an error
io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection timed out
2021-12-15 14:15:44.146 ERROR 1 --- [ryBean_Worker-5] org.quartz.core.JobRunShell : Job DEFAULT.Terrakube_Vcs_24696aae-1a3b-44c4-92e5-cc33348acafa threw an unhandled Exception:
org.springframework.web.reactive.function.client.WebClientRequestException: readAddress(..) failed: Connection timed out; nested exception is io.netty.channel.unix.Errors$NativeIoException: readAddress(..) failed: Connection timed out
at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:141) ~[spring-webflux-5.3.13.jar:5.3.13]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ? Request to POST https://bitbucket.org/site/oauth2/access_token [DefaultWebClient]
Stack trace:
at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:141) ~[spring-webflux-5.3.13.jar:5.3.13]
at reactor.core.publisher.MonoErrorSupplied.subscribe(MonoErrorSupplied.java:55) ~[reactor-core-3.4.9.jar:3.4.9]
at reactor.core.publisher.Mono.subscribe(Mono.java:4338) ~[reactor-core-3.4.9.jar:3.4.9]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.9.jar:3.4.9]
Simplify with one single endpoint and add a field for type
It looks like cluster mode is not enable by default.
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is not clustered.
There is a lot of community tools for Terraform right now and probably the best option to run custom tools in a flow is to create a Plugin #37 this could be required a certain amount of time to create a wrapper in a plugin.
So an alternative option is allow to use custom commands inside a template. so once Templates are supporte #68, allow users to run terraform open source tools without the need to create a plugin or wrapper, this empower user to access already existing tools without the need to wait until a plugin is available.
Lets say we want to use terratag in our template https://github.com/env0/terratag but there is not an available plugin yet for that.
YAML
run:
- terraform: init
- commad: "terratag --tags {\"environment_id\": \"prod\"} "
url: "https://github.com/env0/terratag/releases/download/v0.1.29/terratag_0.1.29_linux_amd64.tar.gz"
enforcement-level: mandatory
- terraform: plan
- terraform: apply
So in this case after the command: reserved word a url with a tar.gz file is optional, terrakube will download and unzip the file and then will be run the command, so terrakube will execute
terratag -tags={\"environment_id\": \"prod\"}
enforcement-level : advisory tasks can not block a run from completing. If the command fails, a warning will be displayed on the run but it will proceed.
mandatory commands can block a run from completing. If the command fails (including a timeout or unexpected error condition), a warning will be displayed on the run and the run will transition to an Errored state.
Hashicorp just released Run Tasks Support in Terraform cloud https://www.hashicorp.com/blog/terraform-cloud-run-tasks-beta-now-available, and because they already had support for tools like snyk, infracost, bridgecrew, etc.
Should be nice if Terrakube could reuse all the available run tasks.
So once Templates are supported #68, please allow to define run tasks inside a template, should be something like this
YAML
run:
- terraform: plan
- run-task:
name: "snyk"
url: "http://snyk/run/task"
enforcement-level: mandatory
hmac-key: "mykey"
- terraform: apply
Name (required): A human-readable name for the run task.
URL (required): The URL where your external service is listening for a run tasks payload. (https://www.terraform.io/docs/cloud/api/run-tasks.html)
hmac-key (optional): A key that your remote endpoint can use to verify that requests are originating from Terrakube.
enforcement-level : advisory tasks can not block a run from completing. If the task fails, a warning will be displayed on the run but it will proceed.
mandatory tasks can block a run from completing. If the task fails (including a timeout or unexpected remote error condition), a warning will be displayed on the run and the run will transition to an Errored state.
For this case Terrakube will create a request to the url using the run task payload (https://www.terraform.io/docs/cloud/api/run-tasks.html) and will process the response, if the result is ok will continue with the following step, depending on the enforcement level
We need to update github action to include the image for the open-registry
Add name field in each step in order to identify it with a user friendly name in UI
flow:
- type: "terraformPlan"
name: "Plan"
step: 100
- type: "terraformApply"
name: "Apply"
step: 200
Elide provide support to add test cases for the API.
Add support to show the cost estimate inside a job
Para implementar el protocolo se debe seguir las siguientes condiciones
Por ejemplo al publicar un modulo para mediaservices en la organizacion azborg usando una instancia de azb server https://azbserver.com el source deberia ser
module "media" {
source = "azbserver.com/azborg/mediaservices/azurerm"
}
{
"modules.v1": "https://azbserver.com/terraform/modules/v1/"
}
Debe devolver un json con todas las versiones disponibles para el modulo
{
"modules": [
{
"versions": [
{"version": "1.0.0"},
{"version": "1.1.0"},
{"version": "2.0.0"}
]
}
]
}
El body de la respuesta debe estar vacia y debe contener un header X-Terraform-Get con el url donde se encuentre el zip para descargar el modulo
Ejemplo de header:
X-Terraform-Get: https://azbserver.com/terraform/modules/v1/azborg/mediaservices/azurerm/1.0.0/module.zip
Allow clients (CLI, UI) to connect in real time to Terraform Logs while the process is running.
Changes required:
Modify endpoint {{server}}/api/v1/organization/{{organizationId}}/job
Create a new property inside Jobs: "log-read-url"
Modify AzBuilder Executor
to update log-read-url with a log location. AzBuilder Executor
must flush the logs to the location more frequently so CLI and UI can read the updates
Sometimes you need some infraestructure deployed in a specific date or you need a infraestructure up and running only in working hours, so should be nice have workspaces with the option to create and destroy in specific time.
For example if I am creating some infraestructure only for testing purposes, I can specify that workspace should run at 8:00 am all the days and should be destroyed at 5:00 pm,
Or if I need some infraestructure for weekend trainings, I can schedule that workspaces should be run at 10 am on saturdays and should be destroyed at 5 pm on sundays
So add a 2 new fields in workspaces:
Authenticated guest Azure AD users does not include UPN field in token and it breaks the authentication.
It breaks email validation
https://github.com/AzBuilder/azb-server/blob/main/api/src/main/java/org/azbuilder/api/plugin/security/user/azure/AzureAuthenticatedUserImpl.java
@Override public String getEmail(User user) { return (String) getAzureAdPrincipal(user).getAttributes().get("upn"); }
Support should be similar to
https://www.terraform.io/docs/cloud/vcs/github.html
Create the API definition for the server
Add a new field in the workspaces api to specify a date in which the workspace will be destroyed,
Modify executor to check expire date in Workspaces and execute a Terraform destroy on the specified date
Bring support to run Terraform workflow remotely in AZB Server using Terraform CLI.
So in my local tf files I can configure remote backend
terraform {
backend "remote" {
hostname = "azbserver.com"
organization = "azb-organization"
workspaces {
name = "myWorkspace"
}
}
}
And after run Apply or Plan the runs should execute remotely in the remote AZB Server
More information about CLI Driven Workflow: https://www.terraform.io/docs/cloud/run/cli.html
Support for elide 6.0 READ LifeCycleHookBinding was removed
This build is failing for more detail:
#88
Templates will help teams to define a custom flow inside Terrakube, not all the teams required the same standard
Terraform init > Terraform Plan > Terraform Apply flow, so Templates in the future will be the option to customize the flow.
This issue is only to support the standard jobs commands that already exists in the template (plan, apply, deploy)
By default all the workspaces will use the standard flow
In order to execute a Job command the yaml will use the reserved word terraform:
followed by the command, example terraform: plan, terraform: apply.
So the terraform: plan
in the yaml file is equivalent to
{
"data": {
"type": "job",
"attributes": {
"command": "plan"
}
}
and the terraform: apply
in the yaml file is equivalent to
{
"data": {
"type": "job",
"attributes": {
"command": "apply"
}
}
Define a standard template:
YAML
run:
- terraform: plan
- terraform: apply
API
{
"data": {
"type": "template",
"attributes": {
"id":"template-id",
"name": "StandardTemplate",
"description":"Standard Terraform Template"
"version": "1.0.0",
"template" : "terraform: plan
terraform: apply"
}
}
}
Destroy the resources after the apply (Useful for testing workspaces)
YAML
run:
- terraform: plan
- terraform: apply
- terraform: destroy
API
{
"data": {
"type": "template",
"attributes": {
"id":"template-id",
"name": "ApplyDestroy",
"description":"Destroy all the resources after apply successfully"
"version": "1.0.0",
"template" : "terraform: plan
terraform: apply
terraform: destroy"
}
}
}
Finally add a new field in the workspace API in order to set the specific Template for that workspace
Publish docker image when a new version is released
Create new endpoint for VCS connection with fields:
Type: Github/Bitbucket/GitLab
Token: (Oauth Token to access repository)
Dont show field token to any user or super users, only service accounts can see the value
Modify Workspace repository and add relationship to VCS
Terraform registry has an access issue
2021-11-13 22:38:48.137 INFO 1 --- [ task-320] o.a.a.r.c.template.TeamViewTemplate : team view template e611d71a-199d-4760-8d73-c315fb01b3e5
2021-11-13 22:38:48.137 INFO 1 --- [ task-320] o.a.a.p.s.g.a.AzureAdGroupServiceImpl : Search User Id null
2021-11-13 22:38:48.138 INFO 1 --- [ Thread-917] c.azure.identity.ClientSecretCredential : Azure Identity => getToken() result for scopes [https://graph.microsoft.com/.default]: SUCCESS
2021-11-13 22:38:48.195 INFO 1 --- [ task-320] o.a.a.p.s.g.a.AzureAdGroupServiceImpl : Search Group Id AZB_USER
2021-11-13 22:38:48.196 INFO 1 --- [ Thread-918] c.azure.identity.ClientSecretCredential : Azure Identity => getToken() result for scopes [https://graph.microsoft.com/.default]: SUCCESS
2021-11-13 22:38:48.256 INFO 1 --- [ Thread-919] c.azure.identity.ClientSecretCredential : Azure Identity => getToken() result for scopes [https://graph.microsoft.com/.default]: SUCCESS
2021-11-13 22:38:48.305 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404Graph service exception Error code: Request_ResourceNotFound
2021-11-13 22:38:48.306 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404Error message: Resource 'null' does not exist or one of its queried reference-property objects are not present.
2021-11-13 22:38:48.306 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404
2021-11-13 22:38:48.307 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404POST https://graph.microsoft.com/v1.0/users/null/microsoft.graph.checkMemberGroups
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404SdkVersion : graph-java/v5.0.0
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404[...]
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404404 : Not Found
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404[...]
2021-11-13 22:38:48.308 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404
2021-11-13 22:38:48.309 ERROR 1 --- [ task-320] global : CoreHttpProvider[sendRequestInternal] - 404[Some information was truncated for brevity, enable debug logging for more details]
2021-11-13 22:38:48.309 ERROR 1 --- [ task-320] global : Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code: Request_ResourceNotFound
Error message: Resource 'null' does not exist or one of its queried reference-property objects are not present.
POST https://graph.microsoft.com/v1.0/users/null/microsoft.graph.checkMemberGroups
SdkVersion : graph-java/v5.0.0
Add new fields to add the user who creates the Job:
Upgrade Elide from version 4.7.2 to 5.0.4 and fix the swagger endpoint
Update the datasource to support mysql and postgresql database
Add a new configuration properties to support the new database like the one used by sql azure
https://github.com/AzBuilder/azb-server/blob/main/api/src/main/java/org/azbuilder/api/plugin/datasource/azure/AzureDataSourceProperties.java
In VCS endpoint allow clients to define an unique id, and then use that id to generate the callback url logic
We need to validate Azure Active Directory user before executing any change in the API.
How security works:
In the output logs include ANSI characters in order to support Terraform color in UI and CLI results
Currently Terraform Enterprise support approvals in a Run
So add the option to use approvals in Terrakube, once Templates are supported #68 . Add the option to define approvals using a template. In the template an approval will start with approval:
and the Team name that must approve in order to continue with the execution
Example
YAML
terrakube: plan
approval: AZ_USER
terrakube: apply
approval: AZ_ADMIN
terrakube: destroy
API
{
"data": {
"type": "template",
"attributes": {
"id":"template-id",
"name": "ApplyDestroy",
"description":"Destroy all the resources after apply successfully"
"version": "1.0.0",
"template" : "terrakube: plan
approval: AZ_USER
terrakube: apply
approval: AZ_ADMIN
terrakube: destroy"
}
}
}
Add support to use github webhooks to start jobs
Migrate the Job to use Quartz instead of the spring boot scheduler to have better control over pending jobs execution
Allow to import custom extensions into jobs:
{
"data": {
"type": "plugin",
"attributes": {
"id":"terratest-id",
"name": "Terratest",
"description":"Terratest makes it easier to write automated tests for your infrastructure code. It provides a variety of helper functions and patterns for common infrastructure testing tasks"
"version": "0.37.7",
"command": "terratest", --this value will be used as command parameter when a new job is created
"source": "https://github.com/gruntwork-io/terratest/releases/download/v0.37.7/terratest.jar"--this value could be a java wrapper for the app containing a method with the specific logic to execute, the job-executor must download the jar and call the "RUN" method when this command is executed
}
}
}
**Using plugins in a template **
A plugin could be identified in a template using the plugin:
follwing by the plugin name
YAML
terrakube: plan
terrakube: apply
plugin: terratest
API
{
"data": {
"type": "template",
"attributes": {
"id":"template-id",
"name": "Terratest",
"description":"Running terratest after apply"
"version": "1.0.0",
"template" : "terrakube: plan
terrakube: apply
plugin: terratest"
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.