1. 项目概述:Adobe Ops CLI,一个云原生基础设施的“瑞士军刀”

如果你和我一样,长期在AWS、Azure上管理着几十甚至上百个Kubernetes集群,每天在Terraform、Ansible、Helm和各种云服务商CLI之间反复横跳,那你一定懂那种“工具链臃肿”的痛苦。配置文件散落在各处,环境变量满天飞,新同事上手得看三天文档,一个简单的集群创建流程背后是十几个手动步骤。Adobe开源的Ops CLI,就是我在这片混沌中发现的“秩序之光”。它不是什么颠覆性的新工具,而是一个极其聪明的“胶水层”,用Python把Terraform、Ansible、SSH、云CLI乃至Vault这些工具无缝粘合在一起,通过一个统一的集群配置文件(YAML)和一条 ops 命令来驱动一切。简单说,它让你能用声明式的方式,去执行那些原本需要一堆脚本才能完成的、复杂的、多步骤的云基础设施操作。

它的核心价值在于“标准化”和“简化”。想象一下,你有一个标准的Kubernetes集群配置模版,里面定义了VPC、EKS、节点组、Helm Charts。过去,你需要先 terraform apply ,等资源创建完,再去拿kubeconfig,然后 helm install 。现在,你只需要一个 cluster.yaml 文件,然后运行 ops cluster.yaml terraform apply ops cluster.yaml helm apply ,剩下的编排、依赖管理、上下文切换,Ops CLI帮你搞定。它尤其适合需要管理多环境(开发、测试、生产)、多团队、多区域相似基础设施的场景,能极大降低维护成本和出错概率。

2. 核心设计哲学与架构拆解

2.1 为什么是“胶水”,而不是“轮子”?

Ops CLI的聪明之处在于它没有尝试重新发明Terraform或Ansible。相反,它承认这些工具在各自领域(IaC、配置管理)的权威性,并专注于解决它们之间的“间隙”问题。这个间隙包括:

  1. 环境上下文传递 :Terraform输出的资源ID(如EKS集群名、VPC ID)如何自动成为Ansible Playbook或Helm Chart的输入变量?
  2. 操作流程编排 :创建基础设施、配置系统、部署应用是一个有顺序的管道,如何避免手动执行每个步骤?
  3. 配置集中管理 :如何避免在Terraform的 .tfvars 、Ansible的 group_vars 、Helm的 values.yaml 中重复定义相同的值(如环境名、区域)?

Ops CLI的答案是: 一个中心化的、支持Jinja2模板的集群配置文件(cluster.yaml) 。这个文件是所有操作的唯一事实来源。它内部按插件(plugin)组织,每个插件对应一个工具或一类操作(如 terraform inventory helm )。插件可以读取文件中的配置,并利用Jinja2的强大能力,实现配置间的动态引用和派生。

2.2 配置驱动:解剖一个cluster.yaml文件

理解Ops CLI,最关键的就是看懂它的集群配置文件。它不是一个简单的键值对列表,而是一个分层的、模块化的声明。

# 示例:一个简化版的AWS EKS集群配置 (clusters/my-eks.yaml)
---
# 1. 全局变量与元数据
cluster_name: &cluster_name "my-eks-prod"
environment: &env "production"
aws_region: &region "us-west-2"
vpc_cidr: &vpc_cidr "10.0.0.0/16"

# 2. Terraform 配置块
terraform:
  - path: infrastructure/aws-eks  # Terraform模块所在路径
    name: aws-eks  # 给这个Terraform配置块起个名字,用于--path-name指定
    backend:
      s3:
        bucket: "my-company-tf-state-&{env}"
        key: "&{cluster_name}/terraform.tfstate"
        region: *region
        dynamodb_table: "terraform-locks"
    vars:  # 传递给Terraform的变量
      cluster_name: *cluster_name
      environment: *env
      region: *region
      vpc_cidr: *vpc_cidr
      node_groups:
        - name: managed-ng-spot
          instance_types: ["t3.large", "t3a.large"]
          min_size: 2
          desired_size: 3
          max_size: 6

# 3. 清单(Inventory)配置块 - 用于获取动态主机信息
inventory:
  - plugin: cns  # “Cloud Native Services”插件,主要对接AWS
    args:
      clusters:
        - region: *region
          boto_profile: "my-aws-profile"  # 对应 ~/.aws/credentials 中的profile
          names: [*cluster_name]  # 通过AWS Tag “cluster” 来筛选实例

