diff --git a/infrastructure/.gitignore b/infrastructure/.gitignore new file mode 100644 index 00000000..2fa2fc37 --- /dev/null +++ b/infrastructure/.gitignore @@ -0,0 +1,39 @@ +/.idea/ + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc \ No newline at end of file diff --git a/infrastructure/README.md b/infrastructure/README.md new file mode 100644 index 00000000..7a6270e6 --- /dev/null +++ b/infrastructure/README.md @@ -0,0 +1,97 @@ +Install k3s + Rancher with letsecrypt + +``` +sudo su +``` + + +``` +export IP_ADDRESS_HOST=3.215.23.96 + +dnf install htop -y +curl -sfL https://get.k3s.io | sh - +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash +alias k=kubectl +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + +helm repo add jetstack https://charts.jetstack.io +helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true + +helm repo add rancher-stable https://releases.rancher.com/server-charts/stable +kubectl create namespace cattle-system + +helm upgrade -i rancher rancher-stable/rancher \ + --namespace cattle-system \ + --set hostname=$IP_ADDRESS_HOST.sslip.io \ + --set bootstrapPassword=admin \ + --set ingress.tls.source=letsEncrypt \ + --set letsEncrypt.email=mirafzal.shavkatov@dsr-corporation.com \ + --set letsEncrypt.ingress.class=traefik \ + --set replicas=1 \ + --set agentTLSMode=system-store + +echo https://$IP_ADDRESS_HOST.sslip.io/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}') + +``` + +Install k3s + Rancher self-signed certificate + +``` +sudo su + +dnf install htop -y + +curl -sfL https://get.k3s.io | sh - + +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + +alias k=kubectl + +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + +helm repo add jetstack https://charts.jetstack.io +helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true + +helm repo add rancher-stable https://releases.rancher.com/server-charts/stable +kubectl create namespace cattle-system + +helm upgrade -i rancher rancher-stable/rancher \ + --namespace cattle-system \ + --set hostname=ec2-54-166-76-61.compute-1.amazonaws.com \ + --set bootstrapPassword=admin \ + --set replicas=1 + +echo https://ec2-54-166-76-61.compute-1.amazonaws.com/dashboard/?setup=$(kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{.data.bootstrapPassword|base64decode}}') +``` + +Install ebs-csi driver + +``` +helm upgrade --install aws-ebs-csi-driver \ + --namespace kube-system \ + aws-ebs-csi-driver/aws-ebs-csi-driver --values aws-ebs-csi-driver-values.yaml +``` + +Then apply aws-secret.yaml + +``` +kubectl apply -f aws-secret.yaml +``` + +Install besu +``` +git clone https://github.com/ConsenSys/quorum-kubernetes.git +cd quorum-kubernetes/helm +kubectl create namespace besu +helm install genesis ./charts/besu-genesis --namespace besu --create-namespace --values ./values/genesis-besu.yml +helm install bootnode-1 ./charts/besu-node --namespace besu --values ./values/bootnode.yml +helm install bootnode-2 ./charts/besu-node --namespace besu --values ./values/bootnode.yml +helm install validator-1 ./charts/besu-node --namespace besu --values ./values/validator.yml +helm install validator-2 ./charts/besu-node --namespace besu --values ./values/validator.yml +``` \ No newline at end of file diff --git a/infrastructure/aws-ebs-csi-driver-values.yaml b/infrastructure/aws-ebs-csi-driver-values.yaml new file mode 100644 index 00000000..7d6f4dae --- /dev/null +++ b/infrastructure/aws-ebs-csi-driver-values.yaml @@ -0,0 +1,10 @@ +storageClasses: + - name: ebs-sc + # annotations: + # storageclass.kubernetes.io/is-default-class: "true" + volumeBindingMode: Immediate + reclaimPolicy: Delete +controller: + serviceAccount: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::{org_id}:role/k8s-ebs-csi \ No newline at end of file diff --git a/infrastructure/aws-secret.yaml b/infrastructure/aws-secret.yaml new file mode 100644 index 00000000..b521d6f9 --- /dev/null +++ b/infrastructure/aws-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: aws-secret + namespace: kube-system +stringData: + key_id: "" + access_key: "" \ No newline at end of file diff --git a/infrastructure/blockscout-values.yaml b/infrastructure/blockscout-values.yaml new file mode 100644 index 00000000..ea81d346 --- /dev/null +++ b/infrastructure/blockscout-values.yaml @@ -0,0 +1,410 @@ +# Default values for blockscout-stack. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +## Provide a name in place of blockscout-stack for `app:` labels +## +nameOverride: "" +## Provide a name to substitute for the full names of resources +## +fullnameOverride: "" +## Reference to one or more secrets to be used when pulling images +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +## +imagePullSecrets: [] +## Blockscout configuration options. See frontend Docs +## ref: https://github.com/blockscout/frontend/blob/main/docs/ENVS.md#blockchain-parameters +## +config: + network: + id: 1 + name: Ether + shortname: Ether + currency: + name: Ether + symbol: ETH + decimals: 18 + account: + enabled: false + testnet: false + ## If set to true will create service monitors for blockscout and stats + ## + prometheus: + enabled: false +## Configuration options for backend +## +blockscout: + enabled: true + ## Currently only one replica is supported + ## + replicaCount: 1 + ## Image parametes + ## + image: + repository: blockscout/blockscout + pullPolicy: IfNotPresent + tag: "latest" + ## Init container configuration (used to run DB migrations) + ## + init: + enabled: true + command: + - /bin/sh + args: + - -c + - bin/blockscout eval "Elixir.Explorer.ReleaseTasks.create_and_migrate()" + ## Blockscout ENV vars + ## ref: https://docs.blockscout.com/for-developers/information-and-settings/env-variables + ## + env: + DATABASE_URL: "postgresql://postgres:postgres@blockscout-postgresql.default.svc.cluster.local:5432/postgres" + ETHEREUM_JSONRPC_VARIANT: "besu" + ETHEREUM_JSONRPC_HTTP_URL: "http://besu-node-bootnode-1.besu.svc.cluster.local:8545/" +# DATABASE_URL: "postgresql://blockscout:ceWb1MeLBEeOIfk65gU8EjF8@db:5432/blockscout" + ETHEREUM_JSONRPC_WS_URL: "ws://host.docker.internal:8546/" + ETHEREUM_JSONRPC_TRANSPORT: "http" + ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES: "false" + ETHEREUM_JSONRPC_TRACE_URL: "http://besu-node-bootnode-1.besu.svc.cluster.local:8545/" + NETWORK: "Indy-Besu" + SUBNETWORK: "Indy-Besu" + LOGO: "/images/blockscout_logo.svg" + SECRET_KEY_BASE: "56NtB48ear7+wMSf0IQuWDAAazhpb31qyc7GiyspBP2vh7t5zlCsF5QDv76chXeN" + PORT: "4000" + EMISSION_FORMAT: "POA" + CHAIN_SPEC_PATH: "/opt/besu/genesis.json" + POOL_SIZE: "80" + POOL_SIZE_API: "10" + ECTO_USE_SSL: "false" + HEART_BEAT_TIMEOUT: "30" + BLOCK_TRANSFORMER: "base" + FOOTER_LOGO: "/images/blockscout_logo.svg" + FOOTER_LINK_TO_OTHER_EXPLORERS: "false" + FOOTER_OTHER_EXPLORERS: "{}" + SUPPORTED_CHAINS: "{}" + CACHE_BLOCK_COUNT_PERIOD: "7200" + CACHE_TXS_COUNT_PERIOD: "7200" + CACHE_ADDRESS_SUM_PERIOD: "3600" + CACHE_TOTAL_GAS_USAGE_PERIOD: "3600" + CACHE_ADDRESS_TRANSACTIONS_GAS_USAGE_COUNTER_PERIOD: "1800" + CACHE_TOKEN_HOLDERS_COUNTER_PERIOD: "3600" + CACHE_TOKEN_TRANSFERS_COUNTER_PERIOD: "3600" + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL: "1800" + CACHE_AVERAGE_BLOCK_PERIOD: "1800" + CACHE_MARKET_HISTORY_PERIOD: "21600" + CACHE_ADDRESS_TRANSACTIONS_COUNTER_PERIOD: "1800" + CACHE_ADDRESS_TOKENS_USD_SUM_PERIOD: "3600" + CACHE_ADDRESS_TOKEN_TRANSFERS_COUNTER_PERIOD: "1800" + TOKEN_METADATA_UPDATE_INTERVAL: "172800" + CONTRACT_VERIFICATION_ALLOWED_SOLIDITY_EVM_VERSIONS: "homestead,tangerineWhistle,spuriousDragon,byzantium,constantinople,petersburg,istanbul,berlin,london,paris,shanghai,default" + CONTRACT_VERIFICATION_ALLOWED_VYPER_EVM_VERSIONS: "byzantium,constantinople,petersburg,istanbul,berlin,paris,shanghai,default" + CONTRACT_MAX_STRING_LENGTH_WITHOUT_TRIMMING: "2040" + UNCLES_IN_AVERAGE_BLOCK_TIME: "false" + DISABLE_WEBAPP: "false" + API_V2_ENABLED: "true" + API_V1_READ_METHODS_DISABLED: "false" + API_V1_WRITE_METHODS_DISABLED: "false" + API_RATE_LIMIT_TIME_INTERVAL: "1s" + API_RATE_LIMIT_BY_IP_TIME_INTERVAL: "5m" + API_RATE_LIMIT: "50" + API_RATE_LIMIT_BY_KEY: "50" + API_RATE_LIMIT_BY_WHITELISTED_IP: "50" + API_RATE_LIMIT_WHITELISTED_IPS: "" + API_RATE_LIMIT_STATIC_API_KEY: "" + API_RATE_LIMIT_UI_V2_WITH_TOKEN: "5" + API_RATE_LIMIT_BY_IP: "3000" + DISABLE_INDEXER: "false" + DISABLE_REALTIME_INDEXER: "false" + DISABLE_CATCHUP_INDEXER: "false" + INDEXER_DISABLE_TOKEN_INSTANCE_REALTIME_FETCHER: "false" + INDEXER_DISABLE_TOKEN_INSTANCE_RETRY_FETCHER: "false" + INDEXER_DISABLE_TOKEN_INSTANCE_SANITIZE_FETCHER: "false" + INDEXER_DISABLE_TOKEN_INSTANCE_LEGACY_SANITIZE_FETCHER: "false" + INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER: "false" + INDEXER_DISABLE_INTERNAL_TRANSACTIONS_FETCHER: "false" + SHOW_ADDRESS_MARKETCAP_PERCENTAGE: "true" + CHECKSUM_ADDRESS_HASHES: "true" + CHECKSUM_FUNCTION: "eth" + DISABLE_EXCHANGE_RATES: "true" + TXS_STATS_ENABLED: "true" + SHOW_PRICE_CHART: "false" + SHOW_PRICE_CHART_LEGEND: "false" + SHOW_TXS_CHART: "true" + TXS_HISTORIAN_INIT_LAG: "0" + TXS_STATS_DAYS_TO_COMPILE_AT_INIT: "10" + COIN_BALANCE_HISTORY_DAYS: "90" + APPS_MENU: "true" + EXTERNAL_APPS: "[]" + SHOW_MAINTENANCE_ALERT: "false" + CHAIN_ID: "1337" + MAX_SIZE_UNLESS_HIDE_ARRAY: "50" + HIDE_BLOCK_MINER: "false" + DISPLAY_TOKEN_ICONS: "false" + RE_CAPTCHA_DISABLED: "false" + JSON_RPC: "" + API_RATE_LIMIT_UI_V2_TOKEN_TTL_IN_SECONDS: "18000" + FETCH_REWARDS_WAY: "trace_block" + MICROSERVICE_SC_VERIFIER_ENABLED: "true" + MICROSERVICE_SC_VERIFIER_URL: "https://eth-bytecode-db.services.blockscout.com/" + MICROSERVICE_SC_VERIFIER_TYPE: "eth_bytecode_db" + MICROSERVICE_ETH_BYTECODE_DB_INTERVAL_BETWEEN_LOOKUPS: "10m" + MICROSERVICE_ETH_BYTECODE_DB_MAX_LOOKUPS_CONCURRENCY: "10" +# MICROSERVICE_VISUALIZE_SOL2UML_ENABLED: "true" +# MICROSERVICE_VISUALIZE_SOL2UML_URL: "http://visualizer:8050/" +# MICROSERVICE_SIG_PROVIDER_ENABLED: "true" +# MICROSERVICE_SIG_PROVIDER_URL: "http://sig-provider:8050/" + DECODE_NOT_A_CONTRACT_CALLS: "true" + ACCOUNT_ENABLED: "false" + ACCOUNT_REDIS_URL: "redis://redis_db:6379" + EIP_1559_ELASTICITY_MULTIPLIER: "2" + SOURCIFY_INTEGRATION_ENABLED: "false" + SHOW_TENDERLY_LINK: "false" + # NAME: VALUE + ## Set ENV vars via secret, this can be usefull for DB connection params, api keys, etc. + ## + envFromSecret: [] + # NAME: VALUE + ## Command to start blockscout instance + ## + command: + - /bin/sh + args: + - -c + - bin/blockscout start + ## Annotations to add to blockscout pod + podAnnotations: {} + + podSecurityContext: {} + ## SecurityContext holds pod-level security attributes and common container settings. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: {} + terminationGracePeriodSeconds: 300 + ## Liveness probe + ## + livenessProbe: + enabled: true + path: /api/v1/health/liveness + params: + initialDelaySeconds: 100 + periodSeconds: 100 + timeoutSeconds: 30 + ## Readiness probe + ## + readinessProbe: + enabled: true + path: /api/v1/health/readiness + params: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 60 + + service: + type: ClusterIP + port: 80 + ## Configure ingress resource that allow you to access the blockscout installation. + ## ref: http://kubernetes.io/docs/user-guide/ingress/ + ## + ingress: + enabled: false + className: "" + annotations: {} + hostname: chart-example.local + tls: + enabled: false + paths: + - path: /api + pathType: Prefix + - path: /socket + pathType: Prefix + + resources: + limits: + cpu: 1 + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi +## Configuration options for frontend +## +frontend: + enabled: true + ## Image parametes + image: + repository: ghcr.io/blockscout/frontend + tag: latest + pullPolicy: IfNotPresent + + replicaCount: 1 + ## Annotations to add to frontend pod + ## + podAnnotations: {} + + podSecurityContext: {} + ## SecurityContext holds pod-level security attributes and common container settings. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## + securityContext: {} + + service: + type: ClusterIP + port: 80 + ## Configure ingress resource that allow you to access the frontend installation. + ## ref: http://kubernetes.io/docs/user-guide/ingress/ + ## + ingress: + enabled: false + className: "" + annotations: {} + hostname: chart-example.local + tls: + enabled: false + paths: + - path: / + + resources: + limits: + memory: "384Mi" + cpu: 200m + requests: + memory: "384Mi" + cpu: 200m + ## Liveness probe + ## + livenessProbe: + enabled: true + path: /api/healthz + params: + initialDelaySeconds: 100 + periodSeconds: 100 + timeoutSeconds: 30 + ## Readiness probe + ## + readinessProbe: + enabled: true + path: /api/healthz + params: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 30 + ## Frontend ENV vars + ## ref: https://github.com/blockscout/frontend/blob/main/docs/ENVS.md + ## + env: + NEXT_PUBLIC_API_HOST: "localhost:26000" + NEXT_PUBLIC_API_PROTOCOL: "http" + # NEXT_PUBLIC_STATS_API_HOST: "http://localhost:26001" + NEXT_PUBLIC_NETWORK_NAME: Indy-Besu + NEXT_PUBLIC_NETWORK_SHORT_NAME: Indy-Besu + NEXT_PUBLIC_NETWORK_ID: "5" + NEXT_PUBLIC_NETWORK_CURRENCY_NAME: "Ether" + NEXT_PUBLIC_NETWORK_CURRENCY_SYMBOL: "ETH" + NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS: "18" + NEXT_PUBLIC_API_BASE_PATH: "/" + NEXT_PUBLIC_APP_HOST: "localhost:26000" + NEXT_PUBLIC_APP_PROTOCOL: "http" + NEXT_PUBLIC_HOMEPAGE_CHARTS: "['daily_txs']" + # NEXT_PUBLIC_VISUALIZE_API_HOST: "http://localhost:26002" + NEXT_PUBLIC_IS_TESTNET: "true" + NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL: "ws" + NEXT_PUBLIC_API_SPEC_URL: "https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml" + NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE: validation + NEXT_PUBLIC_GAS_TRACKER_ENABLED: false + NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS: '["value","tx_fee"]' + # NAME: VALUE + envFromSecret: [] + # NAME: VALUE + +stats: + enabled: false + ## Image parametes + ## + image: + repository: ghcr.io/blockscout/stats + tag: latest + pullPolicy: IfNotPresent + + replicasCount: 1 + service: + type: ClusterIP + port: 80 + metricsPort: 6060 + + podAnnotations: {} + + podSecurityContext: {} + + securityContext: {} + + ## Configure ingress resource that allow you to access the stats installation. + ## ref: http://kubernetes.io/docs/user-guide/ingress/ + ## + ingress: + enabled: false + className: "" + annotations: {} + hostname: chart-example-stats.local + tls: + enabled: false + paths: + - path: / + pathType: Prefix + + resources: + limits: + memory: "512Mi" + cpu: 250m + requests: + memory: 512Mi + cpu: 250m + ## Files to mount to stats pod + ## + files: + enabled: false + list: {} + # file.txt: | + # test + mountPath: /tmp/path + + ## Liveness probe + ## + livenessProbe: + enabled: false + path: /health + params: + initialDelaySeconds: 100 + periodSeconds: 100 + timeoutSeconds: 30 + ## Readiness probe + ## + readinessProbe: + enabled: false + path: /health + params: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 60 + ## Stats ENV vars + ## ref: https://github.com/blockscout/blockscout-rs/tree/main/stats#env + env: [] + # NAME: VALUE + envFromSecret: [] + # NAME: VALUE +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" +## Node labels for blockscout-stack pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} + +tolerations: [] + +## Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} \ No newline at end of file diff --git a/infrastructure/helm-charts/monitoring/grafana/values.yaml b/infrastructure/helm-charts/monitoring/grafana/values.yaml new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/helm-charts/monitoring/prometheus/values.yaml b/infrastructure/helm-charts/monitoring/prometheus/values.yaml new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/helm-charts/monitoring/promtail/values.yaml b/infrastructure/helm-charts/monitoring/promtail/values.yaml new file mode 100644 index 00000000..e69de29b diff --git a/infrastructure/postgres-values.yaml b/infrastructure/postgres-values.yaml new file mode 100644 index 00000000..7d89bb9f --- /dev/null +++ b/infrastructure/postgres-values.yaml @@ -0,0 +1,18 @@ +auth: + ## @param auth.enablePostgresUser Assign a password to the "postgres" admin user. Otherwise, remote access will be blocked for this user + ## + enablePostgresUser: true + ## @param auth.postgresPassword Password for the "postgres" admin user. Ignored if `auth.existingSecret` is provided + ## + postgresPassword: "postgres" +tls: + enabled: true + autoGenerated: true +primary: + resources: + requests: + cpu: 250m + memory: 512Mi + limits: + cpu: 500m + memory: 750Mi \ No newline at end of file diff --git a/infrastructure/terraform/.terraform.lock.hcl b/infrastructure/terraform/.terraform.lock.hcl new file mode 100644 index 00000000..3a35643d --- /dev/null +++ b/infrastructure/terraform/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.75.0" + constraints = "~> 5.75" + hashes = [ + "h1:36n0sS0B/ZL0yr4JsW07TT+WtLmozvlKTAA/MQWpDY8=", + "zh:01b01b132b70df918f735898f1ad012ab3033d1b909b2e38950d16964d94c084", + "zh:28bc6ee7b0c88b1a48f315509ad390fb1e8f39bebe0f7a43c22b1a63825251d1", + "zh:31f9043a4c3538883ab9b9d3b399dae62e4552251e6a2b1da13ec3a2018a027d", + "zh:47451c295ffbddd19679a41d728f0942486d6de0d9206418d9593dda5a20c120", + "zh:5204c1a9f41dcc10e38879d41d95d95fdbb10527f613c129603137b1dbe99777", + "zh:64c3165a6019045782c8ad2a40d6fa4253d44dba67a5a971a81791cff5a9d3d5", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a5788f78da2f0ac78f99ca2a4c489c041654bec992f3183fd0b972e0554f91e9", + "zh:aed486e3b24e9f82543bf558b2a7eade4a905608060fac1284145c00ff63d3e2", + "zh:b42523c409940a9c3866f4973c8251b96e5f3a0934230849c533a04b95854965", + "zh:b570353eeb97b3ed1b423a6f67857a7a3c1c47c9907e45a81c3df186a2fd88d0", + "zh:bf05df84199cbc776a878f920f6be4d27737f2de204f80794e6a652d49692f0d", + "zh:c27133287d20620244de95f4c2438135e60c057e0891a3ec97539c990f7ebdec", + "zh:c59143082fe8e4f5d5b0676472b8b0e24c2a2f1ede622a64f9f24639382d4b03", + "zh:ebe01c3b7a85deebc10b4081097dd6e8b4c79b7c13a20acb099bd17ff06afcb7", + ] +} diff --git a/infrastructure/terraform/files/userdata_rancher_node.template b/infrastructure/terraform/files/userdata_rancher_node.template new file mode 100644 index 00000000..5437d888 --- /dev/null +++ b/infrastructure/terraform/files/userdata_rancher_node.template @@ -0,0 +1,34 @@ +#!/bin/bash -x + +TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") +export IP_ADDRESS_HOST=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/public-ipv4) + +dnf install htop -y +curl -sfL https://get.k3s.io | sh - +curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash +alias k=kubectl +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml + +helm repo add jetstack https://charts.jetstack.io +helm upgrade -i cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true \ + --version 1.16.2 \ + --wait \ + --wait-for-jobs + +helm repo add rancher-stable https://releases.rancher.com/server-charts/stable +helm upgrade -i rancher rancher-stable/rancher \ + --namespace cattle-system \ + --set hostname=$IP_ADDRESS_HOST.sslip.io \ + --set bootstrapPassword=admin \ + --set ingress.tls.source=letsEncrypt \ + --set letsEncrypt.email=mirafzal.shavkatov@dsr-corporation.com \ + --set letsEncrypt.ingress.class=traefik \ + --set replicas=1 \ + --set agentTLSMode=system-store \ + --version 2.10.0 \ + --create-namespace \ + --wait \ + --wait-for-jobs \ No newline at end of file diff --git a/infrastructure/terraform/main.tf b/infrastructure/terraform/main.tf new file mode 100644 index 00000000..f6910e53 --- /dev/null +++ b/infrastructure/terraform/main.tf @@ -0,0 +1,52 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.75" + } + } + + required_version = ">= 1.2.0" +} + +provider "aws" { + region = "us-east-1" +} + +resource "aws_key_pair" "rancher_ec2_server_key_pair" { + key_name = "mirafzal-pc-key-pair" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDQK9fOCy2mVnk5v+tsqfUmr+moMwg/OrCrDti1oWZPmQQL3PfOCSDRA2WvScaKgqRqDh4yKhE3uWUS9ZvdT73f5nD5omHPLQbs2IWcMhUNyn4uC8w3nM2G969QSXsyUR6H+gzGkDjNpA+CWoEhNhyIOLZVbJsZbpyerK11xrkGrymCP0m28E69xm5hLoEathk/BYlakLNqqeoJBFafljvFjmRG9HkcADLQW5jmJc9xDHrzu+AXBNa0SPDiB5wB0be2f5Se6WTqW2kBDWcMHwxKW+sJHhe+tXsnlABPFhVJe9eRKuT31Vfu8QbUFpduYx7B+MqWw/i0zz1t1tpVakKNJtzPGfDaXLdIN7j9+v33sfNAsT9byU6k8+vv6ewK/OcmgPGOlgGQrVUlI9wIGQw0/yz6+hkIu14veL37kt2gR7GcIVOIFZ8/gS6jhtsFAw5AWrLMV1FIRB8VggzQ6nTcCwnjLVRr9N6vgWNZQcLaOW5Ovlh051dMMFlZtYdKUllhs9l2dVKW8vTEEipyEFSIpczvU2PXNi4Mxfr39THZfa+eZDsxUan1TCA/b3dvsPbdaRYYsql9XRCmAcuzIHcw4i1vkFXQoaQgz0MTcaGCv9bevNwImA/wgLHH+oQC4O1BTGz8q+kKyHRnZOAwP8TF8MtuPhUms03nNdpHXpHUQQ== sammy@DESKTOP-JJ791QV" +} + +resource "aws_instance" "rancher_ec2_server" { + ami = "ami-0453ec754f44f9a4a" + instance_type = "t3a.medium" + + root_block_device { + volume_size = "20" + } + + tags = { + Name = "rancher-ec2-server" + } + + key_name = aws_key_pair.rancher_ec2_server_key_pair.key_name + + user_data = templatefile( + "${path.module}/files/userdata_rancher_node.template", + {} + ) + +} + +output "rancher_ec2_server_ip" { + value = aws_instance.rancher_ec2_server.public_ip +} + +output "rancher_api_url" { + value = "https://${aws_instance.rancher_ec2_server.public_ip}.sslip.io" +} + +output "rancher_ec2_server_ssh_command" { + value = "ssh ec2-user@${aws_instance.rancher_ec2_server.public_ip}" +} \ No newline at end of file diff --git a/infrastructure/terraform/rancher/.gitignore b/infrastructure/terraform/rancher/.gitignore new file mode 100644 index 00000000..2fa2fc37 --- /dev/null +++ b/infrastructure/terraform/rancher/.gitignore @@ -0,0 +1,39 @@ +/.idea/ + +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Ignore transient lock info files created by terraform apply +.terraform.tfstate.lock.info + +# Include override files you do wish to add to version control using negated pattern +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc \ No newline at end of file diff --git a/infrastructure/terraform/rancher/.terraform.lock.hcl b/infrastructure/terraform/rancher/.terraform.lock.hcl new file mode 100644 index 00000000..a9ba2452 --- /dev/null +++ b/infrastructure/terraform/rancher/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.80.0" + constraints = "~> 5.75" + hashes = [ + "h1:N5Wfsf4xe5DJfSeo0G/ulkIxzyfmUIoSj/hAiZ2DaKU=", + "zh:0b1655e39639d60f2de2860a5df8642f9556ba0ca04529c1b861fde4935cb0df", + "zh:13dc0155e0a11edceee29ce687fc04c5a5a85f3324c67556472713cfd52e5807", + "zh:180f6cb2be44be14cfe329e0649121b774319f083b6e4e8fb749f85090d73121", + "zh:3158d44b74c67465f7f19f22c42b643840c8d18ce833e2ec86e8d93085b06926", + "zh:6351b5bf7cde5dc83e926944891570636069e05ca43341f4d1feda67773469bf", + "zh:6fa9db1532096ba50e842d369b6688979306d2295c7ead49b8a266b0d60962cc", + "zh:85d2fe75def7619ff2cc29102048875039cad088fafb62ecc14c3763e7b1e9d9", + "zh:9028d653f1d7341c6dfe2afe961b6541581e9043a474eac2faf90e6426a24f6d", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9c4e248c442bc60f07f9f089e5361f19936833370dc3c04b27916672b765f0e1", + "zh:a710a3979596e3f3938c3ec6bb748e604724d3a4afa96ed2c14f0a245cc41a11", + "zh:c27936bdf447779d0c0833bf52a9ef618985f5ea8e3e243d6266513520ca31c4", + "zh:c7681134a123486e72eaedc3f8d2d75e267dbbfd45fa7de5aea8f757af57f89b", + "zh:ea717ebad3561fd02591f9eecf30f3df5635405556fba2bdbf29fd42691bebac", + "zh:f4e1e8f23c58c3e8f4371f9c3379a723ab4155246e6b6daad8eb99e16666b2cb", + ] +} + +provider "registry.terraform.io/rancher/rancher2" { + version = "6.0.0" + constraints = "6.0.0" + hashes = [ + "h1:uV/GQ3Q2Up0sLeBZiVX27s/6C+Qa8dDMdFueiPenWV4=", + "zh:170937ece0e963e32778882fbd2b527bfec1ce43b4ed319088cbd4829170a09b", + "zh:1d91fd63cbd26dcd03f2445dc63695d3daa17e4a882ee412bbcd958c33a7a845", + "zh:3d9644592afec9fc3148885ae676b2f7e30e197c69d7594d06ca504cd1f6027f", + "zh:5820dcfa50a1577d3ed936c2711c347fbee35f65caf02bb3465d497dc5b42fce", + "zh:5a40f994c5fe26a5c5cd006c24badd2d79fe4290594b35862f00b564242d416c", + "zh:5a7fabf5db5c442095c4c1f99a9a405842dfb2126e8f597102be119e06cf5234", + "zh:75e2f4dc20eff039f54f5df36da6ef4f8e9e49f278368e69824144671683cc33", + "zh:7d8bc9da9530e260688caf9524e8026995edc8467e1050b8e10f601f678b2bfa", + "zh:801ca2613a6aaf9c073fe052a8ad56e77df2872ec2d5a819327b1ed3820db943", + "zh:8f05f36d72e5a3b38d707b2e6fe5b197d24b18667073e220b4015fddc26b6776", + "zh:c5527bf2a6cd11149fb2840a7c5558bb7a5fb432fd56df0ae2a603066847f93f", + "zh:dd3d9a4cfcafd78f32ad23d8aaeb3d9260dd7caf8e8c8a8143ba1272ae00df8d", + ] +} diff --git a/infrastructure/terraform/rancher/aws-ebs-csi-driver-values.yaml b/infrastructure/terraform/rancher/aws-ebs-csi-driver-values.yaml new file mode 100644 index 00000000..636278b2 --- /dev/null +++ b/infrastructure/terraform/rancher/aws-ebs-csi-driver-values.yaml @@ -0,0 +1,6 @@ +storageClasses: + - name: ebs-sc +# annotations: +# storageclass.kubernetes.io/is-default-class: "true" + volumeBindingMode: Immediate + reclaimPolicy: Retain \ No newline at end of file diff --git a/infrastructure/terraform/rancher/aws-ebs-csi-role.tf b/infrastructure/terraform/rancher/aws-ebs-csi-role.tf new file mode 100644 index 00000000..574c9ab9 --- /dev/null +++ b/infrastructure/terraform/rancher/aws-ebs-csi-role.tf @@ -0,0 +1,9 @@ +# resource "aws_iam_role" "ebs_csi" { +# name = "ebs-csi" +# assume_role_policy = data.aws_iam_policy_document.ebs_csi_irsa.json +# } +# +# resource "aws_iam_role_policy_attachment" "AmazonEBSCSIDriverPolicy" { +# policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy" +# role = aws_iam_role.ebs_csi.name +# } \ No newline at end of file diff --git a/infrastructure/terraform/rancher/aws-network-module.tf b/infrastructure/terraform/rancher/aws-network-module.tf new file mode 100644 index 00000000..45e6b042 --- /dev/null +++ b/infrastructure/terraform/rancher/aws-network-module.tf @@ -0,0 +1,19 @@ +# module "vpc" { +# source = "terraform-aws-modules/vpc/aws" +# +# name = "k8s-vpc-module" +# cidr = "10.0.0.0/16" +# +# azs = ["us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d"] +# private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24", "10.0.4.0/24"] +# # public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24", "10.0.104.0/24"] +# +# # enable_nat_gateway = true +# # enable_vpn_gateway = true +# +# tags = { +# Terraform = "true" +# Environment = "dev" +# } +# +# } \ No newline at end of file diff --git a/infrastructure/terraform/rancher/aws-network.tf b/infrastructure/terraform/rancher/aws-network.tf new file mode 100644 index 00000000..056efab9 --- /dev/null +++ b/infrastructure/terraform/rancher/aws-network.tf @@ -0,0 +1,115 @@ +# -------------------- Network -------------------- # + +resource "aws_vpc" "downstream_kubernetes_vpc" { + cidr_block = "10.0.0.0/16" + enable_dns_hostnames = true + tags = { + Name = "k8s-vpc" + } +} + +resource "aws_internet_gateway" "downstream_kubernetes_gateway" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + tags = { + Name = "k8s-gateway" + } +} + +resource "aws_subnet" "downstream_kubernetes_subnet_zone_a" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + availability_zone = "us-east-1a" + cidr_block = "10.0.0.0/24" + + tags = { + Name = "k8s-subnet-zone-a" + } +} + +resource "aws_subnet" "downstream_kubernetes_subnet_zone_b" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + availability_zone = "us-east-1b" + cidr_block = "10.0.1.0/24" + + tags = { + Name = "k8s-subnet-zone-b" + } +} + +resource "aws_subnet" "downstream_kubernetes_subnet_zone_c" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + availability_zone = "us-east-1c" + cidr_block = "10.0.2.0/24" + + tags = { + Name = "k8s-subnet-zone-c" + } +} + +resource "aws_subnet" "downstream_kubernetes_subnet_zone_d" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + availability_zone = "us-east-1d" + cidr_block = "10.0.3.0/24" + + tags = { + Name = "k8s-subnet-zone-d" + } +} + +resource "aws_route_table" "downstream_kubernetes_route_table" { + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.downstream_kubernetes_gateway.id + } + + tags = { + Name = "k8s-route-table" + } +} + +resource "aws_route_table_association" "downstream_kubernetes_route_table_association_zone_a" { + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_a.id + route_table_id = aws_route_table.downstream_kubernetes_route_table.id +} + +resource "aws_route_table_association" "downstream_kubernetes_route_table_association_zone_b" { + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_b.id + route_table_id = aws_route_table.downstream_kubernetes_route_table.id +} + +resource "aws_route_table_association" "downstream_kubernetes_route_table_association_zone_c" { + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_c.id + route_table_id = aws_route_table.downstream_kubernetes_route_table.id +} + +resource "aws_route_table_association" "downstream_kubernetes_route_table_association_zone_d" { + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_d.id + route_table_id = aws_route_table.downstream_kubernetes_route_table.id +} + +resource "aws_security_group" "downstream_kubernetes_security_group" { + name = "k8s-security-group" + description = "Downstream k8s security group" + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + + ingress { + from_port = "0" + to_port = "0" + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = "0" + to_port = "0" + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + +} \ No newline at end of file diff --git a/infrastructure/terraform/rancher/downstream-kubernetes-cluster.tf b/infrastructure/terraform/rancher/downstream-kubernetes-cluster.tf new file mode 100644 index 00000000..d643d5cc --- /dev/null +++ b/infrastructure/terraform/rancher/downstream-kubernetes-cluster.tf @@ -0,0 +1,141 @@ +# -------------------- Provision downstream k8s cluster -------------------- # + +# Create AmazonEC2 cloud credential +resource "rancher2_cloud_credential" "aws_cloud_credential" { + name = var.aws_creds_name + amazonec2_credential_config { + access_key = var.aws_access_key + secret_key = var.aws_secret_key + default_region = "us-east-1" + } +} + +# Create AmazonEC2 machine config v2 +resource "rancher2_machine_config_v2" "zone_a" { + generate_name = "zone-a-pool" + amazonec2_config { + ami = "ami-0e2c8caa4b6378d8c" + region = "us-east-1" + security_group = [aws_security_group.downstream_kubernetes_security_group.name] + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_a.id + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + zone = "a" + root_size = "20" + instance_type = "t3a.small" + volume_type = "gp3" + iam_instance_profile = "k8s-ebs-csi" + } +} + +resource "rancher2_machine_config_v2" "zone_b" { + generate_name = "zone-b-pool" + amazonec2_config { + ami = "ami-0e2c8caa4b6378d8c" + region = "us-east-1" + security_group = [aws_security_group.downstream_kubernetes_security_group.name] + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_b.id + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + zone = "b" + root_size = "20" + instance_type = "t3a.small" + volume_type = "gp3" + iam_instance_profile = "k8s-ebs-csi" + + } +} + +resource "rancher2_machine_config_v2" "zone_c" { + generate_name = "zone-c-pool" + amazonec2_config { + ami = "ami-0e2c8caa4b6378d8c" + region = "us-east-1" + security_group = [aws_security_group.downstream_kubernetes_security_group.name] + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_c.id + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + zone = "c" + root_size = "20" + instance_type = "t3a.small" + volume_type = "gp3" + iam_instance_profile = "k8s-ebs-csi" + } +} + +resource "rancher2_machine_config_v2" "zone_d" { + generate_name = "zone-d-pool" + amazonec2_config { + ami = "ami-0e2c8caa4b6378d8c" + region = "us-east-1" + security_group = [aws_security_group.downstream_kubernetes_security_group.name] + subnet_id = aws_subnet.downstream_kubernetes_subnet_zone_d.id + vpc_id = aws_vpc.downstream_kubernetes_vpc.id + zone = "d" + root_size = "20" + instance_type = "t3a.small" + volume_type = "gp3" + iam_instance_profile = "k8s-ebs-csi" + } +} + +resource "rancher2_cluster_v2" "downstream_kubernetes_cluster" { + name = "downstream-k8s-cluster" + kubernetes_version = "v1.31.2+k3s1" + enable_network_policy = false + rke_config { + machine_global_config = <