2017-09-05 5 views
0

J'ai testé terraform (v.0.10) pour provisionner des instances EC2, des groupes de sécurité, des instances RDS, etc. dans AWS pour une entreprise.Can terraform peut-il utiliser un hachage variable ou une carte ou des cartes pour créer des entrées de données dans des fichiers .tf?

J'utilise une approche du module afin que ceux-ci peuvent être « sourced » pour chacun de mes environnements:

apps: 
    main.tf 
    app.tf 
    vars.tf 
sec_groups: 
    main.tf 
    sec_group.tf 
    vars.tf 
: 
: 

Pour chacun de mes environnements (non-prod, prod) Je suis l'approvisionnement de ces modules, et stocker l'état terraform dans un compartiment s3 distant - un compartiment par environnement.

Je fournis à chaque environnement les variables nécessaires comme subnet_cidrs, le nom de VPC etc etc et les environnements sont créés: VPC ont leurs sous-réseaux pertinents, qui contiennent les instances EC2 correspondantes ... tout bon! Mon défi vient lorsque je viens d'ajouter des groupes de sécurité (pour lesquels j'ai beaucoup de différents types d'environnements et d'instances EC2) avec leurs règles respectives. Alors que je pouvais créer la base de règles dans un fichier sec_group.tf approprié et ajouter les règles de sortie/entrée (chacune avec leur from_port, to_port, protocol, cidr_blocks ..) je me demandais si l'information pouvait être générée (json) hash de données? Je pense que cette hiérarchie globale de données pourrait être utilisée pour contenir les règles et pourrait être traitée pour rassembler des règles pertinentes pour chaque environnement et appliquer uniquement celles qui sont pertinentes à l'environnement actuel sur lequel 'terraform apply' est exécuté, être là 2 ou 200 règles. Quelque chose comme ceci:

non-prod-env: 
    ssh: 
    from_port: 22 
    to_port: 22 
    protocol: "tcp" 
    cidr_blocks: 
     - 10.1.1.1 
     - 10.2.2.2 
    : 
    : 
    smtp: 
    from_port: 25 
    to_port: 25 
    protocol: "tcp" 
    cidr_blocks: 
     - 100.1.1.1 
     - 100.2.2.2 
    : 
    : 
prod-env: 
    ssh: 
    from_port: 22 
    to_port: 22 
    protocol: "tcp" 
    cidr_blocks: 
     - 11.1.1.1 
     - 11.2.2.2 
    : 
    : 

Après avoir lu les différents types de vars (string, liste, carte) Je ne sais pas si ce que je vous demande est encore possible, mais elle permettrait un système centralisé (global) source de des données que tous les environnements pourraient tirer.

Je serais intéressé de savoir si quelqu'un a déjà examiné/étudié cette approche ou s'il existe une approche beaucoup plus simple que je pourrais manquer.

Des idées ou des commentaires seraient appréciés.

Vive

+0

Je pensais que je devrais expliquer plus derrière cette question - le raisonnement pour vouloir considérer l'utilisation d'un hachage (quelque part, un peu comment) est semblable à la façon dont vous pourriez employer hiera dans la marionnette: avoir un système de paires de valeurs qui pourraient être remplacées plus bas dans le hachage. Une fusion permettrait à une seule source de données de minimiser l'utilisation de la duplication variable. –

Répondre

1

Terraform ne supporte pas encore les cartes imbriquées (terraform#2114) mais vous pourriez être en mesure de lire votre fichier global JSON en utilisant un External Data Source.

Complètement une option ici, mais je suis arrivé à déterminer que les opérations logiques dépassent ce que HCL a été conçu pour faire et que les orchestrations plus complexes devraient plutôt mettre dans un fournisseur personnalisé. Un plan HCL devrait être explicite dans ce qu'il fait et ne pas en tirer autant de ressources externes.Voici comment j'abordé les règles du groupe LCA et de sécurité:

ACL:

Lorsque la network_ssh_access variable est une liste des blocs CIDR autorisés pour ce VPC

variable network_ssh_access { 
    type = "list" 
    default = [] 
} 

resource "aws_network_acl" "main" { 
    vpc_id = "${aws_vpc.main.id}" 
} 

resource "aws_network_acl_rule" "network_ssh_access" { 
    count   = "${length(var.network_ssh_access)}" 
    network_acl_id = "${aws_network_acl.main.id}" 
    rule_number = "${200 + count.index}" 
    egress   = false 
    protocol  = "tcp" 
    rule_action = "allow" 
    cidr_block  = "${element(var.network_ssh_access, count.index)}" 
    from_port  = 22 
    to_port  = 22 
} 

Groupe de sécurité: Lorsque la appname_ssh_access variable est une liste des blocs cidr autorisés pour l'application appelée "appname"

variable appname_ssh_access { 
    type = "list" 
    default = [] 
} 

resource "aws_security_group" "appname" { 
    name  = "appname" 
} 

resource "aws_security_group_rule" "allow_all" { 
    count   = "${length(var.appname_ssh_access)}" 
    type   = "ingress" 
    from_port  = 22 
    to_port   = 22 
    protocol  = "tcp" 
    cidr_blocks  = "${element(var.network_ssh_access, count.index)}" 
    security_group_id = "${aws_security_group.appname.id" 
} 

Vous répliqueriez alors t son modèle pour les ports restants et les protocoles (mail, http, https, etc).