# 4. Helm 配置块 (假设通过Ansible或自定义插件集成)
# Ops CLI本身不直接包含helm插件,但可以通过ansible playbook或扩展来实现。
# 常见做法是在terraform块中定义helm所需的kubeconfig输出,然后在后续步骤中使用。
# 或者,利用`ops ... run`命令在生成kubeconfig后调用helm。

# 5. 敏感信息管理 - 从Vault或AWS SSM读取
database:
  password: "{{ 'secret/data/myapp/&{env}/db' | vault_kv2(path='password') }}"
  # 或使用AWS SSM Parameter Store
  api_key: "{{ '/myapp/&{env}/api_key' | read_ssm(aws_profile='my-aws-profile') }}"

关键理解 :这个YAML文件首先被Jinja2引擎渲染。这意味着 &{cluster_name} {{ ... | vault_kv2(...) }} 这些语法会被替换成实际值。然后,不同的插件(如terraform插件)只读取自己关心的那部分配置(如 terraform: 下的内容),并转换为对应工具(terraform)的调用参数。

2.3 插件化架构:灵活性的源泉

Ops CLI的所有核心功能都通过插件实现。这包括:

  • Inventory插件 ( cns , azr ): 从AWS或Azure动态获取主机列表和元数据(IP、标签等),并缓存起来供 ssh play run sync 命令使用。
  • Terraform插件 : 处理Terraform模板的渲染(Jinja2)、初始化、计划、应用、状态管理等。
  • Ansible集成 : play run sync 命令本质上是构建了一个动态的Ansible Inventory(来源于inventory插件),然后调用 ansible-playbook ansible ansible-doc
  • SSH插件 : 基于缓存的inventory信息,提供智能的SSH连接,支持跳板机(Bastion)、隧道、代理,甚至与Balabit SCB或Teleport集成。

这种架构让Ops CLI非常易于扩展。如果你需要集成一个新的云服务商(如GCP),理论上只需要实现一个新的inventory插件。

3. 实战演练:从零搭建一个可管理的基础设施项目

让我们抛开理论,动手创建一个真实的项目结构,看看Ops CLI如何融入日常工作流。假设我们要管理一个基于AWS EKS的微服务应用。

3.1 项目初始化与环境准备

首先,确保你的本地环境已经就绪。

# 1. 安装Ops CLI(推荐使用虚拟环境)
python3 -m venv ~/.venv/ops-cli
source ~/.venv/ops-cli/bin/activate
pip install --upgrade pip
pip install ops-cli

# 验证安装
ops --help

# 2. 安装并配置后端工具
# Terraform (Ops CLI会调用它,需要它在PATH中)
# 从 https://www.terraform.io/downloads.html 下载并安装

# AWS CLI & 凭证配置(如果你管理AWS资源)
aws configure --profile my-company-prod
# 输入 Access Key, Secret Key, 默认区域等

# 3. 创建项目目录结构
mkdir -p my-eks-platform
cd my-eks-platform
mkdir -p clusters infrastructure/aws-eks ansible/playbooks

3.2 编写核心基础设施Terraform代码

Ops CLI不关心你的Terraform模块内部怎么写,它只负责调用和传递变量。但我们仍需编写标准的Terraform模块。

# infrastructure/aws-eks/variables.tf
variable "cluster_name" {
  description = "EKS集群名称"
  type        = string
}
variable "environment" { ... }
variable "vpc_cidr" { ... }
variable "node_groups" { ... }

# infrastructure/aws-eks/main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
  # 注意:backend配置会被Ops CLI根据cluster.yaml动态覆盖,这里可以留空或写一个默认值。
  # backend "s3" {}
}

provider "aws" {
  region = var.region
  profile = var.aws_profile # 可以通过Ops CLI传递
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"
  version = "~> 3.0"
  name = "${var.cluster_name}-vpc"
  cidr = var.vpc_cidr
  # ... 其他VPC配置
}

module "eks" {
  source = "terraform-aws-modules/eks/aws"
  version = "~> 19.0"
  cluster_name    = var.cluster_name
  cluster_version = "1.27"
  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets
  # ... 其他EKS配置
  node_groups = var.node_groups
}

