JAX DevOps, London 2018
https://steinim.github.io/slides/aws-terraform-workshop
cloud-config.yml
vars:
- name: AWS_DEFAULT_REGION
value: eu-central-1
- name: TF_VAR_env
value: prod
- name: TF_VAR_public_key
value: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzwGCC+nMTL6QIg+Z7SXtIXhiJJ5caa5tZkWQ1E6jDgHp7NqDAb21ZzjK3mGFlugF81h3OBF8uZPE5E+A0mRCB/pMzEMi/SBv0nvuPhijT81OeJxiF11Zxejc6gk8YiJIywQcYD3OcmmWvP2gK7MU1VIf3SQjHEROMaz+4uNJlC6QpDJfepxevQVJ4GVk7uq71NJjXV91gyT4/smOz5dP6tT7dYuP5Zn3lr5VN/BmHmtpklK9AWhwoIyRi+t97T1ihgiDvrmg7QSH9hIM+zKH2oxWi0RGV99t+ac6DV54ys4XD7OLAhHdlL7qV2G1TSIFqXXOaV98Cj2Mkxd2vJhhZ"
secret-vars:
- name: TF_VAR_db_root_password
key: app/helloworld/prod/db_root_password
pass
~/.password-store
├── AWS_ACCESS_KEY_ID
├── AWS_SECRET_ACCESS_KEY
├── hello
│ ├── prod
│ │ └── db_password.gpg
│ ├── test
│ └── db_password.gpg
├── nexus
│ └── users
│ ├── admin.gpg
│ └── deployment.gpg
├── ...
│ ├── maven
│ └── settings.xml.gpg
│ └── travis
│ └── buildserver.gpg
...
✗ pass show -c hello/test/db_password
┌────────────────────────────────────────────────────────────────────────────────────┐
│ Please enter the passphrase to unlock the secret key for the OpenPGP certificate: │
│ "Stein Inge Morisbak <stein.inge.morisbak@BEKK.no>" │
│ 2048-bit RSA key, ID 38380D80, │
│ created 2014-05-15 (main key ID 0CB573BF). │
│ │
│ │
│ Passphrase ***********____________________________________________________________ │
│ │
│ <OK> <Cancel> │
└────────────────────────────────────────────────────────────────────────────────────┘
✗ pass show -c hello/test/db_password
Copied hello/test/db_password to clipboard. Will clear in 45 seconds.
envchain
✗ envchain --set aws AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
aws.AWS_ACCESS_KEY_ID: AKIAXXXXXXXXXXXXXXXX
aws.AWS_SECRET_ACCESS_KEY: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
✗ envchain aws env | grep AWS_
AWS_ACCESS_KEY_ID=AKIAXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
✗ envchain aws terraform-wrapper apply
You are provisioning PROD. Type PROD to continue... PROD
Started terraform operation at: 2017-09-08 12:46:57.870942455 +0200 CEST m=+6.052644916
null_resource.upload_efs_backup_script: Refreshing state... (ID: 8456414560025152219)
aws_route53_record.environment_route53_record: Refreshing state... (ID: Z1FHZIDFG100FA_prod.cloud.nsb.no_CNAME)
aws_route53_record.environment_route53_record: Refreshing state... (ID: Z1FHZIDFG100FA_app1.cloud.nsb.no_CNAME)
aws_route53_record.environment_route53_record: Refreshing state... (ID: Z1FHZIDFG100FA_app1.prod.cloud.nsb.no_CNAME)
aws_security_group.app_security_group: Refreshing state... (ID: sg-5f731534)
aws_security_group.efs_backup_security_group: Refreshing state... (ID: sg-279d864c)
aws_route53_record.environment_route53_record: Refreshing state... (ID: Z1FHZIDFG100FA_cloud.nsb.no_A)
aws_security_group.efs_security_group: Refreshing state... (ID: sg-a43d30cf)
aws_iam_user.user: Refreshing state... (ID: nsbno-prod)
aws_iam_role.role: Refreshing state... (ID: prod-nsbno-s3-full-access)
aws_iam_policy.policy: Refreshing state... (ID: arn:aws:iam::635004941268:policy/AmazonS3FullAccess-ElasticBeanstalk-NSBNO-prod)
aws_security_group.db_sg: Refreshing state... (ID: sg-817214ea)
aws_efs_file_system.efs: Refreshing state... (ID: fs-985cb8c1)
...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
./infrastructure #1
./app-infrastructure... #2
./app1 #3
./app2
...
./appN
./infrastructure
./infrastructure
├── <environment>
│ ├── main.tf
│ └── vars.tf
└── modules
├── vpc
│ ├── main.tf
│ ├── outputs.tf
│ └── vars.tf
├── subnets
│ ├── main.tf
│ ├── outputs.tf
│ └── vars.tf
├── security-groups
│ ├── main.tf
│ └── vars.tf
├── instance
│ ├── main.tf
│ ├── outputs.tf
│ └── vars.tf
├── ...
./app-infrastructure
./app-infrastructure
└── modules
├── rds
│ ├── main.tf
│ ├── outputs.tf
│ └── vars.tf
└── security_groups
├── main.tf
├── outputs.tf
└── vars.tf
{./app1,./app2,...}
Easy to begin, Impossible to outgrow
eb create
eb deploy
eb terminate
./create.sh
#!/bin/bash
...
envchain aws eb create ${env}-helloworld \
--keyname ${env} \
--vpc.id ${vpc_id} \
--vpc.dbsubnets ${private_subnet_ids} \
--vpc.ec2subnets ${private_subnet_ids} \
--vpc.elbpublic \
--vpc.elbsubnets ${public_subnet_ids} \
--vpc.securitygroups ${security_group_ids} \
--instance_type t2.micro \
--platform java-8 \
--cname ${env}-helloworld \
--scale 2
...
Tutorial:
https://github.com/steinim/aws-terraform-workshop
Slides:
https://steinim.github.io/slides/aws-terraform-workshop
.<app1>
├──.ebextensions
| ├── 00-set-timezone.config
| ├── 03-secure-listener.config
| ├── 05-cw-logging.config
| └── ...
├── Procfile
├── create.sh
├── deploy.sh
├── terminate.sh
.ebextensions/00-set-timezone.config
commands:
link_Oslo:
command: "ln -sf /usr/share/zoneinfo/Europe/Oslo /etc/localtime"
.ebextensions/01-set-number-of-file-descriptors.config
files:
"/etc/security/limits.d/00-webapp.conf":
content: |
webapp soft nofile 65535
webapp hard nofile 65535
.ebextensions/03-securelistener.config
option_settings:
aws:elb:listener:443:
SSLCertificateId: arn:aws:acm:eu-central-1:635004941268:certificate/6502eb35-99a7-4004-8e47-a5a0ec194c6a
ListenerProtocol: HTTPS
InstancePort: 80
aws:elb:listener:80:
ListenerEnabled: false
aws:elasticbeanstalk:application:
Application Healthcheck URL: /health
.ebextensions/05-cw-logging.config
option_settings:
aws:elasticbeanstalk:cloudwatch:logs:
StreamLogs: true
DeleteOnTerminate: false
RetentionInDays: 7
Tutorial:
https://github.com/steinim/aws-terraform-workshop
Slides:
https://steinim.github.io/slides/aws-terraform-workshop