Tim Andersson has proposed merging ~andersson123/autopkgtest-cloud:dump-service-bundle-move-to-terraform into autopkgtest-cloud:master.
Requested reviews: Canonical's Ubuntu QA (canonical-ubuntu-qa) For more details, see: https://code.launchpad.net/~andersson123/autopkgtest-cloud/+git/autopkgtest-cloud/+merge/467108 -- Your team Canonical's Ubuntu QA is requested to review the proposed merge of ~andersson123/autopkgtest-cloud:dump-service-bundle-move-to-terraform into autopkgtest-cloud:master.
diff --git a/.launchpad.yaml b/.launchpad.yaml index bf8ccf2..ac9e82a 100644 --- a/.launchpad.yaml +++ b/.launchpad.yaml @@ -14,6 +14,7 @@ jobs: ppa: canonical-ubuntu-qa/backport-pre-commit snaps: - name: yq + - name: tflint packages: - git - pre-commit diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 87d3323..574b10e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,10 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - id: check-yaml + - repo: https://github.com/antonbabenko/pre-commit-terraform + rev: v1.89.1 + hooks: + - id: terraform_tflint - repo: https://github.com/shellcheck-py/shellcheck-py rev: v0.9.0.5 hooks: diff --git a/terraform/local/locals.tf b/terraform/local/locals.tf new file mode 100644 index 0000000..d1e3ef9 --- /dev/null +++ b/terraform/local/locals.tf @@ -0,0 +1,19 @@ +##################################################### +##################################################### +# Local variable declarations +locals { + # Everything with XXX needs to be replaced by the dev using this. + hostname = "localhost" + https_proxy = "" + no_proxy = "" + storage_host_internal = "XXX" + storage_path_internal = "XXX" + stage_name = "devel" + base = "ubuntu@20.04" + releases = "focal jammy noble oracular plucky" + channel = "latest/edge" + # local_dir = "XXX" + local_dir = "/home/andersson123/.local/autopkgtest-cloud/" + # model_name = "XXX" + model_name = "dev-model" +} diff --git a/terraform/local/main.tf b/terraform/local/main.tf new file mode 100644 index 0000000..f1514c3 --- /dev/null +++ b/terraform/local/main.tf @@ -0,0 +1,338 @@ +##################################################### +##################################################### +# Application declarations + +##################################################### +# cloud worker applications +resource "juju_application" "autopkgtest_cloud_worker" { + name = "autopkgtest-cloud-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + units = 1 + constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M" + + config = { + # Everything with XXX needs to be replaced by the dev using this. + swift-password = file("${local.local_dir}/${local.stage_name}/swift_password") + releases = local.releases + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "XXX" + influxdb-username = "XXX" + influxdb-context = local.stage_name + swift-username = "XXX" + swift-region = "XXX" + swift-auth-url = "XXX" + swift-tenant = "XXX" + swift-auth-version = 3 + swift-project-domain-name = "XXX" + swift-project-name = "XXX" + swift-user-domain-name = "XXX" + nova-rcs = filebase64("${local.local_dir}/${local.stage_name}/novarcs.tar") + worker-tmp-cleanup-config = "D /tmp 1777 root root 30d" + worker-upstream-percentage = 33 + stable-release-percentage = 100 + worker-net-names = <<-EOT + default: net_stg-proposed-migration + EOT + worker-flavor-config = <<-EOT + default: autopkgtest + big: autopkgtest-big + EOT + mirror = "http://ftpmaster.internal/ubuntu" + worker-args = "ssh -s /CHECKOUTDIR//ssh-setup/nova -- --flavor $PACKAGESIZE --security-groups $SECGROUP --name adt-$RELEASE-$ARCHITECTURE-$PACKAGENAME-$TIMESTAMP-$HOSTNAME-$UUID --image adt/ubuntu-$RELEASE-$HOSTARCH-server --keyname testbed-/HOSTNAME/ --net-id=/NET_NAME/ -e TERM=linux -e 'http_proxy={{ http_proxy }}' -e 'https_proxy={{ https_proxy }}' -e 'no_proxy={{ no_proxy }}' --mirror=/MIRROR/" + worker-setup-command = "/AUTOPKGTEST_CLOUD_DIR//worker-config-production/setup-canonical.sh" + n-workers = <<-EOT + lcy02: + amd64: 1 # can add more dc's below as required + EOT + } +} + +resource "juju_application" "autopkgtest_lxd_worker" { + name = "autopkgtest-lxd-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + units = 1 + constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M" + config = { + releases = local.releases + worker-args = "lxd -r $LXD_REMOTE $LXD_REMOTE:autopkgtest/ubuntu/$RELEASE/$ARCHITECTURE" + worker-setup-command2 = "ln -s /dev/null /etc/systemd/system/bluetooth.service; printf \"http_proxy={{ http_proxy }}\nhttps_proxy={{ https_proxy }}\nno_proxy={{ no_proxy }}\n\" >> /etc/environment" + lxd-remotes = <<-EOT + armhf: + 10.44.83.56: 3 + EOT + } +} + +##################################################### +# web applications +resource "juju_application" "apache2" { + name = "apache2" + model = local.model_name + trust = true + charm { + name = "apache2" + channel = "latest/stable" + base = local.base + } + constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M" + units = 1 + config = { + enable_modules = "include cgi proxy proxy_http remoteip" + mpm_type = "prefork" + } +} + +resource "juju_application" "autopkgtest_web" { + name = "autopkgtest-web" + + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-web" + channel = local.channel + base = local.base + } + units = 0 + + config = { + hostname = local.hostname + allowed-requestor-teams = <<-EOT + autopkgtest-requestors + canonical-foundations + canonical-kernel-distro-team + canonical-partner-eng + canonical-security + canonical-server + canonical-ubuntu-qa + EOT + storage-url-internal = "https://${local.storage_host_internal}${local.storage_path_internal}" + influxdb-username = "stg_proposed_migration" + influxdb-context = "staging" + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "metrics" + github-secrets = file("${local.local_dir}/${local.stage_name}/github-secrets.json") + github-status-credentials = file("${local.local_dir}/${local.stage_name}/github-status-credentials.txt") + swift-web-credentials = file("${local.local_dir}/${local.stage_name}/swift-web-credentials.conf") + public-swift-creds = file("${local.local_dir}/${local.stage_name}/public-swift-creds") + external-web-requests-api-keys = file("${local.local_dir}/${local.stage_name}/external-web-requests-api-keys.json") + https-proxy = local.https_proxy + no-proxy = local.no_proxy + cookies = "S0 S1" + indexed-packages-fp = "/home/ubuntu/indexed-packages.json" + } +} + +##################################################### +# haproxy applications +resource "juju_application" "haproxy" { + name = "haproxy" + model = local.model_name + charm { + name = "haproxy" + base = local.base + revision = 79 + } + units = 1 + constraints = "arch=amd64 cores=2 mem=4098M" + config = { + default_options = "httplog, dontlognull, forwardfor" + services = <<-EOT + - service_name: https_service + service_host: "::" + service_port: 443 + crts: [DEFAULT] + service_options: + - acl path_results path_beg /swift/v1/ + - balance source + - cookie SRVNAME insert + - timeout client 240s + - timeout server 240s + - option httpchk HEAD / HTTP/1.0 + - http-request set-header X-Forwarded-Proto https + - http-request capture req.hdr(User-Agent) len 100 + - http-request replace-pathq ^/results/(.*) "${local.storage_path_internal}"/\1 + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - use_backend results_reverse_proxy if path_results + server_options: check inter 10000 rise 2 fall 5 maxconn 512 cookie S{i} + backends: + - backend_name: results_reverse_proxy + servers: [[swift, objectstorage.prodstack5.canonical.com, 443, [ssl, verify, required, ca-file /etc/ssl/certs/ca-certificates.crt]]] + - service_name: http_redirect_to_https + service_host: "::" + service_port: 80 + service_options: + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - "redirect scheme https code 301 if ! { ssl_fc }" + EOT + ssl_cert = "DEFAULT" + ssl_key = "" + } +} + +resource "juju_application" "autocert_haproxy" { + name = "autocert-haproxy" + model = local.model_name + charm { + name = "autocert" + channel = "latest/stable" + revision = 53 + } + units = 0 + config = { + autocert_host = "autocert.canonical.com" + cert_additional_names = "${local.hostname}=default" + cert_auth_pairs = file("${local.local_dir}/${local.stage_name}/cert_auth_pairs") + dir_certs = "/var/lib/haproxy" + dir_keys = "/var/lib/haproxy" + service_action = "reload" + service_name = "haproxy" + suffix_cert = ".pem" + suffix_chain = ".pem" + suffix_key = ".pem" + } +} + +##################################################### +# rabbitmq applications +resource "juju_application" "rabbitmq_server" { + name = "rabbitmq-server" + model = local.model_name + charm { + name = "rabbitmq-server" + } + units = 1 + expose {} + constraints = "arch=amd64 cores=2 mem=4098M" +} + + + +##################################################### +##################################################### +# Integration declarations + +##################################################### +# web unit integrations +resource "juju_integration" "apache2-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.apache2.name + endpoint = "apache-website" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "website" + } + lifecycle { + replace_triggered_by = [ + juju_application.apache2.name, + juju_application.apache2.model, + juju_application.apache2.constraints, + juju_application.apache2.placement, + juju_application.apache2.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +##################################################### +# rabbitmq integrations +resource "juju_integration" "rabbitmq-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +resource "juju_integration" "rabbitmq-autopkgtest-cloud-worker" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_cloud_worker.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_cloud_worker.name, + juju_application.autopkgtest_cloud_worker.model, + juju_application.autopkgtest_cloud_worker.constraints, + juju_application.autopkgtest_cloud_worker.placement, + juju_application.autopkgtest_cloud_worker.charm.name, + ] + } +} + +##################################################### +# Other integrations +resource "juju_integration" "haproxy-autocert-haproxy" { + model = local.model_name + application { + name = juju_application.haproxy.name + endpoint = "juju-info" + } + application { + name = juju_application.autocert_haproxy.name + endpoint = "juju-info" + } + lifecycle { + replace_triggered_by = [ + juju_application.haproxy.name, + juju_application.haproxy.model, + juju_application.haproxy.constraints, + juju_application.haproxy.placement, + juju_application.haproxy.charm.name, + juju_application.autocert_haproxy.name, + juju_application.autocert_haproxy.model, + juju_application.autocert_haproxy.constraints, + juju_application.autocert_haproxy.placement, + juju_application.autocert_haproxy.charm.name, + ] + } +} diff --git a/terraform/local/providers.tf b/terraform/local/providers.tf new file mode 100644 index 0000000..9747525 --- /dev/null +++ b/terraform/local/providers.tf @@ -0,0 +1,4 @@ +##################################################### +##################################################### +# Provider declaration +provider "juju" {} diff --git a/terraform/local/versions.tf b/terraform/local/versions.tf new file mode 100644 index 0000000..e1f982b --- /dev/null +++ b/terraform/local/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0" + required_providers { + juju = { + version = "0.15.0" + source = "juju/juju" + } + } +} diff --git a/terraform/prod/locals.tf b/terraform/prod/locals.tf new file mode 100644 index 0000000..2e4f831 --- /dev/null +++ b/terraform/prod/locals.tf @@ -0,0 +1,17 @@ +##################################################### +##################################################### +# Local variable declarations +locals { + hostname = "autopkgtest.ubuntu.com" + https_proxy = "http://squid.internal:3128" + no_proxy = "127.0.0.1,127.0.1.1,login.ubuntu.com,localhost,localdomain,novalocal,internal,archive.ubuntu.com,ports.ubuntu.com,security.ubuntu.com,ddebs.ubuntu.com,changelogs.ubuntu.com,keyserver.ubuntu.com,launchpadlibrarian.net,launchpadcontent.net,launchpad.net,10.24.0.0/24,keystone.ps5.canonical.com,objectstorage.prodstack5.canonical.com" + storage_host_internal = "objectstorage.prodstack5.canonical.com:443" + storage_path_internal = "/swift/v1/AUTH_0f9aae918d5b4744bf7b827671c86842" + stage_name = "production" + base = "ubuntu@20.04" + releases = "trusty xenial bionic focal jammy noble oracular plucky" + channel = "latest/stable" + # These values are for ps5 + local_dir = "/home/prod-proposed-migration-environment/.local/share/mojo/LOCAL/autopkgtest-cloud/" + model_name = "prod-proposed-migration-environment" +} diff --git a/terraform/prod/main.tf b/terraform/prod/main.tf new file mode 100644 index 0000000..68d0a52 --- /dev/null +++ b/terraform/prod/main.tf @@ -0,0 +1,401 @@ +##################################################### +##################################################### +# Application declarations + +##################################################### +# cloud worker applications +resource "juju_application" "autopkgtest_cloud_worker" { + name = "autopkgtest-cloud-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + storage_directives = { + tmp = "350G" + } + + units = 3 + # This is for testing deployment in environments with a smaller quota. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M root-disk-source=volume" + constraints = "arch=amd64 cores=8 mem=16384M root-disk=40960M root-disk-source=volume" + + config = { + swift-password = file("${local.local_dir}/${local.stage_name}/swift_password") + releases = local.releases + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "metrics" + influxdb-username = "prod_proposed_migration" + influxdb-context = local.stage_name + swift-username = "prod-proposed-migration-environment" + swift-region = "prodstack5" + swift-auth-url = "https://keystone.ps5.canonical.com:5000/v3" + swift-tenant = "prod-proposed-migration-environment_project" + swift-auth-version = "3" + swift-project-domain-name = "Default" + swift-project-name = "prod-proposed-migration-environment_project" + swift-user-domain-name = "Default" + nova-rcs = filebase64("${local.local_dir}/${local.stage_name}/novarcs.tar") + worker-tmp-cleanup-config = "D /tmp 1777 root root 30d" + worker-upstream-percentage = 33 + stable-release-percentage = 100 + worker-net-names = <<-EOT + default: net_prod-proposed-migration + bos03: + amd64: net_prod-proposed-migration-amd64 + ppc64el: net_prod-proposed-migration-ppc64el + s390x: net_prod-proposed-migration-s390x + EOT + worker-flavor-config = <<-EOT + default: autopkgtest + big: autopkgtest-big + bos03: + amd64: + default: builder-cpu2-ram4-disk20 + big: builder-cpu4-ram8-disk100 + ppc64el: + default: autopkgtest-ppc64el + big: autopkgtest-big-ppc64el + s390x: + default: autopkgtest-s390x + big: autopkgtest-big-s390x + EOT + mirror = "http://ftpmaster.internal/ubuntu" + worker-args = "ssh -s /CHECKOUTDIR//ssh-setup/nova -- --flavor $PACKAGESIZE --security-groups $SECGROUP --name adt-$RELEASE-$ARCHITECTURE-$PACKAGENAME-$TIMESTAMP-$HOSTNAME-$UUID --image adt/ubuntu-$RELEASE-$HOSTARCH-server --keyname testbed-/HOSTNAME/ --net-id=/NET_NAME/ -e TERM=linux -e 'http_proxy={{ http_proxy }}' -e 'https_proxy={{ https_proxy }}' -e 'no_proxy={{ no_proxy }}' --mirror=/MIRROR/" + worker-setup-command = "/AUTOPKGTEST_CLOUD_DIR//worker-config-production/setup-canonical.sh" + n-workers = <<-EOT + lcy02: + amd64: 10 + bos03: + amd64: 32 + arm64: 43 + ppc64el: 32 + s390x: 32 + EOT + } +} + +resource "juju_application" "autopkgtest_lxd_worker" { + name = "autopkgtest-lxd-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + storage_directives = { + tmp = "200G" + } + + units = 1 + # This is for test deployment in envs with small quotas. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M root-disk-source=volume" + constraints = "arch=amd64 cores=8 mem=16384M root-disk=40960M root-disk-source=volume" + config = { + releases = local.releases + worker-args = "lxd -r $LXD_REMOTE $LXD_REMOTE:autopkgtest/ubuntu/$RELEASE/$ARCHITECTURE" + worker-setup-command2 = "ln -s /dev/null /etc/systemd/system/bluetooth.service; printf \"http_proxy={{ http_proxy }}\nhttps_proxy={{ https_proxy }}\nno_proxy={{ no_proxy }}\n\" >> /etc/environment" + lxd-remotes = <<-EOT + armhf: + 10.145.243.201: 3 # lxd-armhf-bos03-01 @ ps6-ra2-arm64-n1 + 10.145.243.115: 3 # lxd-armhf-bos03-02 @ ps6-ra4-arm64-n1 + 10.145.243.202: 3 # lxd-armhf-bos03-03 @ ps6-rb1-arm64-n1 + 10.145.243.52: 3 # lxd-armhf-bos03-04 @ ps6-ra2-arm64-n1 + 10.145.243.234: 3 # lxd-armhf-bos03-05 @ ps6-rb1-arm64-n1 + 10.145.243.9: 3 # lxd-armhf-bos03-06 @ ps6-rb1-arm64-n1 + 10.145.243.36: 3 # lxd-armhf-bos03-07 @ ps6-ra2-arm64-n1 + 10.145.243.28: 3 # lxd-armhf-bos03-08 @ ps6-ra4-arm64-n1 + 10.145.243.254: 3 # lxd-armhf-bos03-09 @ ps6-ra2-arm64-n1 + 10.145.243.242: 3 # lxd-armhf-bos03-10 @ ps6-rb2-arm64-n1 + 10.145.243.171: 3 # lxd-armhf-bos03-11 @ ps6-ra4-arm64-n1 + 10.145.243.142: 3 # lxd-armhf-bos03-12 @ ps6-ra2-arm64-n1 + 10.145.243.188: 3 # lxd-armhf-bos03-13 @ ps6-ra2-arm64-n1 + 10.145.243.141: 3 # lxd-armhf-bos03-14 @ ps6-rb1-arm64-n1 + 10.145.243.158: 3 # lxd-armhf-bos03-15 @ ps6-ra2-arm64-n1 + 10.145.243.21: 3 # lxd-armhf-bos03-16 @ ps6-rb1-arm64-n1 + 10.145.243.227: 3 # lxd-armhf-bos03-17 @ ps6-ra1-arm64-n1 + 10.145.243.51: 3 # lxd-armhf-bos03-18 @ ps6-ra1-arm64-n1 + 10.145.243.149: 3 # lxd-armhf-bos03-19 @ ps6-ra3-arm64-n1 + 10.145.243.247: 3 # lxd-armhf-bos03-20 @ ps6-ra2-arm64-n1 + 10.145.243.85: 3 # lxd-armhf-bos03-21 @ ps6-ra4-arm64-n1 + 10.145.243.240: 3 # lxd-armhf-bos03-22 @ ps6-ra3-arm64-n1 + 10.145.243.27: 3 # lxd-armhf-bos03-23 @ ps6-ra2-arm64-n1 + 10.145.243.76: 3 # lxd-armhf-bos03-24 @ ps6-rb1-arm64-n1 + 10.145.243.16: 3 # lxd-armhf-bos03-25 @ ps6-ra1-arm64-n1 + 10.145.243.232: 3 # lxd-armhf-bos03-26 @ ps6-ra2-arm64-n1 + 10.145.243.229: 3 # lxd-armhf-bos03-27 @ ps6-ra3-arm64-n1 + 10.145.243.197: 3 # lxd-armhf-bos03-28 @ ps6-rb1-arm64-n1 + 10.145.243.184: 3 # lxd-armhf-bos03-29 @ ps6-ra1-arm64-n1 + 10.145.243.53: 3 # lxd-armhf-bos03-30 @ ps6-ra2-arm64-n1 + EOT + } +} + +##################################################### +# web applications +resource "juju_application" "apache2" { + name = "apache2" + model = local.model_name + trust = true + charm { + name = "apache2" + channel = "latest/stable" + base = local.base + } + # This is for test deployment in envs with small quotas. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M" + constraints = "arch=amd64 cores=2 mem=16384M root-disk=51200M" + units = 1 + config = { + enable_modules = "include cgi proxy proxy_http remoteip" + mpm_type = "prefork" + } +} + +resource "juju_application" "autopkgtest_web" { + name = "autopkgtest-web" + + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-web" + channel = local.channel + base = local.base + } + units = 0 + + config = { + hostname = local.hostname + allowed-requestor-teams = <<-EOT + autopkgtest-requestors + canonical-foundations + canonical-kernel-distro-team + canonical-partner-eng + canonical-security + canonical-server + canonical-ubuntu-qa + EOT + storage_host_internal = local.storage_host_internal + storage_path_internal = local.storage_path_internal + storage-url-internal = "https://${local.storage_host_internal}${local.storage_path_internal}" + influxdb-username = "prod_proposed_migration" + influxdb-context = "production" + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "metrics" + github-secrets = file("${local.local_dir}/${local.stage_name}/github-secrets.json") + github-status-credentials = file("${local.local_dir}/${local.stage_name}/github-status-credentials.txt") + swift-web-credentials = file("${local.local_dir}/${local.stage_name}/swift-web-credentials.conf") + public-swift-creds = file("${local.local_dir}/${local.stage_name}/public-swift-creds") + external-web-requests-api-keys = file("${local.local_dir}/${local.stage_name}/external-web-requests-api-keys.json") + https-proxy = local.https_proxy + no-proxy = local.no_proxy + cookies = "S0 S1" + indexed-packges-fp = "/home/ubuntu/indexed-packages.json" + } +} + +##################################################### +# haproxy applications +resource "juju_application" "haproxy" { + name = "haproxy" + model = local.model_name + charm { + name = "haproxy" + base = local.base + revision = 79 + } + # placement = juju_machine.haproxy_machine.machine_id + units = 1 + config = { + default_options = "httplog, dontlognull, forwardfor" + services = <<-EOT + - service_name: https_service + service_host: "::" + service_port: 443 + crts: [DEFAULT] + service_options: + - acl path_results path_beg /swift/v1/ + - balance source + - cookie SRVNAME insert + - timeout client 240s + - timeout server 240s + - option httpchk HEAD / HTTP/1.0 + - http-request set-header X-Forwarded-Proto https + - http-request capture req.hdr(User-Agent) len 100 + - http-request replace-pathq ^/results/(.*) "${local.storage_path_internal}"/\1 + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - use_backend results_reverse_proxy if path_results + server_options: check inter 10000 rise 2 fall 5 maxconn 512 cookie S{i} + backends: + - backend_name: results_reverse_proxy + servers: [[swift, objectstorage.prodstack5.canonical.com, 443, [ssl, verify, required, ca-file /etc/ssl/certs/ca-certificates.crt]]] + - service_name: http_redirect_to_https + service_host: "::" + service_port: 80 + service_options: + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - "redirect scheme https code 301 if ! { ssl_fc }" + EOT + ssl_cert = "DEFAULT" + ssl_key = "" + } +} + +resource "juju_application" "autocert_haproxy" { + name = "autocert-haproxy" + model = local.model_name + charm { + name = "autocert" + channel = "latest/stable" + revision = 53 + } + units = 0 + config = { + autocert_host = "autocert.canonical.com" + cert_additional_names = "${local.hostname}=default" + cert_auth_pairs = file("${local.local_dir}/${local.stage_name}/cert_auth_pairs") + dir_certs = "/var/lib/haproxy" + dir_keys = "/var/lib/haproxy" + service_action = "reload" + service_name = "haproxy" + suffix_cert = ".pem" + suffix_chain = ".pem" + suffix_key = ".pem" + } +} + +##################################################### +# rabbitmq applications +resource "juju_application" "rabbitmq_server" { + name = "rabbitmq-server" + model = local.model_name + charm { + name = "rabbitmq-server" + } + units = 1 + expose {} + constraints = "arch=amd64 mem=8192M root-disk-source=volume" +} + + + +##################################################### +##################################################### +# Integration declarations + +##################################################### +# web unit integrations +resource "juju_integration" "apache2-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.apache2.name + endpoint = "apache-website" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "website" + } + lifecycle { + replace_triggered_by = [ + juju_application.apache2.name, + juju_application.apache2.model, + juju_application.apache2.constraints, + juju_application.apache2.placement, + juju_application.apache2.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +##################################################### +# rabbitmq integrations +resource "juju_integration" "rabbitmq-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +resource "juju_integration" "rabbitmq-autopkgtest-cloud-worker" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_cloud_worker.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_cloud_worker.name, + juju_application.autopkgtest_cloud_worker.model, + juju_application.autopkgtest_cloud_worker.constraints, + juju_application.autopkgtest_cloud_worker.placement, + juju_application.autopkgtest_cloud_worker.charm.name, + ] + } +} + +##################################################### +# Other integrations +resource "juju_integration" "haproxy-autocert-haproxy" { + model = local.model_name + application { + name = juju_application.haproxy.name + endpoint = "juju-info" + } + application { + name = juju_application.autocert_haproxy.name + endpoint = "juju-info" + } + lifecycle { + replace_triggered_by = [ + juju_application.haproxy.name, + juju_application.haproxy.model, + juju_application.haproxy.constraints, + juju_application.haproxy.placement, + juju_application.haproxy.charm.name, + juju_application.autocert_haproxy.name, + juju_application.autocert_haproxy.model, + juju_application.autocert_haproxy.constraints, + juju_application.autocert_haproxy.placement, + juju_application.autocert_haproxy.charm.name, + ] + } +} diff --git a/terraform/prod/providers.tf b/terraform/prod/providers.tf new file mode 100644 index 0000000..9747525 --- /dev/null +++ b/terraform/prod/providers.tf @@ -0,0 +1,4 @@ +##################################################### +##################################################### +# Provider declaration +provider "juju" {} diff --git a/terraform/prod/versions.tf b/terraform/prod/versions.tf new file mode 100644 index 0000000..e1f982b --- /dev/null +++ b/terraform/prod/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0" + required_providers { + juju = { + version = "0.15.0" + source = "juju/juju" + } + } +} diff --git a/terraform/staging/locals.tf b/terraform/staging/locals.tf new file mode 100644 index 0000000..449b83c --- /dev/null +++ b/terraform/staging/locals.tf @@ -0,0 +1,17 @@ +##################################################### +##################################################### +# Local variable declarations +locals { + hostname = "autopkgtest.staging.ubuntu.com" + https_proxy = "http://squid.internal:3128" + no_proxy = "127.0.0.1,127.0.1.1,login.ubuntu.com,localhost,localdomain,novalocal,internal,archive.ubuntu.com,ports.ubuntu.com,security.ubuntu.com,ddebs.ubuntu.com,changelogs.ubuntu.com,keyserver.ubuntu.com,launchpadlibrarian.net,launchpadcontent.net,launchpad.net,10.24.0.0/24,keystone.ps5.canonical.com,objectstorage.prodstack5.canonical.com" + storage_host_internal = "objectstorage.prodstack5.canonical.com:443" + storage_path_internal = "/swift/v1/AUTH_cc509e38c54f4edebda2fd17557309bb" + stage_name = "staging" + base = "ubuntu@20.04" + releases = "focal jammy noble oracular plucky" + channel = "latest/edge" + # These values are for ps5 + local_dir = "/home/stg-proposed-migration-environment/.local/share/mojo/LOCAL/autopkgtest-cloud/" + model_name = "stg-proposed-migration-environment" +} diff --git a/terraform/staging/main.tf b/terraform/staging/main.tf new file mode 100644 index 0000000..385dc65 --- /dev/null +++ b/terraform/staging/main.tf @@ -0,0 +1,366 @@ +##################################################### +##################################################### +# Application declarations + +##################################################### +# cloud worker applications +resource "juju_application" "autopkgtest_cloud_worker" { + name = "autopkgtest-cloud-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + storage_directives = { + tmp = "200G" + } + + units = 1 + # This is for testing deployment in environments with a smaller quota. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M root-disk-source=volume" + constraints = "arch=amd64 cores=8 mem=16384M root-disk=40960M root-disk-source=volume" + + config = { + swift-password = file("${local.local_dir}/${local.stage_name}/swift_password") + releases = local.releases + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "metrics" + influxdb-username = "stg_proposed_migration" + influxdb-context = local.stage_name + swift-username = "stg-proposed-migration-environment" + swift-region = "prodstack5" + swift-auth-url = "https://keystone.ps5.canonical.com:5000/v3" + swift-tenant = "stg-proposed-migration-environment_project" + swift-auth-version = "3" + swift-project-domain-name = "Default" + swift-project-name = "stg-proposed-migration-environment_project" + swift-user-domain-name = "Default" + nova-rcs = filebase64("${local.local_dir}/${local.stage_name}/novarcs.tar") + worker-tmp-cleanup-config = "D /tmp 1777 root root 30d" + worker-upstream-percentage = 33 + stable-release-percentage = 100 + worker-net-names = <<-EOT + default: net_stg-proposed-migration + bos03: + ppc64el: net_stg-proposed-migration-ppc64el + s390x: net_stg-proposed-migration-s390x + EOT + worker-flavor-config = <<-EOT + default: stag-cpu2-ram4-disk20 + big: stag-cpu4-ram16-disk50 + bos03: + ppc64el: + default: builder-ppc64el-cpu2-ram4-disk20 + big: builder-ppc64el-cpu2-ram4-disk100 + s390x: + default: autopkgtest-s390x + big: autopkgtest-big-s390x + EOT + mirror = "http://ftpmaster.internal/ubuntu" + worker-args = "ssh -s /CHECKOUTDIR//ssh-setup/nova -- --flavor $PACKAGESIZE --security-groups $SECGROUP --name adt-$RELEASE-$ARCHITECTURE-$PACKAGENAME-$TIMESTAMP-$HOSTNAME-$UUID --image adt/ubuntu-$RELEASE-$HOSTARCH-server --keyname testbed-/HOSTNAME/ --net-id=/NET_NAME/ -e TERM=linux -e 'http_proxy={{ http_proxy }}' -e 'https_proxy={{ https_proxy }}' -e 'no_proxy={{ no_proxy }}' --mirror=/MIRROR/" + worker-setup-command = "/AUTOPKGTEST_CLOUD_DIR//worker-config-production/setup-canonical.sh" + n-workers = <<-EOT + lcy02: + amd64: 1 + bos03: + amd64: 1 + arm64: 1 + ppc64el: 1 + s390x: 1 + EOT + } +} + +resource "juju_application" "autopkgtest_lxd_worker" { + name = "autopkgtest-lxd-worker" + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-cloud-worker" + channel = local.channel + base = local.base + } + + storage_directives = { + tmp = "200G" + } + + units = 1 + # This is for test deployment in envs with small quotas. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M root-disk-source=volume" + constraints = "arch=amd64 cores=8 mem=16384M root-disk=40960M root-disk-source=volume" + config = { + releases = local.releases + worker-args = "lxd -r $LXD_REMOTE $LXD_REMOTE:autopkgtest/ubuntu/$RELEASE/$ARCHITECTURE" + worker-setup-command2 = "ln -s /dev/null /etc/systemd/system/bluetooth.service; printf \"http_proxy={{ http_proxy }}\nhttps_proxy={{ https_proxy }}\nno_proxy={{ no_proxy }}\n\" >> /etc/environment" + lxd-remotes = <<-EOT + armhf: + 10.44.83.56: 3 + EOT + } +} + +##################################################### +# web applications +resource "juju_application" "apache2" { + name = "apache2" + model = local.model_name + trust = true + charm { + name = "apache2" + channel = "latest/stable" + base = local.base + } + # This is for test deployment in envs with small quotas. + # constraints = "arch=amd64 cores=2 mem=4096M root-disk=20480M" + constraints = "arch=amd64 cores=2 mem=16384M root-disk=51200M" + units = 1 + config = { + enable_modules = "include cgi proxy proxy_http remoteip" + mpm_type = "prefork" + } +} + +resource "juju_application" "autopkgtest_web" { + name = "autopkgtest-web" + + model = local.model_name + + charm { + name = "ubuntu-release-autopkgtest-web" + channel = local.channel + base = local.base + } + units = 0 + + config = { + hostname = local.hostname + allowed-requestor-teams = <<-EOT + autopkgtest-requestors + canonical-foundations + canonical-kernel-distro-team + canonical-partner-eng + canonical-security + canonical-server + canonical-ubuntu-qa + EOT + storage-url-internal = "https://${local.storage_host_internal}${local.storage_path_internal}" + influxdb-username = "stg_proposed_migration" + influxdb-context = "staging" + influxdb-hostname = file("${local.local_dir}/${local.stage_name}/influx-hostname.txt") + influxdb-password = file("${local.local_dir}/${local.stage_name}/influx-password.txt") + influxdb-database = "metrics" + github-secrets = file("${local.local_dir}/${local.stage_name}/github-secrets.json") + github-status-credentials = file("${local.local_dir}/${local.stage_name}/github-status-credentials.txt") + swift-web-credentials = file("${local.local_dir}/${local.stage_name}/swift-web-credentials.conf") + public-swift-creds = file("${local.local_dir}/${local.stage_name}/public-swift-creds") + external-web-requests-api-keys = file("${local.local_dir}/${local.stage_name}/external-web-requests-api-keys.json") + https-proxy = local.https_proxy + no-proxy = local.no_proxy + cookies = "S0 S1" + indexed-packages-fp = "/home/ubuntu/indexed-packages.json" + } +} + +##################################################### +# haproxy applications +resource "juju_application" "haproxy" { + name = "haproxy" + model = local.model_name + charm { + name = "haproxy" + base = local.base + revision = 79 + } + # placement = juju_machine.haproxy_machine.machine_id + units = 1 + config = { + default_options = "httplog, dontlognull, forwardfor" + services = <<-EOT + - service_name: https_service + service_host: "::" + service_port: 443 + crts: [DEFAULT] + service_options: + - acl path_results path_beg /swift/v1/ + - balance source + - cookie SRVNAME insert + - timeout client 240s + - timeout server 240s + - option httpchk HEAD / HTTP/1.0 + - http-request set-header X-Forwarded-Proto https + - http-request capture req.hdr(User-Agent) len 100 + - http-request replace-pathq ^/results/(.*) "${local.storage_path_internal}"/\1 + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - use_backend results_reverse_proxy if path_results + server_options: check inter 10000 rise 2 fall 5 maxconn 512 cookie S{i} + backends: + - backend_name: results_reverse_proxy + servers: [[swift, objectstorage.prodstack5.canonical.com, 443, [ssl, verify, required, ca-file /etc/ssl/certs/ca-certificates.crt]]] + - service_name: http_redirect_to_https + service_host: "::" + service_port: 80 + service_options: + - "redirect prefix https://${local.hostname} code 301 unless { hdr(host) -i ${local.hostname} }" + - "redirect scheme https code 301 if ! { ssl_fc }" + EOT + ssl_cert = "DEFAULT" + ssl_key = "" + } +} + +resource "juju_application" "autocert_haproxy" { + name = "autocert-haproxy" + model = local.model_name + charm { + name = "autocert" + channel = "latest/stable" + revision = 53 + } + units = 0 + config = { + autocert_host = "autocert.canonical.com" + cert_additional_names = "${local.hostname}=default" + cert_auth_pairs = file("${local.local_dir}/${local.stage_name}/cert_auth_pairs") + dir_certs = "/var/lib/haproxy" + dir_keys = "/var/lib/haproxy" + service_action = "reload" + service_name = "haproxy" + suffix_cert = ".pem" + suffix_chain = ".pem" + suffix_key = ".pem" + } +} + +##################################################### +# rabbitmq applications +resource "juju_application" "rabbitmq_server" { + name = "rabbitmq-server" + model = local.model_name + charm { + name = "rabbitmq-server" + } + units = 1 + expose {} + constraints = "arch=amd64 mem=8192M root-disk-source=volume" +} + + + +##################################################### +##################################################### +# Integration declarations + +##################################################### +# web unit integrations +resource "juju_integration" "apache2-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.apache2.name + endpoint = "apache-website" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "website" + } + lifecycle { + replace_triggered_by = [ + juju_application.apache2.name, + juju_application.apache2.model, + juju_application.apache2.constraints, + juju_application.apache2.placement, + juju_application.apache2.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +##################################################### +# rabbitmq integrations +resource "juju_integration" "rabbitmq-autopkgtest-web" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_web.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_web.name, + juju_application.autopkgtest_web.model, + juju_application.autopkgtest_web.constraints, + juju_application.autopkgtest_web.placement, + juju_application.autopkgtest_web.charm.name, + ] + } +} + +resource "juju_integration" "rabbitmq-autopkgtest-cloud-worker" { + model = local.model_name + application { + name = juju_application.rabbitmq_server.name + endpoint = "amqp" + } + application { + name = juju_application.autopkgtest_cloud_worker.name + endpoint = "amqp" + } + lifecycle { + replace_triggered_by = [ + juju_application.rabbitmq_server.name, + juju_application.rabbitmq_server.model, + juju_application.rabbitmq_server.constraints, + juju_application.rabbitmq_server.placement, + juju_application.rabbitmq_server.charm.name, + juju_application.autopkgtest_cloud_worker.name, + juju_application.autopkgtest_cloud_worker.model, + juju_application.autopkgtest_cloud_worker.constraints, + juju_application.autopkgtest_cloud_worker.placement, + juju_application.autopkgtest_cloud_worker.charm.name, + ] + } +} + +##################################################### +# Other integrations +resource "juju_integration" "haproxy-autocert-haproxy" { + model = local.model_name + application { + name = juju_application.haproxy.name + endpoint = "juju-info" + } + application { + name = juju_application.autocert_haproxy.name + endpoint = "juju-info" + } + lifecycle { + replace_triggered_by = [ + juju_application.haproxy.name, + juju_application.haproxy.model, + juju_application.haproxy.constraints, + juju_application.haproxy.placement, + juju_application.haproxy.charm.name, + juju_application.autocert_haproxy.name, + juju_application.autocert_haproxy.model, + juju_application.autocert_haproxy.constraints, + juju_application.autocert_haproxy.placement, + juju_application.autocert_haproxy.charm.name, + ] + } +} diff --git a/terraform/staging/providers.tf b/terraform/staging/providers.tf new file mode 100644 index 0000000..9747525 --- /dev/null +++ b/terraform/staging/providers.tf @@ -0,0 +1,4 @@ +##################################################### +##################################################### +# Provider declaration +provider "juju" {} diff --git a/terraform/staging/versions.tf b/terraform/staging/versions.tf new file mode 100644 index 0000000..e1f982b --- /dev/null +++ b/terraform/staging/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.0" + required_providers { + juju = { + version = "0.15.0" + source = "juju/juju" + } + } +}
-- Mailing list: https://launchpad.net/~canonical-ubuntu-qa Post to : canonical-ubuntu-qa@lists.launchpad.net Unsubscribe : https://launchpad.net/~canonical-ubuntu-qa More help : https://help.launchpad.net/ListHelp