# 输出kubeconfig,供后续部署使用
output "kubeconfig" {
  description = "用于连接EKS集群的kubeconfig"
  value       = module.eks.cluster_primary_security_group_id # 简化示例,实际应输出module.eks.cluster_auth_base64或通过data源生成
  sensitive   = true
}

3.3 创建Ops CLI的集群配置文件

这是连接一切的枢纽。

# clusters/production.yaml
---
# 定义锚点,便于多处引用
cluster_name: &cluster_name "myapp-eks-prod"
environment: &env "prod"
aws_region: &region "us-east-1"
aws_profile: &aws_profile "my-company-prod" # 对应本地 ~/.aws/credentials

# Terraform 配置
terraform:
  - path: infrastructure/aws-eks
    name: eks-core
    backend:
      s3:
        bucket: "mycompany-terraform-state-global"
        key: "eks/&{environment}/&{cluster_name}/terraform.tfstate"
        region: *region
        encrypt: true
        dynamodb_table: "terraform-state-lock"
    vars:
      cluster_name: *cluster_name
      environment: *env
      region: *region
      aws_profile: *aws_profile
      vpc_cidr: "10.10.0.0/16"
      node_groups:
        - name: app-nodes
          instance_types: ["m5.large"]
          min_size: 3
          desired_size: 3
          max_size: 10
          labels: { role: "app" }

# Inventory 配置:用于管理EKS的Worker Node(EC2)或后续添加的独立EC2服务
inventory:
  - plugin: cns
    args:
      clusters:
        - region: *region
          boto_profile: *aws_profile
          names: [*cluster_name] # 查找Tag:cluster=myapp-eks-prod的实例

# 定义一些全局变量,可在Jinja2模板或Ansible中引用
global_vars:
  app_name: "my-microservice"
  docker_image: "myregistry.com/&{app_name}:latest"
  # 从SSM读取数据库密码
  db_password: "{{ '/&{environment}/&{app_name}/database/password' | read_ssm(aws_profile=*aws_profile, region=*region) }}"

3.4 执行完整的生命周期操作

现在,一切就绪,我们可以用一行命令完成复杂操作。

# 1. 初始化并规划Terraform变更
# --path-name 指定使用哪个terraform配置块(如果文件中有多个)
ops clusters/production.yaml terraform --path-name eks-core plan

# 输出会显示Terraform的plan结果。Ops CLI会先渲染Jinja2模板(如果有),再调用terraform plan。
# 它自动处理了后端S3桶的配置和变量传递。

# 2. 应用变更,创建EKS集群
ops clusters/production.yaml terraform --path-name eks-core apply
# 输入 yes 确认

# 3. 集群创建后,查看所有被标记的EC2实例(EKS节点)
ops clusters/production.yaml inventory
# 输出一个表格,显示实例ID、私有IP、标签等。

# 4. SSH到某个节点(Ops CLI会自动通过Tag找到对应的实例和私钥)
# 假设我们标签了第一个节点为 `myapp-eks-prod-app-nodes-0`
ops clusters/production.yaml ssh myapp-eks-prod-app-nodes-0 -l ec2-user

# 5. 运行Ansible Playbook配置节点(例如,安装监控Agent)
# 首先,确保有对应的Ansible playbook
# ansible/playbooks/setup-node.yaml
ops clusters/production.yaml play ansible/playbooks/setup-node.yaml -- -u ec2-user --limit "tag:role=app"

# 6. 在多个节点上执行一次性命令
ops clusters/production.yaml run "sudo yum update -y kubelet" -- -u ec2-user --limit app-nodes

# 7. 同步配置文件
ops clusters/production.yaml sync ./local/configs/ app-nodes:/etc/myapp/ -l ec2-user

# 8. 销毁整个集群(谨慎!)
ops clusters/production.yaml terraform --path-name eks-core destroy

3.5 高级技巧:利用Jinja2实现配置模板化

这是Ops CLI的杀手级特性。你可以在Terraform的 .tf 文件中直接使用Jinja2语法,实现逻辑判断、循环和引用cluster.yaml中的变量。

