Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ def setupCommonDockerImageConfig(project: Project): Project =
project
.settings(
dockerRepository := Some("localhost:5001"),
dockerBuildCommand := {
if (sys.props("os.arch") != "amd64") {
// use buildx with platform to build supported amd64 images on other CPU architectures
// this may require that you have first run 'docker buildx create' to set docker buildx up
dockerExecCommand.value ++ Seq(
"buildx",
"build",
"--platform=linux/amd64",
//"--platform=linux/arm64/v8",
"--load"
) ++ dockerBuildOptions.value :+ "."
} else dockerBuildCommand.value
},
dockerBaseImage := "eclipse-temurin:11.0.16.1_1-jdk-focal",
Docker / aggregate := false,
Compile / packageDoc / publishArtifact := false
Expand Down
7 changes: 0 additions & 7 deletions infra/Pulumi.yaml

This file was deleted.

44 changes: 44 additions & 0 deletions infra/aws-eks/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import besom.*
import besom.api.{aws, awsx, eks}

@main def main = Pulumi.run {
val appName = "vss"
val vpc = awsx.ec2.Vpc(
name = s"$appName-vpc",
awsx.ec2.VpcArgs(
cidrBlock = "10.1.0.0/16",
enableDnsHostnames = true,
enableDnsSupport = true
)
)

val cluster = eks.Cluster(
name = s"$appName-cluster",
eks.ClusterArgs(
vpcId = vpc.vpcId,
subnetIds = vpc.publicSubnetIds,
desiredCapacity = 2,
minSize = 1,
maxSize = 2,
storageClasses = "gp2"
)
)

val repo = aws.ecr.Repository(
s"$appName-repository",
aws.ecr.RepositoryArgs(
imageTagMutability = "MUTABLE"
)
)

val authorizationToken =
aws.ecr.getAuthorizationToken(aws.ecr.GetAuthorizationTokenArgs(registryId = repo.registryId))

Stack(cluster).exports(
registryEndpoint = authorizationToken.proxyEndpoint,
repositoryUrl = repo.repositoryUrl,
accessKeyId = authorizationToken.map(_.userName).asSecret,
secretAccessKey = authorizationToken.map(_.password).asSecret,
kubeconfig = cluster.kubeconfigJson
)
}
5 changes: 5 additions & 0 deletions infra/aws-eks/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: vss-aws-eks
runtime: scala
description: VSS AWS EKS infra
config:
aws:region: us-west-2
6 changes: 6 additions & 0 deletions infra/aws-eks/project.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//> using scala "3.3.3"
//> using options -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement
//> using plugin "org.virtuslab::besom-compiler-plugin:0.2.2"
//> using dep "org.virtuslab::besom-core:0.2.2"
//> using dep "org.virtuslab::besom-awsx:2.5.0-core.0.2"
//> using dep "org.virtuslab::besom-eks:2.2.1-core.0.2"
76 changes: 76 additions & 0 deletions infra/azure-aks/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import besom.*
import besom.api.azurenative

@main def main = Pulumi.run {
val appName = "vss"

val resourceGroup = azurenative.resources.ResourceGroup(s"$appName-resource-group")

val identity = azurenative.managedidentity.UserAssignedIdentity(
name = s"$appName-identity",
azurenative.managedidentity.UserAssignedIdentityArgs(resourceGroupName = resourceGroup.name)
)

val k8sCluster = azurenative.containerservice.ManagedCluster(
name = s"$appName-cluster",
azurenative.containerservice.ManagedClusterArgs(
resourceGroupName = resourceGroup.name,
dnsPrefix = appName,
identity = azurenative.containerservice.inputs.ManagedClusterIdentityArgs(
`type` = azurenative.containerservice.enums.ResourceIdentityType.UserAssigned,
userAssignedIdentities = List(identity.id)
),
agentPoolProfiles = List(
azurenative.containerservice.inputs.ManagedClusterAgentPoolProfileArgs(
count = 1,
vmSize = "Standard_DS2_v2",
mode = azurenative.containerservice.enums.AgentPoolMode.System,
name = "agentpool",
osType = azurenative.containerservice.enums.OsType.Linux
)
)
)
)

val kubeconfig = azurenative.containerservice
.listManagedClusterUserCredentials(
azurenative.containerservice.ListManagedClusterUserCredentialsArgs(
resourceName = k8sCluster.name,
resourceGroupName = resourceGroup.name
)
)
.kubeconfigs
.map(_.head.value)

val registry = azurenative.containerregistry.Registry(
name = s"$appName-registry",
azurenative.containerregistry.RegistryArgs(
resourceGroupName = resourceGroup.name,
registryName = s"${appName}Registry",
sku = azurenative.containerregistry.inputs.SkuArgs(
name = azurenative.containerregistry.enums.SkuName.Basic
),
adminUserEnabled = true
),
opts = opts(deleteBeforeReplace = true)
)

val registryCredentials = azurenative.containerregistry.listRegistryCredentials(
azurenative.containerregistry.ListRegistryCredentialsArgs(
registryName = registry.name,
resourceGroupName = resourceGroup.name
)
)

Stack.exports(
registryEndpoint = registry.loginServer,
repositoryUrl = p"${registry.loginServer}/$appName",
accessKeyId = registryCredentials.username,
// TODO make it secret
secretAccessKey = registryCredentials.passwords.map(_.head.head).value,
// TODO make it secret
kubeconfig = kubeconfig.map(base64Decoder)
)
}

private def base64Decoder: String => String = v => new String(java.util.Base64.getDecoder.decode(v.getBytes))
5 changes: 5 additions & 0 deletions infra/azure-aks/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: vss-azure-aks
runtime: scala
description: VSS Azure AKS infra
config:
azure-native:location: East US
5 changes: 5 additions & 0 deletions infra/azure-aks/project.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//> using scala "3.3.3"
//> using options -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement
//> using plugin "org.virtuslab::besom-compiler-plugin:0.2.2"
//> using dep "org.virtuslab::besom-core:0.2.2"
//> using dep "org.virtuslab::besom-azure-native:2.29.0-core.0.2"
117 changes: 117 additions & 0 deletions infra/gcp-gke/Main.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import besom.*
import besom.api.gcp

enum GCPService(val name: String):
case KubernetesEngine extends GCPService("container.googleapis.com")
case ArtifactRegistry extends GCPService("artifactregistry.googleapis.com")

@main def main = Pulumi.run {
val appName = "vss"

// Enable GCP service(s) for the current project
val enableServices: Map[GCPService, Output[gcp.projects.Service]] =
GCPService.values
.map(api => api -> projectService(api))
.toMap

val k8sCluster = gcp.container.Cluster(
name = s"$appName-cluster",
gcp.container.ClusterArgs(
deletionProtection = false,
initialNodeCount = 1,
minMasterVersion = "1.29.1-gke.1589018",
nodeVersion = "1.29.1-gke.1589018",
nodeConfig = gcp.container.inputs.ClusterNodeConfigArgs(
machineType = "n1-standard-1",
oauthScopes = List(
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring"
)
)
),
opts = opts(dependsOn = enableServices(GCPService.KubernetesEngine))
)

val context = p"${k8sCluster.project}_${k8sCluster.location}_${k8sCluster.name}"
val kubeconfig =
p"""apiVersion: v1
|clusters:
|- cluster:
| certificate-authority-data: ${k8sCluster.masterAuth.clusterCaCertificate.map(_.get).asPlaintext}
| server: https://${k8sCluster.endpoint}
| name: $context
|contexts:
|- context:
| cluster: $context
| user: $context
| name: $context
|current-context: $context
|kind: Config
|preferences: {}
|users:
|- name: $context
| user:
| exec:
| apiVersion: client.authentication.k8s.io/v1beta1
| command: gke-gcloud-auth-plugin
| installHint: Install gke-gcloud-auth-plugin for use with kubectl by following
| https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
| provideClusterInfo: true
|""".stripMargin

val repository = gcp.artifactregistry.Repository(
name = s"$appName-repository",
gcp.artifactregistry.RepositoryArgs(
repositoryId = s"$appName-repository",
format = "DOCKER"
),
opts = opts(dependsOn = enableServices(GCPService.ArtifactRegistry))
)

val serviceAccount = gcp.serviceaccount.Account(
name = s"$appName-service-account",
gcp.serviceaccount.AccountArgs(
accountId = s"$appName-service-account",
displayName = "Service Account for Artifact Registry"
)
)

val serviceAccountKey = gcp.serviceaccount.Key(
name = s"$appName-service-account-key",
gcp.serviceaccount.KeyArgs(
serviceAccountId = serviceAccount.accountId,
privateKeyType = "TYPE_GOOGLE_CREDENTIALS_FILE"
)
)

val repositoryIamBinding = gcp.artifactregistry.RepositoryIamMember(
name = s"$appName-service-iam-everyone",
gcp.artifactregistry.RepositoryIamMemberArgs(
repository = repository.repositoryId,
role = "roles/artifactregistry.repoAdmin",
member = "allUsers"
)
)

Stack(repositoryIamBinding).exports(
registryEndpoint = p"${k8sCluster.location}-docker.pkg.dev",
repositoryUrl = p"${k8sCluster.location}-docker.pkg.dev/${k8sCluster.project}/${repository.repositoryId}/$appName",
accessKeyId = "_json_key_base64",
secretAccessKey = serviceAccountKey.privateKey,
kubeconfig = kubeconfig
)
}

private def projectService(api: GCPService)(using Context): Output[gcp.projects.Service] =
gcp.projects.Service(
name = s"enable-${api.name.replace(".", "-")}",
gcp.projects.ServiceArgs(
service = api.name,
/* if true - at every destroy this will disable the dependent services for the whole project */
disableDependentServices = true,
/* if true - at every destroy this will disable the service for the whole project */
disableOnDestroy = true
)
)
6 changes: 6 additions & 0 deletions infra/gcp-gke/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: vss-gcp-gke
runtime: scala
description: VSS GCP GKE infra
config:
gcp:project: besom-413811
gcp:region: us-west1
5 changes: 5 additions & 0 deletions infra/gcp-gke/project.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//> using scala "3.3.3"
//> using options -Werror -Wunused:all -Wvalue-discard -Wnonunit-statement
//> using plugin "org.virtuslab::besom-compiler-plugin:0.2.2"
//> using dep "org.virtuslab::besom-core:0.2.2"
//> using dep "org.virtuslab::besom-gcp:7.9.0-core.0.2"
11 changes: 11 additions & 0 deletions infra/k8s/Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: vss
description: VSS infra
runtime: scala
config:
vss:localRepository: "localhost:5001/vss-zio"
vss:imageTag: "0.1.0-SNAPSHOT"
vss:cluster: "remote"
vss:clusterOrg: "organization"
vss:clusterProject: "vss-aws-eks"
vss:clusterStack: "dev"
grafana:auth: "admin:admin"
2 changes: 2 additions & 0 deletions infra/project.scala → infra/k8s/project.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using scala 3.3.3
//> using dep org.virtuslab::besom-core:0.2.2
//> using dep org.virtuslab::besom-kubernetes::4.8.0-core.0.2
//> using dep org.virtuslab::besom-docker:4.5.1-core.0.2
//> using dep org.virtuslab::besom-grafana:0.2.0-core.0.2
11 changes: 11 additions & 0 deletions infra/k8s/src/main/scala/Cluster.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
enum Cluster(val name: String):
case Local extends Cluster("local")
case Remote extends Cluster("remote")

object Cluster:
val parseName = Cluster.values
.map(c => c.name -> c)
.toMap
.withDefault(str =>
throw Exception(s"$str value not allowed. Available values are local or remote. Change vss:cluster configuration")
)
Loading