First version that works, or at least gets all the way through ansible config
This commit is contained in:
parent
17d579a6eb
commit
31b13dc09b
15 changed files with 302 additions and 71 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -9,3 +9,9 @@ terraform.tfstate*
|
|||
config.tf
|
||||
privkey
|
||||
pubkey
|
||||
.toolcheck
|
||||
.s3_iam_credentials
|
||||
.s3_id
|
||||
.s3_secret
|
||||
ansible/credentials
|
||||
ansible/mastodon_secrets.yaml
|
||||
|
|
13
Makefile
13
Makefile
|
@ -12,7 +12,10 @@ endef
|
|||
|
||||
default: terraform ansible
|
||||
|
||||
terraform ansible: config.mk
|
||||
ansible: config.mk .s3_iam_credentials
|
||||
@$(MAKE) -C $@
|
||||
|
||||
terraform: config.mk
|
||||
@$(MAKE) -C $@
|
||||
|
||||
ssh: config.mk
|
||||
|
@ -21,10 +24,16 @@ ssh: config.mk
|
|||
#ansible:
|
||||
# @$(MAKE) -C ansible
|
||||
|
||||
config.mk:
|
||||
config.mk: config.mk.in
|
||||
@ $(info $(CONFIG_MSG) )
|
||||
@ exit 1
|
||||
|
||||
.s3_iam_credentials: terraform/.s3_id terraform/.s3_secret
|
||||
cat $^ > $@
|
||||
|
||||
terraform/.s3_id terraform/.s3_secret: terraform
|
||||
|
||||
|
||||
clean:
|
||||
rm -f config.mk
|
||||
@$(MAKE) -C terraform clean
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
include ../config.mk
|
||||
include ../terraform/terraform.mk
|
||||
|
||||
# XXX parameterize
|
||||
AWS_REGION = us-west-2
|
||||
# I don't remember why I had this at all:
|
||||
#AWS_REGION = $(AWS_REGION)
|
||||
|
||||
SSH := ssh -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null -o ProxyCommand="sh -c \"aws --region $(AWS_REGION) ssm start-session --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p\"" -i ../terraform/privkey -l ubuntu
|
||||
|
||||
|
@ -21,7 +21,7 @@ inventory.yaml: inventory.tmpl.yaml sedline
|
|||
|
||||
SEDLINE =
|
||||
|
||||
sedline: terraform_sedline config_sedline
|
||||
sedline: terraform_sedline config_sedline s3_sedline
|
||||
|
||||
config_sedline: $(addprefix __sed_,$(shell grep '^[0-9A-Z_]' ../config.mk | awk '{print $$1}'))
|
||||
|
||||
|
@ -30,13 +30,10 @@ terraform_sedline: $(addprefix __sed_,$(shell grep '^[0-9A-Z_]' ../terraform/ter
|
|||
__sed_%:
|
||||
$(eval SEDLINE := $$(SEDLINE) -e 's/{{$*}}/$($*)/')
|
||||
|
||||
|
||||
|
||||
#
|
||||
#TF_OUTPUTS =
|
||||
#
|
||||
#tf_outputs: ../terraform/terraform.tfstate
|
||||
#
|
||||
# FIXME: this is awful because it's all in the clear
|
||||
s3_sedline:
|
||||
$(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_ID}}/$(shell head -1 ../.s3_iam_credentials)/')
|
||||
$(eval SEDLINE := $$(SEDLINE) -e 's/{{S3_IAM_SECRET}}/$(shell tail -1 ../.s3_iam_credentials)/')
|
||||
|
||||
# FIXME: DRY this target
|
||||
|
||||
|
@ -57,5 +54,6 @@ toolcheck:
|
|||
fi
|
||||
|
||||
@echo
|
||||
mkdir -p credentials/mastodon
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,24 @@ social:
|
|||
hostname: social
|
||||
vars:
|
||||
ansible_ssh_common_args: -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ProxyCommand="sh -c \"aws --region {{AWS_REGION}} ssm start-session --target %h --document-name AWS-StartSSHSession --parameters portNumber=%p\""
|
||||
public_ip: "{{PUBLIC_IP}}"
|
||||
alternate_domains: {{ALTERNATE_DOMAINS}}
|
||||
aws_region: {{AWS_REGION}}
|
||||
#db_password:
|
||||
domain_name: {{DOMAIN_NAME}}
|
||||
mastodon_sidekiq_count: {{MASTODON_SIDEKIQ_COUNT}}
|
||||
mastodon_sidekiq_threads: {{MASTODON_SIDEKIQ_THREADS}}
|
||||
public_ip: "{{PUBLIC_IP}}"
|
||||
s3_bucket_name: "{{S3_BUCKET_NAME}}"
|
||||
#s3_endpoint:
|
||||
s3_hostname: "s3.{{AWS_REGION}}.amazonaws.com"
|
||||
s3_iam_id: {{S3_IAM_ID}}
|
||||
s3_iam_secret: {{S3_IAM_SECRET}}
|
||||
#smtp_server:
|
||||
|
||||
otp_secret:
|
||||
secret_key_base:
|
||||
vapid_secrets:
|
||||
#vapid_private_key:
|
||||
#vapid_public_key:
|
||||
|
||||
|
||||
|
|
|
@ -7,22 +7,97 @@
|
|||
- docker-compose-v2
|
||||
- git
|
||||
|
||||
- name: Mastodon path
|
||||
- name: base path
|
||||
file:
|
||||
path: "/srv/mastodon"
|
||||
state: directory
|
||||
recurse: true
|
||||
|
||||
- name: mastodon source
|
||||
- name: source
|
||||
git:
|
||||
repo: "https://tea.entar.net/teh/mastodon.git"
|
||||
dest: /srv/mastodon/src
|
||||
|
||||
- name: mastodon docker-compose
|
||||
- name: docker-compose file
|
||||
template:
|
||||
src: templates/docker-compose.mastodon.yaml
|
||||
dest: /srv/mastodon/docker-compose.yaml
|
||||
register: compose
|
||||
|
||||
# add env file
|
||||
## generate a secrets file if we need one
|
||||
# FIXME: what's in the mastodon_secrets.yaml file should be in credential lookup like db_password is
|
||||
|
||||
- name: check mastodon secrets var file
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
stat:
|
||||
path: mastodon_secrets.yaml
|
||||
register: mastosecrets
|
||||
|
||||
- name: env file stub
|
||||
template:
|
||||
src: templates/env.production
|
||||
dest: /srv/mastodon/.env.production
|
||||
vars:
|
||||
db_password: "{{ lookup('ansible.builtin.password', 'credentials/mastodon/postgres', length=15) }}"
|
||||
alternate_domains: "mastodon_web"
|
||||
when: mastosecrets.stat.exists != true
|
||||
|
||||
- name: get SECRET_KEY_BASE
|
||||
shell: docker compose run --rm mastodon_web rake secret 2>/dev/null | tail -1
|
||||
args:
|
||||
chdir: /srv/mastodon
|
||||
register: skb
|
||||
when: mastosecrets.stat.exists != true
|
||||
|
||||
- name: get OTP_SECRET
|
||||
shell: docker compose run --rm mastodon_web rake secret 2>/dev/null | tail -1
|
||||
args:
|
||||
chdir: /srv/mastodon
|
||||
register: otp
|
||||
when: mastosecrets.stat.exists != true
|
||||
|
||||
- name: get vapid secrets
|
||||
command: docker compose run --rm mastodon_web rake mastodon:webpush:generate_vapid_key
|
||||
args:
|
||||
chdir: /srv/mastodon
|
||||
register: vapid
|
||||
when: mastosecrets.stat.exists != true
|
||||
|
||||
- name: create mastodon secrets file
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
template:
|
||||
src: templates/mastodon_secrets.yaml
|
||||
dest: mastodon_secrets.yaml
|
||||
when: mastosecrets.stat.exists != true
|
||||
|
||||
## now that we have a secrets file, read it in and make the env file again
|
||||
|
||||
- name: read env secret vars
|
||||
include_vars:
|
||||
file: mastodon_secrets.yaml
|
||||
|
||||
- name: env file
|
||||
template:
|
||||
src: templates/env.production
|
||||
dest: /srv/mastodon/.env.production
|
||||
vars:
|
||||
db_password: "{{ lookup('ansible.builtin.password', 'credentials/mastodon/postgres', length=15) }}"
|
||||
alternate_domains: "mastodon_web"
|
||||
register: envfile
|
||||
|
||||
## finally, let's launch mastodon
|
||||
|
||||
- name: launch mastodon
|
||||
command: docker compose up -d
|
||||
args:
|
||||
chdir: /srv/mastodon
|
||||
|
||||
- name: restart mastodon
|
||||
command: docker compose restart
|
||||
args:
|
||||
chdir: /srv/mastodon
|
||||
when: envfile.changed or compose.changed
|
||||
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ services:
|
|||
# - "thread_pool.write.queue_size=1000"
|
||||
# networks:
|
||||
# - mastodon
|
||||
# - nginx
|
||||
# #- nginx
|
||||
# healthcheck:
|
||||
# test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
|
||||
# volumes:
|
||||
|
@ -67,7 +67,7 @@ services:
|
|||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||
networks:
|
||||
- mastodon
|
||||
- nginx
|
||||
#- nginx
|
||||
healthcheck:
|
||||
# prettier-ignore
|
||||
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
|
||||
|
@ -78,7 +78,7 @@ services:
|
|||
- mastodon_redis
|
||||
# - es
|
||||
volumes:
|
||||
- ./public/system:/mastodon/public/system
|
||||
- ./src/public/system:/mastodon/public/system
|
||||
|
||||
mastodon_streaming:
|
||||
container_name: mastodon_streaming
|
||||
|
@ -91,7 +91,7 @@ services:
|
|||
command: node ./streaming
|
||||
networks:
|
||||
- mastodon
|
||||
- nginx
|
||||
#- nginx
|
||||
healthcheck:
|
||||
# prettier-ignore
|
||||
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
|
||||
|
@ -103,7 +103,7 @@ services:
|
|||
|
||||
{% for i in range(mastodon_sidekiq_count) %}
|
||||
mastodon_sidekiq_{{i}}:
|
||||
container_name: mastodon_sidekiq
|
||||
container_name: mastodon_sidekiq_{{i}}
|
||||
build: src
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.1
|
||||
restart: always
|
||||
|
@ -116,9 +116,9 @@ services:
|
|||
- mastodon_redis
|
||||
networks:
|
||||
- mastodon
|
||||
- nginx
|
||||
#- nginx
|
||||
volumes:
|
||||
- ./public/system:/mastodon/public/system
|
||||
- ./src/public/system:/mastodon/public/system
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
|
||||
|
||||
|
@ -150,7 +150,7 @@ services:
|
|||
command:
|
||||
"--statsd.mapping-config=/statsd-mapping.yaml"
|
||||
volumes:
|
||||
- ./statsd-mapping.yaml:/statsd-mapping.yaml
|
||||
- ./src/statsd-mapping.yaml:/statsd-mapping.yaml
|
||||
networks:
|
||||
- mastodon
|
||||
|
||||
|
|
87
ansible/roles/mastodon/templates/env.production
Normal file
87
ansible/roles/mastodon/templates/env.production
Normal file
|
@ -0,0 +1,87 @@
|
|||
# Note that this file accepts slightly different syntax depending on whether
|
||||
# you are using `docker-compose` or not. In particular, if you use
|
||||
# `docker-compose`, the value of each declared variable will be taken verbatim,
|
||||
# including surrounding quotes.
|
||||
# See: https://github.com/mastodon/mastodon/issues/16895
|
||||
|
||||
# Federation
|
||||
# ----------
|
||||
# This identifies your server and cannot be changed safely later
|
||||
# ----------
|
||||
LOCAL_DOMAIN={{domain_name}}
|
||||
ALTERNATE_DOMAINS={{alternate_domains}}
|
||||
|
||||
# Redis
|
||||
# -----
|
||||
REDIS_HOST=mastodon_redis
|
||||
REDIS_PORT=6379
|
||||
|
||||
# PostgreSQL
|
||||
# ----------
|
||||
DB_HOST=mastodon_db
|
||||
DB_USER=postgres
|
||||
DB_NAME=mastodon_production
|
||||
DB_PASS={{db_password}}
|
||||
DB_PORT=5432
|
||||
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD={{db_password}}
|
||||
POSTGRES_DB=mastodon_production
|
||||
|
||||
|
||||
## Elasticsearch (optional)
|
||||
## ------------------------
|
||||
#ES_ENABLED=true
|
||||
#ES_HOST=localhost
|
||||
#ES_PORT=9200
|
||||
## Authentication for ES (optional)
|
||||
#ES_USER=elastic
|
||||
#ES_PASS=password
|
||||
|
||||
# Secrets
|
||||
# -------
|
||||
# Make sure to use `rake secret` to generate secrets
|
||||
# -------
|
||||
SECRET_KEY_BASE={{secret_key_base}}
|
||||
OTP_SECRET={{otp_secret}}
|
||||
{{vapid_secrets}}
|
||||
|
||||
# Sending mail
|
||||
# ------------
|
||||
#SMTP_SERVER=#{#{smtp_server#}#}
|
||||
SMTP_PORT=25
|
||||
SMTP_FROM_ADDRESS=Mastodon <notifications@{{domain_name}}>
|
||||
SMTP_AUTH_METHOD=none
|
||||
SMTP_OPENSSL_VERIFY_MODE=none
|
||||
|
||||
## File storage (optional)
|
||||
## -----------------------
|
||||
# teh-entar-net-mastodon-media.us-southeast-1.linodeobjects.com
|
||||
S3_ENABLED=true
|
||||
S3_BUCKET={{s3_bucket_name}}
|
||||
AWS_ACCESS_KEY_ID={{s3_iam_id}}
|
||||
AWS_SECRET_ACCESS_KEY={{s3_iam_secret}}
|
||||
#S3_ALIAS_HOST=
|
||||
S3_REGION={{aws_region}}
|
||||
S3_PROTOCOL=https
|
||||
#S3_HOSTNAME=teh-entar-net-mastodon-media.us-southeast-1.linodeobjects.com
|
||||
S3_HOSTNAME={{s3_hostname}}
|
||||
#S3_ENDPOINT=#{#{s3_endpoint#}#}
|
||||
S3_OVERRIDE_PATH_STYLE=true
|
||||
|
||||
# IP and session retention
|
||||
# -----------------------
|
||||
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
|
||||
# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).
|
||||
# -----------------------
|
||||
IP_RETENTION_PERIOD=31556952
|
||||
SESSION_RETENTION_PERIOD=31556952
|
||||
|
||||
STATSD_ADDR=statsd:9125
|
||||
|
||||
ACTIVITY_API_ENABLED=false
|
||||
PEERS_API_ENABLED=false
|
||||
|
||||
RAILS_LOG_TO_STDOUT=enabled
|
||||
RAILS_LOG_LEVEL=info
|
||||
|
5
ansible/roles/mastodon/templates/mastodon_secrets.yaml
Normal file
5
ansible/roles/mastodon/templates/mastodon_secrets.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
secret_key_base: {{skb.stdout}}
|
||||
otp_secret: {{otp.stdout}}
|
||||
vapid_secrets: |
|
||||
{{vapid.stdout | indent(2)}}
|
|
@ -21,11 +21,16 @@ AWS_SINGLE_INSTANCE_TYPE = t4g.small
|
|||
# Paste (one-line!) the root SSH public key for the AWS instance, or leave blank to generate new private/public keys
|
||||
AWS_INSTANCE_PUBLIC_KEY =
|
||||
|
||||
# What is the DNS subdomain to be delegated for these services? Leave blank to skip.
|
||||
AWS_ROUTE53_ZONE =
|
||||
|
||||
|
||||
|
||||
|
||||
# What is the domain name that will be used for these services? Don't be silly and use the default in production
|
||||
DOMAIN_NAME = burn.social
|
||||
|
||||
# What alternate domains will this use? Leave blank for none.
|
||||
ALTERNATE_DOMAINS =
|
||||
|
||||
# TODO: more detailed sidekiq tuning per https://thomas-leister.de/en/scaling-up-mastodon/
|
||||
|
||||
# How many sidekiq containers should Mastodon have?
|
||||
|
|
|
@ -5,7 +5,7 @@ default: terraform
|
|||
|
||||
# I hate sed too and I am so sorry for what I'm about to do
|
||||
terraform: terraform-check *.tf
|
||||
terraform init
|
||||
terraform init || terraform init -upgrade
|
||||
terraform apply
|
||||
terraform output | sed \
|
||||
-e 's/\(.*\) = /\U\1 = /' \
|
||||
|
@ -15,7 +15,7 @@ terraform: terraform-check *.tf
|
|||
-e 's/ \+$$//' \
|
||||
> terraform.mk
|
||||
|
||||
terraform-check: toolcheck pubkey
|
||||
terraform-check: .toolcheck pubkey
|
||||
$(eval AWS_INSTANCE_PUBLIC_KEY := $(shell sed -e 's/\//\\\//g' pubkey))
|
||||
|
||||
|
||||
|
@ -38,7 +38,8 @@ __sed_%:
|
|||
|
||||
CHECK_TOOLS = terraform aws
|
||||
|
||||
toolcheck:
|
||||
# this relies on your credentials file, so that if you edit it, it will run again
|
||||
.toolcheck: ~/.aws/credentials
|
||||
@echo
|
||||
@echo "Checking applications..."
|
||||
@ FAIL=""; \
|
||||
|
@ -55,6 +56,11 @@ toolcheck:
|
|||
@echo
|
||||
@echo "Checking AWS configuration..."
|
||||
aws iam get-user
|
||||
touch .toolcheck
|
||||
|
||||
# ...but if you don't have a credentials file, that's ok, it just runs the check every time
|
||||
~/.aws/credentials:
|
||||
true
|
||||
|
||||
pubkey:
|
||||
if test -n "$(AWS_INSTANCE_PUBLIC_KEY)"; then \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
locals {
|
||||
public_key = "{{AWS_INSTANCE_PUBLIC_KEY}}"
|
||||
instance_type = "{{AWS_SINGLE_INSTANCE_TYPE}}"
|
||||
route53_zone = "{{AWS_ROUTE53_ZONE}}"
|
||||
aws_region = "{{AWS_REGION}}"
|
||||
domain_name = "{{DOMAIN_NAME}}"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,10 @@
|
|||
|
||||
|
||||
# [X] aws provider
|
||||
# [/] random pet
|
||||
# not needed w/o s3 bucket
|
||||
# [/] s3 bucket
|
||||
# [/] use pet name!
|
||||
# n/a
|
||||
# [X] vpc
|
||||
# [/] tls private key
|
||||
# [X] aws key pair
|
||||
# [/] aws key local file
|
||||
# [X] instance
|
||||
# [ ] "myip"
|
||||
# [X] sg
|
||||
# [X] EIP
|
||||
# [X] iam_instance_profile
|
||||
# [X] iam_role
|
||||
# [X] policydoc
|
||||
# [X] policy
|
||||
# [X] policy attachment
|
||||
# [X] iam policy data
|
||||
# [ ] route53 records
|
||||
# [/] adminpass for nextcloud
|
||||
# [ ] outputs:
|
||||
# [ ] instance ID
|
||||
# [ ] public IP
|
||||
# [ ] name servers
|
||||
# [ ] bucket
|
||||
# [ ] myip
|
||||
|
||||
|
||||
provider "aws" {
|
||||
region = local.aws_region
|
||||
}
|
||||
|
||||
#resource "random_pet" "name" ()
|
||||
resource "random_pet" "name" {}
|
||||
|
||||
module "vpc" {
|
||||
source = "terraform-aws-modules/vpc/aws"
|
||||
|
|
|
@ -6,10 +6,20 @@ output "public_ip" {
|
|||
value = aws_instance.social.public_ip
|
||||
}
|
||||
output "nameservers" {
|
||||
value = length(module.zone) == 0 ? "" : module.zone.0.route53_zone_name_servers
|
||||
#value = length(module.zone) == 0 ? "" : module.zone.0.route53_zone_name_servers
|
||||
value = module.zone.route53_zone_name_servers
|
||||
}
|
||||
output "s3_bucket_name" {
|
||||
value = module.s3_bucket.s3_bucket_id
|
||||
}
|
||||
#output "bucket" {
|
||||
#}
|
||||
#output "myip" {
|
||||
#}
|
||||
|
||||
#output "aws_route53_zone" {
|
||||
# value = local.route53_zone
|
||||
#}
|
||||
|
||||
output "aws_route53_nameservers" {
|
||||
value = module.zone.route53_zone_name_servers
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
|
||||
module "zone" {
|
||||
count = local.route53_zone == "" ? 0 : 1
|
||||
# count = local.route53_zone == "" ? 0 : 1
|
||||
|
||||
source = "terraform-aws-modules/route53/aws//modules/zones"
|
||||
version = "~> 2.0"
|
||||
|
||||
zones = {
|
||||
"${local.route53_zone}" = { comment = "${local.route53_zone}" }
|
||||
"${local.domain_name}" = { comment = "${local.domain_name}" }
|
||||
}
|
||||
}
|
||||
|
||||
module "records" {
|
||||
count = local.route53_zone == "" ? 0 : 1
|
||||
# count = local.route53_zone == "" ? 0 : 1
|
||||
|
||||
source = "terraform-aws-modules/route53/aws//modules/records"
|
||||
version = "~> 2.0"
|
||||
zone_name = keys(module.zone.0.route53_zone_zone_id)[0]
|
||||
#zone_name = keys(module.zone.0.route53_zone_zone_id)[0]
|
||||
zone_name = keys(module.zone.route53_zone_zone_id)[0]
|
||||
|
||||
records = [
|
||||
{
|
||||
|
|
42
terraform/s3.tf
Normal file
42
terraform/s3.tf
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
module "s3_bucket" {
|
||||
source = "terraform-aws-modules/s3-bucket/aws"
|
||||
|
||||
bucket = "mastodon-${random_pet.name.id}"
|
||||
# acl = "private"
|
||||
|
||||
versioning = {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
# server_side_encryption_configuration = {
|
||||
# rule = {
|
||||
# apply_server_side_encryption_by_default = {
|
||||
# sse_algorithm = "AES256"
|
||||
# }
|
||||
#
|
||||
# bucket_key_enabled = true
|
||||
# }
|
||||
# }
|
||||
|
||||
}
|
||||
|
||||
resource "aws_iam_access_key" "s3" {
|
||||
user = aws_iam_user.s3.name
|
||||
}
|
||||
|
||||
resource "aws_iam_user" "s3" {
|
||||
name = "mastodon-s3-${random_pet.name.id}"
|
||||
path = "/system/"
|
||||
}
|
||||
|
||||
resource "local_file" "s3_secret" {
|
||||
filename = ".s3_secret"
|
||||
content = "${aws_iam_access_key.s3.secret}\n"
|
||||
}
|
||||
|
||||
resource "local_file" "s3_id" {
|
||||
filename = ".s3_id"
|
||||
content = "${aws_iam_access_key.s3.id}\n"
|
||||
}
|
||||
|
Loading…
Reference in a new issue