# infrastructure/aws-eks/jinja-templates/security_groups.tf.j2
{% set sg_prefix = cluster_name ~ "-" ~ environment %}
resource "aws_security_group" "allow_app" {
  name        = "{{ sg_prefix }}-allow-app"
  description = "Allow app traffic for {{ cluster_name }}"
  vpc_id      = module.vpc.vpc_id

  {% for port in app_ports %}
  ingress {
    description = "App port {{ port }}"
    from_port   = {{ port }}
    to_port     = {{ port }}
    protocol    = "tcp"
    cidr_blocks = ["10.0.0.0/8"] # 引用VPC CIDR,需要提前定义或从变量来
  }
  {% endfor %}

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "{{ sg_prefix }}-allow-app"
    ManagedBy = "ops-cli"
  }
}

然后在 cluster.yaml 中定义 app_ports 变量,Ops CLI在运行 terraform 命令前,会自动渲染 .tf.j2 文件为标准的 .tf 文件。

4. 深入核心功能与避坑指南

4.1 Inventory系统的运作机制与缓存策略

inventory 命令是 ssh play run sync 的基础。它的工作原理是:

  1. 查询 :根据 cluster.yaml inventory 部分的配置,调用对应云厂商的API(如AWS的 describe_instances )。
  2. 过滤 :根据 --limit 参数和实例标签进行筛选。 --limit webapp 意味着只选择标签中包含“webapp”的实例。
  3. 缓存 :结果会被缓存到本地(默认位置在 ~/.ops-cli/cache/ ),有效期内(可配置)的后续命令直接读取缓存,速度极快。
  4. 格式化 :将实例信息转换为Ansible可识别的动态Inventory格式。

踩坑记录:缓存过期问题 默认缓存时间可能较长。如果你在AWS控制台手动启动或终止了实例,Ops CLI可能因为缓存而感知不到。这时必须用 --refresh-cache 参数强制刷新。

ops clusters/prod.yaml inventory --refresh-cache --limit webapp

在自动化流水线中,对于需要绝对最新信息的步骤,务必加上此参数。

4.2 SSH与隧道功能的灵活运用

Ops CLI的 ssh 命令远不止是连接服务器。

# 基础SSH:自动解析主机名,使用配置中或默认的密钥
ops clusters/prod.yaml ssh webapp-01

# 通过跳板机(Bastion)连接:如果你的集群在私有子网,需要在inventory插件或集群配置中定义bastion主机信息。
# 通常,这需要在.ssh/config或集群配置中预先设置ProxyJump。Ops CLI可以简化这个过程。

# 创建本地到远程的端口隧道(Port Forwarding):调试服务神器
# 将远程服务器(webapp-01)的8080端口映射到本地的9090端口
ops clusters/prod.yaml ssh --tunnel --local 9090 --remote 8080 webapp-01
# 现在,在浏览器访问 http://localhost:9090 就能访问远程服务了。

# 创建SOCKS代理:让所有流量通过某台服务器出去
ops clusters/prod.yaml ssh --proxy --local 1080 bastion-host
# 然后配置浏览器或curl使用 SOCKS5 代理 127.0.0.1:1080

重要提示:SCB与Teleport集成 在企业环境中,直接SSH可能被安全策略禁止,要求通过堡垒机(如Balabit SCB)或Teleport。Ops CLI原生支持。

  • SCB :在 cluster.yaml 中配置 scb: 部分,启用后,所有SSH相关操作都会自动通过SCB代理。使用 --noscb 可以临时禁用。
  • Teleport :在 inventory 配置中设置 teleport_enabled: true ,并配置 teleport: 块。Ops CLI会利用 tsh (Teleport客户端)进行认证和连接,实现无密钥、审计化的访问。

4.3 Ansible集成的最佳实践

play run sync 命令本质都是Ansible的包装器。理解它们如何构建Ansible命令至关重要。

# `ops ... play` 等价于 `ansible-playbook -i <dynamic_inventory> ...`
# `ops ... run` 等价于 `ansible all -i <dynamic_inventory> -m shell -a "..."`
# `ops ... sync` 等价于 `ansible all -i <dynamic_inventory> -m synchronize ...`

# 关键:如何传递额外的Ansible参数?
# 使用 `--` 分隔符,`--` 之后的所有参数都会原样传递给底层的ansible或ansible-playbook命令。
ops clusters/prod.yaml play site.yaml -- -e "app_version=2.0" --tags "deploy" --skip-tags "notify"
ops clusters/prod.yaml run "df -h" -- -u ec2-user --become

