Jo deploy-stap hinget op in ynterne hostnamme wylst deselde opdracht fuortendaliks antwurdet fan jo laptop, en de client-build op beide masines is identyk. De job draait op in runner dy't troch GitHub host wurdt: in firtuele masine dy't foar krekt dy iene job yn 'e wolk fan GitHub makke is, sûnder rûte nei jo privee adresromte, sûnder resolver-ynskriuwing foar de ynterne sône en sûnder sertifikaat dat it privee endpoint akseptearje sil. Allinnich twa ûntwerpen passe by dy beheining, en gjin fan beide kin letter oansetten wurde sûnder de workflow opnij te bouwen. Kies der tusken foar de earste YAML-rigel, want letter ferhúzje kostet mear as de earste poging.

De kar is tusken in runner dy't pleatst wurdt dêr't it netwurk al einiget en in tunnel dy't krekt ien job libbet. Beide drage al jierren produksje-deploys, en se mislearje op ferskillende manieren.

Wêr't de grins eins leit

Alles wat jo op 'e laptop ynstallearje, stoppet by de laptop, en alles wat jo by in job ynstallearje, ferdwynt mei de runner. Der is gjin permaninte netwurk-namespace dêr't in client tusken runs oan fêst bliuwt, dus elke run begjint yn deselde ûnberikbere steat. Azure dokumintearret dizze grins foar aginten dy't troch Microsoft host wurde, dêr't VPN- en ExpressRoute-ferbiningen nei privee netwurken net stipe wurde, en runners dy't troch GitHub host wurde drage deselde foarm fan beheining yn stee fan in apart meganisme. Lês dit as in eigenskip fan it produkt, net as in defekt om om hinne te wurkjen.

Gjin inkele repository-ynstelling ferslappet dat. It label fan 'e job beslút hokker pool it wurk oppakt, en in host label betsjut in masine bûten jo perimeter foar de hiele run.

Privee berikberens moat dus komme fan eat dat jo besitte. In runner pleatst dêr't it netwurk al einiget, of in tunnel dy't ien job libbet. De rest fan it artikel giet oer it bewust beteljen foar ien fan dy beide, yn stee fan de rekken yn produksje te ûntdekken.

Beslis op basis fan runfrekwinsje, net fan fertroudheid

Brûk in eigen runner binnen de VPC of it kantoarnetwurk as deploys ferskate kearen deis binnenkomme, as de job mear as ien privee poarte rekket, of as in plattefoarmteam al patching en credential-rotatie docht. In job op dy masine lost en rûtet as elke oare host efter de firewall. It netwurkwurk bart ien kear, by de ynstallaasje, net by elke run.

Bou de tunnel binnen de job as tagong sporadysk is en jo gjin langlibbene agint wolle dy't in credential yn jo netwurk hâldt. De job wurdt foar in pear minuten syn eigen netwurkclient en lit neat efter, wat faak it hiele punt is.

Skat de kosten fan 'e tunnel foar't jo him kieze. Elke run betellet foar it materialisearjen fan it profyl, it starten fan 'e client, gereedheid en it ôfbrekken. In tunnel dy't omheech komt mar nea ferifiearre wurdt, makket in deploy dy't healwei mislearret en lit de privee steat efter yn in foarm dy't nimmen pland hie. De nije poging dêrnei is selden skjin, en de twadde mislearring wurdt meastentiids op 'e clientferzje skood.

It profyl sa skriuwe dat de stap net ôfbrekke kin

Hâld profylen en credentials bûten de repository en materialisearje se út secret yn 'e stap dy't se nedich hat. De folchoarder beslút oft de job oerlibbet: in triem makke ûnder sudo heart ta root, en de shell fan 'e stap sûnder foech kin dêr net mear yn skriuwe.

