【问题标题】:Referencing gitlab secrets in Terraform在 Terraform 中引用 gitlab 机密
【发布时间】:2019-04-18 04:50:00
【问题描述】:

我对 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
}

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}"
}

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 = ""
}

组织中现在需要创建 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"
}

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

然后管道将触发,当此 repo 合并到 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"
}
  1. 然后在 aws-s3-iam-combo.git main.tf 以某种方式从 gitlab 机密中读取 account1 的凭据。

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

有人可以帮忙吗?

【问题讨论】:

    标签: amazon-web-services tensorflow amazon-s3 gitlab


    【解决方案1】:

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

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

    这是一个例子:

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

    SECRET_1: my-secret-1
    SECRET_2: my-secret-2
    SECRET_3: my-secret-3
    

    然后,创建一个包含 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"
        }
    }
    

    在您的 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
    

    需要注意的是,原来的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"
            }
        }
    }
    

    然后您可以在 Terraform 资源等中使用 "${vars.gitlab_secrets["secret_1"]}" 访问这些值。

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

    【讨论】:

      猜你喜欢
      • 2019-06-27
      • 2022-01-23
      • 2023-02-22
      • 2019-05-31
      • 1970-01-01
      • 2020-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多