最佳实践 :将常用的Ansible参数预定义在 cluster.yaml .opsconfig.yaml 中。例如,在 cluster.yaml 里定义默认的SSH用户和sudo设置,避免每次命令行输入。

4.4 多环境管理与配置继承

这是Ops CLI在大型项目中发挥威力的地方。你可以通过目录结构和Jinja2的 include import 来实现配置的DRY(Don‘t Repeat Yourself)。

my-project/
├── clusters/
│   ├── base.yaml           # 所有环境的通用配置(VPC CIDR块,通用标签)
│   ├── development/
│   │   └── cluster.yaml    # 继承base,覆盖为开发环境值(小实例,单节点)
│   ├── staging/
│   │   └── cluster.yaml    # 继承base,覆盖为预发环境值
│   └── production/
│       └── cluster.yaml    # 继承base,覆盖为生产环境值(大实例,多可用区)
└── infrastructure/

production/cluster.yaml 可以这样写:

---
# 使用Jinja2导入并扩展基础配置
{% extends "../../clusters/base.yaml" %}

{% set environment = "production" %}
{% set cluster_name = "myapp-prod" %}
{% set node_group_size = 5 %}
{% set instance_type = "m5.xlarge" %}

# 覆盖base.yaml中的变量
terraform:
  ... # 复用base的配置结构,但覆盖vars中的值
  vars:
    <<: *base_terraform_vars # 假设base中定义了锚点
    node_groups:
      - name: app-nodes
        instance_types: [*instance_type]
        min_size: *node_group_size
        desired_size: *node_group_size
        max_size: 15

然后,针对不同环境的操作变得非常清晰:

ops clusters/development/cluster.yaml terraform plan
ops clusters/production/cluster.yaml terraform apply

4.5 秘密管理:安全地处理凭证

永远不要将密码、API密钥硬编码在 cluster.yaml 中。Ops CLI支持从HashiCorp Vault或AWS Systems Manager Parameter Store (SSM)动态拉取。

AWS SSM Parameter Store示例:

  1. 在AWS Console或CLI中存储秘密:
    aws ssm put-parameter \
      --name "/production/myapp/database/password" \
      --value "SuperSecret123!" \
      --type SecureString \
      --region us-east-1
    
  2. cluster.yaml 中引用:
    database:
      password: "{{ '/production/myapp/database/password' | read_ssm(aws_profile='my-profile', region='us-east-1') }}"
    
  3. 在Terraform或Ansible模板中使用:
    # Terraform .tf.j2 文件
    resource "aws_db_instance" "default" {
      password = "{{ database.password }}"
    }
    

安全警告 :确保执行 ops 命令的机器(或CI/CD Runner)的IAM角色/用户有权限读取相应的SSM参数或Vault路径。同时,敏感变量的输出(如Terraform output)应标记为 sensitive = true

5. 故障排除与效能提升

5.1 常见错误与解决方案

问题现象 可能原因 解决方案
ops ... inventory 返回空或错误 1. AWS凭证未配置或profile名错误。
2. 实例上没有正确的 cluster 标签。
3. 区域不匹配。
1. 检查 ~/.aws/credentials cluster.yaml 中的 boto_profile
2. 在AWS控制台确认实例的 Tag Key cluster Value 与配置中的 names 一致。
3. 确认配置的 region 与实例所在区域一致。
ops ... terraform plan 报Jinja2语法错误 cluster.yaml .tf.j2 文件中有语法错误。 仔细检查YAML缩进和Jinja2语法。可以先用 ops ... terraform template 命令只渲染模板,查看输出。
ops ... ssh 连接超时或权限被拒 1. 安全组未开放22端口。
2. 使用的SSH密钥对不正确。
3. 需要通过跳板机但未配置。
1. 检查实例安全组规则。
2. 确认本地 ~/.ssh/ 下有对应密钥,或通过 -i 指定(需在集群配置中支持)。
3. 检查网络架构,配置SSH ProxyCommand或使用 --proxy 参数。
ops ... play 执行Ansible失败 1. 目标主机不可达。
2. Ansible模块依赖缺失(如python)。
3. -- 分隔符使用错误,参数未传递给Ansible。
1. 先用 inventory ssh 测试连通性。
2. 在playbook中或通过 ops ... run 先安装Python。
3. 确保Ansible额外参数放在 -- 之后。
执行速度慢 1. Inventory缓存过期,每次重新查询云API。
2. 网络延迟高。
1. 对于不需要实时信息的操作,去掉 --refresh-cache
2. 考虑在离资源近的区域(如EC2实例内)运行Ops CLI。