- name: Bring up OpenVPN
  run: |
    umask 077
    profile="$RUNNER_TEMP/client.ovpn"
    printf '%s\n' "$VPN_PROFILE" > "$profile"
    : > "$RUNNER_TEMP/openvpn.log"
    printf '%s\n' "$VPN_CREDENTIALS" > "$RUNNER_TEMP/credentials.txt"
    sudo openvpn --daemon openvpn-job \
      --config "$profile" \
      --auth-user-pass "$RUNNER_TEMP/credentials.txt" \
      --writepid "$RUNNER_TEMP/openvpn.pid" \
      --log "$RUNNER_TEMP/openvpn.log"

Beide details yn dat blok binne foar lettere stappen. Mei umask 077 lânet it profyl yn modus 0600 en heart it ta de runner-brûker, sudo kin it noch lêze, en de client skriuwt syn log yn in triem dy't de runner al hat, sadat de gereedheidslus dat log lêze kin sûnder in twadde sudo. --writepid registrearret de PID dêr't it ôfbrekken op rjochte is.

In profyl dat him mei in client-sertifikaat autentisearret, hat syn kaai nedich op deselde wize skreaun, en in static-challenge-profyl hat de byhearrende auth-modus nedich. Profylen dy't DNS-opsjes pushje hawwe openvpn-systemd-resolved nedich op Ubuntu en Debian, want it pushjen allinnich feroaret neat op in basisôfbylding.

Gereedheid is in probe, gjin pauze

In fêste sleep hâldt krekt oant de konsintrator stadich wurdt, en dan draait de deploy-stap foar't de rûte bestiet. De mislearring komt dan yn it deploy-ark nei foaren as in timeout nei de privee host, wat neat oer de tunnel seit.

- name: Await private endpoint
  run: |
    for attempt in $(seq 1 30); do
      if getent hosts private.example.internal > /dev/null && \
         timeout 3 bash -c 'exec 3<>/dev/tcp/private.example.internal/8443' 2>/dev/null; then
        echo "endpoint answered after $attempt attempts"
        exit 0
      fi
      sleep 2
    done
    grep -Ei 'error|verify|auth' "$RUNNER_TEMP/openvpn.log" | tail -40
    exit 1

De lus sjocht twa dingen om't elk fan beide de brutsen helte wêze kin. getent hosts bewissiget dat de pushte resolver foar dy namme antwurdet, en it iepenjen fan 'e socket bewissiget dat der wat op 'e poarte heart dy't de deploy brûke sil; in profyl mei allinnich in rûte hat it letterlike adres en de rigel getent fuortsmiten nedich.

As de lus ferrint, is it log it iennichste dat trije ferskillende flaters skiedt: in wegere sertifikaat, in ferkearde auth-modus en in rûte dy't nea oankaam. Filterje foar de tail hâldt dy útfier koart genôch om te lêzen wylst de job noch mislearret. Lês de earste flater yn stee fan 'e lêste rigel, want in client dy't him net autentisearje kin, werhellet himsels oant de lus opjout. ip -4 route show dev tun0 antwurdet de ienfâldiger fraach oft der oait in rûte pusht is, en it kostet ien rigel yn deselde lus.

Ôfbrekken en de fraach oer it artefakt

Slút de job ôf mei in stap dy't beskerme wurdt troch if: always() en dy't sudo kill "$(sudo cat "$RUNNER_TEMP/openvpn.pid")" útfiert en neat oars. Op in dielde eigen runner meitsje nea dea op prosesnamme: in oare job kin in client hawwe mei deselde binary en ferlykbere arguminten. De mislearring falt dan op 'e job dy't as twadde draaide, en syn log wiist nei in workflow dy't neat ferkeard die.

De beskerming is wichtich om't in mislearre deploy dochs in libbene tunnel efterlit. Sûnder always() wurdt de opromjestap oerslein krekt wannear't dy nedich is, en de folgjende run begjint tsjin in client dy't al ferbûn is.

Ien fraach bliuwt oer foar't jo ien fan beide ûntwerpen oannimme: hat de build-faze eins in privee rûte nedich? In deployment-agint dat al yn it netwurk sit, kin in goedkard artefakt helje, en dat hâldt gewoane builds fan it privee paad ôf. Minder jobs dy't in tunnel hâlde betsjut minder plakken dêr't in ferâldere rûte him ferskûlje kin.

Relatearre artikelen