Giter Club home page Giter Club logo

one-time-secret's Introduction

Hi there, I'm Raphi - aka swissbuechi ๐Ÿ‘‹

I am a: IT Enthusiast, Snowboarder, Hip-Hop DJ, Breakdancer
I work as: Software Engineer at netider.ch it solutions, System Engineer at axelion AG, Cloud Engineer at null
I work on: Automation, Security (Infrastructure, Software), Cloud Migrations, Endpoint Management
Tools I use: Terraform, Vue, Java, Go, Powershell, Bash
Cloud technologies I know very well: Azure, Google Cloud Platform
I'm not a fan of: Overengineering, ClickOps

Projects
๐Ÿ” You need to securely send encrypted one time messages? Passwords, keys? ๐Ÿ‘‰๐Ÿป one-time-secret
๐Ÿ“‹ You want to secure your Microsoft Entra ID tenant? EXO, SPO or Entra ID? ๐Ÿ‘‰๐Ÿป AzureAdDeployer

Contributions
๐Ÿ’ป Homebrew is the Nr. 1 macOS package manager to install and update all kind of applicaitons. ๐Ÿ‘‰๐Ÿป homebrew-autoupdate
๐Ÿค– Using github dependabot and noticed it's not updating your docker-compose.yml files? ๐Ÿ‘‰๐Ÿป simple-compose-service-updates

๐Ÿ“• Latest Blog Posts

โžก๏ธ more blog posts...


one-time-secret's People

Contributors

automergebot-bot[bot] avatar dependabot[bot] avatar swissbuechi avatar

Stargazers

 avatar  avatar

Watchers

 avatar

Forkers

eranchetz

one-time-secret's Issues

Add terraform documentation

Terraform Service Principal

az ad sp create-for-rbac --name SERVICE_GITLAB_TERRAFORM --role Contributor --scopes /subscriptions/<id>

Pipeline variables

Terraform

  • SP_CLIENT_ID
  • SP_CLIENT_SECRET
  • SUBSCRIPTION_ID
  • TENANT_ID

ots

  • TF_VAR_ots_vault_cert
  • TF_VAR_ots_vault_cert_key
  • TF_VAR_ots_vault_token

backend.tf

terraform {
  backend "http" {
  }
}

provider.tf

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.53.0"
    }
  }
}

provider "azurerm" {
  features {}
}

axe-ots/config/vault.hcl

backend "file" {
  path = "/vault/file"
}

listener "tcp" {
  address       = "0.0.0.0:8200"
  tls_cert_file = "/vault/cert/cert.pem"
  tls_key_file  = "/vault/cert-key/cert.key"
}

disable_mlock = true

seal "azurekeyvault" {
}

axe-ots/css/custom.css

/* Custom Font */
@font-face {
  font-family: Rubik;
  src: url(../font/Rubik.ttf);
}

body {
  font-family: 'Rubik', sans-serif;
}

button {
  font-family: 'Rubik', sans-serif;
  font-size: 18px;
}

.success-encrypted {
  font-size: 18px;
}

.subtitle {
  font-size: 18px;
}

/* Custom Wallpaper  */
body {
  /* background-image: url("../img/background/background.jpg"); */
  background-color: #343a40;
}

/* Custom Color */
button:hover {
  background-color: rgba(76, 205, 79, 0.7);
}

.encrypt {
  background-color: #4ccd4f;
}

.clipboard {
  background-color: #4ccd4f;
}

/* Custom Logo size */
.logo {
  width: 250px;
}

axe-ots.tf

resource "azurerm_resource_group" "axe-ots" {
  name     = "axe-rg-ots"
  location = var.location
}

data "azurerm_client_config" "current" {}

resource "azurerm_key_vault" "axe-ots" {
  name                        = "axe-kv-ots"
  location                    = azurerm_resource_group.axe-ots.location
  resource_group_name         = azurerm_resource_group.axe-ots.name
  enabled_for_disk_encryption = true
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = false
  sku_name                    = "standard"
  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id
    key_permissions = [
      "Create",
      "Delete",
      "Get",
      "Purge",
      "Recover",
      "Update",
      "GetRotationPolicy",
      "SetRotationPolicy"
    ]
  }
  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = azurerm_user_assigned_identity.axe-aci-ots.principal_id
    key_permissions = [
      "Get",
      "WrapKey",
      "UnwrapKey",
    ]
  }
}