5.2 性能调优与配置技巧

  1. 优化 .opsconfig.yaml :在项目根目录或家目录创建此文件,可以全局调整行为。

    # ~/.opsconfig.yaml 或 /project/.opsconfig.yaml
    inventory:
      cache_ttl: 300  # 将Inventory缓存时间从默认的30秒提高到5分钟,减少API调用
      parallel: true   # 并行获取多个区域的库存(如果配置了多区域)
    
    terraform:
      landscape: true  # 启用terraform-landscape美化`plan`输出,需额外安装
      auto_approve: false # 慎用!设置为true可在apply时跳过确认提示,用于自动化。
    
    ssh:
      connect_timeout: 10
      # 可以指定默认的SSH私钥路径
      private_key_path: ~/.ssh/my_company_key
    
  2. 利用Docker镜像保持环境一致 :在CI/CD流水线中,强烈建议使用官方Docker镜像 ghcr.io/adobe/ops-cli:latest 。这确保了所有运行器都有相同版本的 ops terraform aws-cli 等工具,避免了“在我机器上是好的”这类问题。

    # GitLab CI 示例
    deploy:
      image: ghcr.io/adobe/ops-cli:latest
      script:
        - ops clusters/$ENVIRONMENT/cluster.yaml terraform apply
    
  3. 编写可复用的脚本和Alias :将常用的复杂命令封装成Shell脚本或Shell Alias。

    # 在 ~/.bashrc 或项目根目录的 Makefile 中
    alias ops-plan='ops clusters/production.yaml terraform --path-name eks-core plan'
    alias ops-apply='ops clusters/production.yaml terraform --path-name eks-core apply'
    alias ops-ssh-web='ops clusters/production.yaml ssh --limit webapp'
    
    # 或者一个部署脚本 deploy.sh
    #!/bin/bash
    set -e  # 遇到错误即退出
    ENV=${1:-staging}
    echo "Deploying to $ENV..."
    ops clusters/$ENV/cluster.yaml terraform apply -auto-approve
    ops clusters/$ENV/cluster.yaml play deploy-app.yaml
    

5.3 与现有CI/CD流水线的集成

将Ops CLI集成到Jenkins、GitLab CI、GitHub Actions中,可以实现基础设施的GitOps。

GitHub Actions工作流示例 (.github/workflows/terraform-apply.yaml):

name: 'Terraform Apply on Production'

on:
  push:
    branches:
      - main
    paths:
      - 'clusters/production.yaml'
      - 'infrastructure/**'

jobs:
  terraform:
    runs-on: ubuntu-latest
    environment: production  # 使用GitHub Environments管理机密
    permissions:
      id-token: write  # 用于OIDC
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1

      - name: Run Ops CLI Plan
        run: |
          docker run --rm -v $(pwd):/workspace -w /workspace \
            -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
            ghcr.io/adobe/ops-cli:latest \
            clusters/production.yaml terraform --path-name eks-core plan -out=tfplan

      - name: Run Ops CLI Apply (Manual Approval)
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        run: |
          docker run --rm -v $(pwd):/workspace -w /workspace \
            -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
            ghcr.io/adobe/ops-cli:latest \
            clusters/production.yaml terraform --path-name eks-core apply tfplan

这个工作流实现了:代码推送触发、安全的AWS认证(OIDC)、基于Docker的一致环境、先Plan后Apply的流程。你可以根据需要添加人工审批步骤。

Ops CLI不是一个要取代你现有工具链的庞然大物,而是一个精巧的“指挥家”,让你手中的工具们能更好地协同演奏。它解决的是云原生时代基础设施管理中的“最后一公里”问题——操作体验的碎片化。通过将分散的配置和命令统一到一个接口下,它显著提升了效率,降低了认知负担,尤其适合需要标准化、规模化运维的团队。刚开始可能需要花点时间适应它的配置哲学,但一旦跑通,你会发现自己再也回不去那个到处切换终端、手动拼接命令的原始时代了。

更多推荐