在 Terraform 中引用 gitlab 秘密

qre*_*0ct 6 amazon-s3 amazon-web-services gitlab tensorflow

我对 Terraforms 和 gitlab CI 很陌生,我想用它来做一些事情。

我想使用 Terraform 创建 IAM 用户和 S3 存储桶。使用策略允许该 IAM 用户对此 S3 存储桶执行某些操作。将 IAM 用户的凭证保存在工件中。现在以上将是我的核心模块。

核心模块如下所示:

内容:aws-s3-iam-combo.git

(用于运行所有 Terraform 的 IAM 用户的凭据(例如admin-user)将存储在 gitlab 机密中。)

main.tf

resource "aws_s3_bucket" "bucket" {
  bucket = "${var.name}"
  acl = "private"
  force_destroy = "true"

  tags {
    environment = "${var.tag_environment}"
    team        = "${var.tag_team}"
  }

  policy =<<EOF
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "${aws_iam_user.s3.arn}"
      },
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::${var.name}",
        "arn:aws:s3:::${var.name}/*"
      ]
    }
  ]
}
EOF
}

resource "aws_iam_user" "s3" {
  name = "${var.name}-s3"
  force_destroy = "true"
}

resource "aws_iam_access_key" "s3" {
  user = "${aws_iam_user.s3.name}"
}

resource "aws_iam_user_policy" "s3_policy" {
  name = "${var.name}-policy-s3"
  user = "${aws_iam_user.s3.name}"
  policy =<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::${var.name}",
        "arn:aws:s3:::${var.name}/*"
      ]
    }
  ]
}
EOF
}
Run Code Online (Sandbox Code Playgroud)

outputs.tf

output "bucket" {
  value = "${aws_s3_bucket.bucket.bucket}"
}

output "bucket_id" {
  value = "${aws_s3_bucket.bucket.id}"
}

output "iam_access_key_id" {
  value = "${aws_iam_access_key.s3.id}"
}

output "iam_access_key_secret" {
  value = "${aws_iam_access_key.s3.secret}"
}
Run Code Online (Sandbox Code Playgroud)

variables.tf

variable "name" {
  type = "string"
}

variable "tag_team" {
  type = "string"
  default = ""
}

variable "tag_environment" {
  type = "string"
  default = ""
}

variable "versioning" {
  type = "string"
  default = false
}

variable "profile" {
  type = "string"
  default = ""
}
Run Code Online (Sandbox Code Playgroud)

组织中现在需要创建 S3 存储桶的任何人都需要创建一个新的存储库,其形式如下:

main.tf

module "aws-s3-john-doe" {
  source = "git::https://git@gitlab-address/terraform/aws-s3-iam-combo.git?ref=v0.0.1"
  name = "john-doe"
  tag_team = "my_team"
  tag_environment = "staging"
}
Run Code Online (Sandbox Code Playgroud)

gitlab-ci.yml

stages:
  - plan
  - apply

plan:
  image: hashicorp/terraform
  stage: plan
  script:
    - terraform init
    - terraform plan

apply:
  image: hashicorp/terraform
  stage: apply
  script:
    - terraform init
    - terraform apply
  when: manual
  only:
    - master
Run Code Online (Sandbox Code Playgroud)

然后管道将触发,当此存储库合并到 master 时,将创建资源(S3 和 IAM 用户),并且用户将拥有此 IAM 用户的凭证。

现在的问题是我们有多个AWS账户。因此,如果开发人员想要在某个帐户中创建 S3,则上述设置是不可能的,因为admin-user的信用信息位于 gitlab 机密中,仅适用于一个帐户。

现在我不明白如何实现我的上述要求。我有以下想法:(请建议是否有更好的方法来做到这一点)

  1. 在 gitlab 机密中为每个相关 AWS 账户设置多个不同的信用
  2. 获取用户输入,指定他们想要在其中创建资源的 AWS 账户作为变量。所以说:

main.tf

module "aws-s3-john-doe" {
  source = "git::https://git@gitlab-address/terraform/aws-s3-iam-combo.git?ref=v0.0.1"
  name = "john-doe"
  tag_team = "my_team"
  tag_environment = "staging"
  aws_account = "account1"
}
Run Code Online (Sandbox Code Playgroud)
  1. 然后在aws-s3-iam-combo.git 中以某种方式从 gitlab 机密中读取account1main.tf的信用信息。

现在我不知道如何实现上述目标,比如如何从 gitlab 读取所需的秘密变量等。

有人可以帮忙吗?

rfl*_*ume 3

你不久前问过这个问题,但也许我的想法仍然对其中一个或另一个有帮助......

您可以使用以下方法执行此操作envsubst(需要将 pkggettext安装在您的运行器上或用于运行管道的 Docker 映像中)。

这是一个例子:

首先,在项目设置中,将不同的用户帐户设置为环境变量(项目秘密:

SECRET_1: my-secret-1
SECRET_2: my-secret-2
SECRET_3: my-secret-3
Run Code Online (Sandbox Code Playgroud)

然后,创建一个包含 Terraform 变量的文件,我们将其命名为vars_template.tf

variable "gitlab_secrets" {
    description = "Variables from GitLab"
    type = "map"
    default = {
        secret_1 = "$SECRET_1"
        secret_2 = "$SECRET_2"
        secret_3 = "$SECRET_3"
    }
}
Run Code Online (Sandbox Code Playgroud)

在 CI 管道中,您现在可以配置以下内容:

plan:dev:
  stage: plan dev
  script:
    - envsubst < vars_template.tf > ./vars_envsubst.tf
    - rm vars_template.tf
    - terraform init
    - terraform plan -out "planfile_dev"
  artifacts:
    paths:
      - environments/dev/planfile_dev
      - environments/dev/vars_envsubst.tf

apply:dev:
  stage: apply dev
  script:
    - cd environments/dev
    - rm vars_template.tf
    - terraform init
    - terraform apply -input=false "planfile_dev"
  dependencies:
    - plan:dev
Run Code Online (Sandbox Code Playgroud)

需要注意的是,原始的vars_template.tf必须删除,否则 Terraform 会抛出该变量被多次定义的错误。您可以通过将模板文件存储在 Terraform 工作目录之外的目录中来规避此问题。但从 Terraform 状态中您可以看到变量值已正确替换:

"outputs": {
    "gitlab_secrets": {
        "sensitive": false,
        "type": "map",
        "value": {
            "secret_1": "my-secret-1",
            "secret_2": "my-secret-2",
            "secret_3": "my-secret-3"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

"${vars.gitlab_secrets["secret_1"]}"然后,您可以访问Terraform 资源等中的值。

更新:请注意,此方法会将机密存储在 Terraform 状态文件中,如果该文件存储在 S3 存储桶中以与 Terraform 协作,则这可能是一个潜在的安全问题。存储桶至少应该被加密。此外,建议使用 ACL 限制对文件的访问,例如,只有用户terraform才能访问它。当然,用户可以通过 Terraoform 揭露秘密outputs......