resource "azurerm_key_vault_key" "axe-ots" {
  name         = "ots"
  key_vault_id = azurerm_key_vault.axe-ots.id
  key_type     = "RSA"
  key_size     = 4096
  key_opts = [
    "decrypt",
    "encrypt",
    "sign",
    "unwrapKey",
    "verify",
    "wrapKey"
  ]
}

resource "azurerm_storage_account" "axe-ots" {
  name                     = "axestots"
  resource_group_name      = azurerm_resource_group.axe-ots.name
  location                 = azurerm_resource_group.axe-ots.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

resource "azurerm_storage_share" "axe-ots" {
  name                 = "vault"
  storage_account_name = azurerm_storage_account.axe-ots.name
  quota                = 1
}

resource "azurerm_storage_share" "axe-ots-acme" {
  name                 = "acme"
  storage_account_name = azurerm_storage_account.axe-ots.name
  quota                = 1
}

resource "azurerm_storage_share" "axe-ots-icons" {
  name                 = "icons"
  storage_account_name = azurerm_storage_account.axe-ots.name
  quota                = 1
}

# resource "azurerm_storage_share" "axe-ots-background" {
#   name                 = "background"
#   storage_account_name = azurerm_storage_account.axe-ots.name
#   quota                = 1
# }

resource "azurerm_user_assigned_identity" "axe-aci-ots" {
  location            = azurerm_resource_group.axe-ots.location
  name                = "axe-aci-ots"
  resource_group_name = azurerm_resource_group.axe-ots.name
}

resource "azurerm_container_group" "axe-ots" {
  name                = "axe-aci-ots"
  location            = azurerm_resource_group.axe-ots.location
  resource_group_name = azurerm_resource_group.axe-ots.name
  ip_address_type     = "Public"
  dns_name_label      = "axe-aci-ots"
  os_type             = "Linux"
  restart_policy      = "Never"
  exposed_port {
    port     = 80
    protocol = "TCP"
  }
  exposed_port {
    port     = 443
    protocol = "TCP"
  }
  identity {
    type = "UserAssigned"
    identity_ids = [
      azurerm_user_assigned_identity.axe-aci-ots.id
    ]
  }
  container {
    name   = "vault"
    image  = "hashicorp/vault:latest"
    cpu    = "0.5"
    memory = "0.5"
    ports {
      port     = 8200
      protocol = "TCP"
    }
    commands = [
      "vault", "server", "-config=/vault/config/vault.hcl"
    ]
    environment_variables = {
      "VAULT_CACERT"                   = "/vault/cert/cert.pem"
      "VAULT_ADDR"                     = "https://localhost:8200"
      "VAULT_AZUREKEYVAULT_VAULT_NAME" = "axe-kv-ots"
      "VAULT_AZUREKEYVAULT_KEY_NAME"   = "ots"
      "AZURE_TENANT_ID"                = data.azurerm_client_config.current.tenant_id
    }
    volume {
      name       = "vault-config"
      mount_path = "/vault/config"
      secret = {
        "vault.hcl" = filebase64("${path.module}/axe-ots/config/vault.hcl")
      }
    }
    volume {
      name       = "vault-cert"
      mount_path = "/vault/cert"
      secret = {
        "cert.pem" = base64encode(var.ots_vault_cert)
      }
    }
    volume {
      name       = "vault-cert-key"
      mount_path = "/vault/cert-key"
      secret = {
        "cert.key" = base64encode(var.ots_vault_cert_key)
      }
    }
    volume {
      name                 = "vault-file"
      mount_path           = "/vault/file"
      share_name           = azurerm_storage_share.axe-ots.name
      storage_account_name = azurerm_storage_account.axe-ots.name
      storage_account_key  = azurerm_storage_account.axe-ots.primary_access_key
    }
  }
  container {
    name   = "one-time-secret"
    image  = "ghcr.io/swissbuechi/one-time-secret:latest"
    cpu    = "0.5"
    memory = "0.5"
    environment_variables = {
      "VAULT_CACERT"             = "/vault/ca/cert.pem"
      "VAULT_ADDR"               = "https://localhost:8200"
      "OTS_HTTP_BINDING_ADDRESS" = ":80"
      "OTS_HTTPS_BINDING_ADDRESS"  = ":443"
      "OTS_HTTPS_REDIRECT_ENABLED" = "true"
      "OTS_TLS_AUTO_DOMAIN" = "ots.axelion.ch"
    }
    secure_environment_variables = {
      "VAULT_TOKEN" = var.ots_vault_token
    }
    volume {
      name                 = "acme"
      mount_path           = "/var/www/.cache"
      share_name           = azurerm_storage_share.axe-ots-acme.name
      storage_account_name = azurerm_storage_account.axe-ots.name
      storage_account_key  = azurerm_storage_account.axe-ots.primary_access_key
    }
    volume {
      name       = "vault-ca"
      mount_path = "/vault/ca"
      secret = {
        "cert.pem" = base64encode(var.ots_vault_cert)
      }
    }
    volume {
      name       = "css"
      mount_path = "/app/static/css"
      secret = {
        "custom.css" = filebase64("${path.module}/axe-ots/css/custom.css")
      }
    }
    volume {
      name       = "logo"
      mount_path = "/app/static/img/logo"
      secret = {
        "logo.png" = filebase64("${path.module}/axe-ots/img/logo.png")
      }
    }   
    volume {
      name       = "font"
      mount_path = "/app/static/font"
      secret = {
        "Rubik.ttf" = filebase64("${path.module}/axe-ots/font/Rubik.ttf")
      }
    }
    # volume {
    #   name       = "background"
    #   mount_path = "/app/static/img/background"
    #   share_name           = azurerm_storage_share.axe-ots-background.name
    #   storage_account_name = azurerm_storage_account.axe-ots.name
    #   storage_account_key  = azurerm_storage_account.axe-ots.primary_access_key
    # }
    volume {
      name                 = "favicon"
      mount_path           = "/app/static/icons"
      share_name           = azurerm_storage_share.axe-ots-icons.name
      storage_account_name = azurerm_storage_account.axe-ots.name
      storage_account_key  = azurerm_storage_account.axe-ots.primary_access_key
    }
    ports {
      port     = 80
      protocol = "TCP"
    }
    ports {
      port     = 443
      protocol = "TCP"
    }
  }
  depends_on = [ azurerm_key_vault_key.axe-ots ]
}

resource "azurerm_automation_account" "axe-ots" {
  name                = "axe-aa-ots"
  location            = azurerm_resource_group.axe-ots.location
  resource_group_name = azurerm_resource_group.axe-ots.name
  sku_name = "Basic"
  identity {
    type = "SystemAssigned"
  }
}

resource "azurerm_role_assignment" "axe-ots" {
  scope                = azurerm_container_group.axe-ots.id
  role_definition_name = "Contributor"
  principal_id         = azurerm_automation_account.axe-ots.identity.0.principal_id
}


resource "azurerm_automation_runbook" "axe-ots" {
  name                    = "Restart-ContainerGroup"
  location                = azurerm_resource_group.axe-ots.location
  resource_group_name     = azurerm_resource_group.axe-ots.name
  automation_account_name = azurerm_automation_account.axe-ots.name
  log_verbose             = "true"
  log_progress            = "true"
  runbook_type            = "PowerShell"
  content             = <<-EOT
    param (
      [Parameter(Mandatory=$true)]
      [String]$containergroupname,
      [Parameter(Mandatory=$true)]
      [String]$resourcegroupname
    )
      Connect-AzAccount -Identity
      Restart-AzContainerGroup -Name $containergroupname -ResourceGroupName $resourcegroupname
    EOT
}

resource "azurerm_automation_schedule" "axe-ots" {
  name                    = "weekly-saturday-3am"
  resource_group_name     = azurerm_resource_group.axe-ots.name
  automation_account_name = azurerm_automation_account.axe-ots.name
  frequency               = "Week"
  interval                = 1
  timezone                = "Europe/Zurich"
  start_time              = replace(timeadd(timestamp(), "24h"), "/T\\d{2}:\\d{2}:\\d{2}/", "T03:00:00")
  week_days               = ["Saturday"]
  lifecycle {
    ignore_changes = [
      start_time
    ]
  }
}

resource "azurerm_automation_job_schedule" "axe-ots" {
  resource_group_name     = azurerm_resource_group.axe-ots.name
  automation_account_name = azurerm_automation_account.axe-ots.name
  schedule_name           = azurerm_automation_schedule.axe-ots.name
  runbook_name            = azurerm_automation_runbook.axe-ots.name
  parameters = {
    "resourcegroupname" = azurerm_resource_group.axe-ots.name
    "containergroupname" = azurerm_container_group.axe-ots.name
  }
}

variables.tf

variable "location" {
  type = string
  default = "switzerlandnorth"
}

variable "ots_vault_token" {}
variable "ots_vault_cert" {}
variable "ots_vault_cert_key" {}

.gitlab-ci.yml

image: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
variables:
  CA_CERTIFICATE: "$AXE_CA_01"
  TF_ROOT: "$CI_PROJECT_DIR"
  TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/${CI_PROJECT_NAME}
  ARM_CLIENT_ID: "$SP_CLIENT_ID"
  ARM_CLIENT_SECRET: "$SP_CLIENT_SECRET"
  ARM_SUBSCRIPTION_ID: "$SUBSCRIPTION_ID"
  ARM_TENANT_ID: "$TENANT_ID"

cache:
  key: production
  paths:
    - ${TF_ROOT}/.terraform

before_script:
  - cd ${TF_ROOT}

stages:
  - prepare
  - validate
  - build
  - deploy

init:
  stage: prepare
  script:
    - echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/AXE-CA-01.crt
    - update-ca-certificates
    - gitlab-terraform init

validate:
  stage: validate
  script:
    - echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/AXE-CA-01.crt
    - update-ca-certificates
    - gitlab-terraform init
    - gitlab-terraform validate

plan:
  stage: build
  script:
    - echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/AXE-CA-01.crt
    - update-ca-certificates
    - gitlab-terraform plan
    - gitlab-terraform plan-json
  artifacts:
    name: plan
    paths:
      - ${TF_ROOT}/plan.cache
    reports:
      terraform: ${TF_ROOT}/plan.json

apply:
  stage: deploy
  environment:
    name: production
  script:
    - echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/AXE-CA-01.crt
    - update-ca-certificates
    - gitlab-terraform apply
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: manual
  dependencies:
    - plan
  

Restart container apps to update to latest image

https://learn.microsoft.com/en-us/rest/api/container-instances/container-groups/restart?view=rest-container-instances-2023-05-01&tabs=HTTP

https://docs.gitlab.com/ee/ci/pipelines/schedules.html

resource "azurerm_automation_account" "example" {
  name                = "account1"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  identity {
    type = "SystemAssigned"
  }

  sku_name = "Free"
}

resource "azurerm_role_assignment" "example" {
  scope                = data.azurerm_subscription.primary.id
  role_definition_name = "Contributor"
  principal_id         = data.azurerm_client_config.example.object_id
}

resource "azurerm_automation_variable_string" "example" {
  name                    = "tfex-example-var"
  resource_group_name     = azurerm_resource_group.example.name
  automation_account_name = azurerm_automation_account.example.name
  value                   = "Hello, Terraform Basic Test."
}

resource "azurerm_automation_schedule" "example" {
  name                    = "tfex-automation-schedule"
  resource_group_name     = azurerm_resource_group.example.name
  automation_account_name = azurerm_automation_account.example.name
  frequency               = "Week"
  interval                = 1
  timezone                = "Australia/Perth"
  start_time              = "2014-04-15T18:00:15+02:00"
  description             = "This is an example schedule"
  week_days               = ["Friday"]
}

resource "azurerm_automation_runbook" "example" {
  name                    = "Get-AzureVMTutorial"
  location                = azurerm_resource_group.example.location
  resource_group_name     = azurerm_resource_group.example.name
  automation_account_name = azurerm_automation_account.example.name
  log_verbose             = "true"
  log_progress            = "true"
  description             = "This is an example runbook"
  runbook_type            = "PowerShell"

  content = data.local_file.example.content
  }
}

resource "azurerm_automation_job_schedule" "example" {
  resource_group_name     = "tf-rgr-automation"
  automation_account_name = "tf-automation-account"
  schedule_name           = "hour"
  runbook_name            = "Get-VirtualMachine"
}

Restart-ContainerGroup.ps1

try
{
    "Logging in to Azure..."
    Connect-AzAccount -Identity

    "Restarting Container Group..."
    Restart-AzContainerGroup -Name (Get-AutomationVariable -Name ContainerGroupName) -ResourceGroupName (Get-AutomationVariable -Name ResourceGroupName)
}
catch {
    Write-Error -Message $_.Exception
    throw $_.Exception
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.