-
Notifications
You must be signed in to change notification settings - Fork 9
Release test for AWS IAM Postgres passwordless #192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dc1b2f8
900ca2e
fe76681
5a84216
4f60be5
772f18e
19a7d7e
4473130
0f5b8a9
e81d3fa
8f6ce5b
6639de4
bc92f8c
349ad9a
929385d
be9c385
56adf6b
7ef4799
78ee692
cbcdf17
f05f510
30901b7
be42204
fcc9bec
0a09d3c
bc26dc9
df2c413
24a895a
0e51754
33b6172
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,7 +100,22 @@ locals { | |
| redis_bootstrap_key_pathname = local.redis_bootstrap_key_pathname | ||
| redis_bootstrap_ca_pathname = local.redis_bootstrap_ca_pathname | ||
|
|
||
| # Database configuration for templates | ||
| Database = { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are we adding this |
||
| Passwordless = { | ||
| AWSUseInstanceProfile = var.database_passwordless_aws_use_iam | ||
| AWSRegion = var.database_passwordless_aws_region | ||
| } | ||
| } | ||
|
|
||
| database_azure_msi_auth_enabled = var.database_passwordless_azure_use_msi | ||
| database_aws_iam_auth_enabled = var.database_passwordless_aws_use_iam | ||
| database_aws_iam_region = var.database_passwordless_aws_region | ||
| database_host = var.database_host | ||
| database_name = var.database_name | ||
| admin_database_username = var.admin_database_username | ||
| admin_database_password = var.admin_database_password | ||
| database_iam_username = var.database_iam_username | ||
|
|
||
| proxy_ip = var.proxy_ip | ||
| proxy_port = var.proxy_port | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -183,4 +183,21 @@ mkdir -p $tfe_dir | |
|
|
||
| echo ${docker_compose} | base64 -d > $tfe_dir/compose.yaml | ||
|
|
||
| %{ if database_iam_username != null && database_iam_username != "" ~} | ||
| echo "[$(date +"%FT%T")] Setting up PostgreSQL IAM user" | tee -a $log_pathname | ||
| sudo apt-get update -qq && sudo apt-get install -y postgresql-client-16 >/dev/null 2>&1 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks a little fragile, what happens when we use pg 15 or 17 as in compatibility tests? |
||
| export PGPASSWORD="${admin_database_password}" | ||
| for i in $(seq 1 20); do | ||
| if psql -h "${database_host}" -U "${admin_database_username}" -d "${database_name}" -c "SELECT 1;" >/dev/null 2>&1; then | ||
| echo "DB connected on attempt $i" | tee -a $log_pathname | ||
| psql -h "${database_host}" -U "${admin_database_username}" -d "${database_name}" -c "DO \$\$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${database_iam_username}') THEN CREATE USER \"${database_iam_username}\" WITH LOGIN; GRANT rds_iam TO \"${database_iam_username}\"; GRANT CONNECT ON DATABASE \"${database_name}\" TO \"${database_iam_username}\"; GRANT USAGE, CREATE ON SCHEMA public TO \"${database_iam_username}\"; GRANT ALL ON ALL TABLES IN SCHEMA public TO \"${database_iam_username}\"; GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO \"${database_iam_username}\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO \"${database_iam_username}\"; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO \"${database_iam_username}\"; RAISE NOTICE 'IAM user created'; ELSE RAISE NOTICE 'IAM user exists'; END IF; END \$\$;" >/dev/null 2>&1 | ||
| echo "IAM user ${database_iam_username} ready" | tee -a $log_pathname | ||
|
Comment on lines
+193
to
+194
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this what we suggest to our clients as well? To give admin privileges to the IAM user on all schemas? The reason I ask - release tests should be similar in deployment to what we suggest our clients, if the privileges we suggest change some time in the future the test should break. Also, have we tried doing this via IAM roles and policies? If not, could we first try setting up that manually and if it works then incorporate it here? |
||
| break | ||
| else | ||
| echo "DB attempt $i/20 failed" | tee -a $log_pathname | ||
| sleep 10 | ||
| fi | ||
| done | ||
| %{ endif ~} | ||
|
|
||
| docker compose -f /etc/tfe/compose.yaml up -d | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -187,6 +187,95 @@ mkdir -p $tfe_dir | |
|
|
||
| echo ${docker_compose} | base64 -d > $tfe_dir/compose.yaml | ||
|
|
||
| %{ if database_aws_iam_auth_enabled ~} | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Setting up PostgreSQL IAM user" | tee -a $log_pathname | ||
|
|
||
| # Set AWS region for CLI commands | ||
| export AWS_DEFAULT_REGION="${database_aws_iam_region}" | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] AWS region set to: $AWS_DEFAULT_REGION" | tee -a $log_pathname | ||
|
|
||
| # Install PostgreSQL client for database operations | ||
| if command -v apt-get >/dev/null 2>&1; then | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Installing PostgreSQL client" | tee -a $log_pathname | ||
| apt-get update -qq | ||
| apt-get install -y postgresql-client-15 postgresql-client-common | ||
| elif command -v yum >/dev/null 2>&1; then | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Installing PostgreSQL client" | tee -a $log_pathname | ||
| yum update -y | ||
| yum install -y postgresql15 | ||
| fi | ||
|
|
||
| # Function to create PostgreSQL IAM user | ||
| create_postgres_iam_user() { | ||
| local db_endpoint="${database_host}" | ||
| local admin_user="${admin_database_username}" | ||
| local admin_password="${admin_database_password}" | ||
| local iam_user="${database_iam_username}" | ||
| local db_name="${database_name}" | ||
|
|
||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Creating PostgreSQL IAM user: $iam_user" | tee -a $log_pathname | ||
|
|
||
| # Wait for database to be ready | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Waiting for PostgreSQL database to be ready..." | tee -a $log_pathname | ||
| max_attempts=30 | ||
| attempt=0 | ||
|
|
||
| while [ $attempt -lt $max_attempts ]; do | ||
| if PGPASSWORD="$admin_password" psql -h "$db_endpoint" -U "$admin_user" -d "$db_name" -c 'SELECT 1;' >/dev/null 2>&1; then | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Database is ready!" | tee -a $log_pathname | ||
| break | ||
| fi | ||
| attempt=$((attempt + 1)) | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Waiting for PostgreSQL... (attempt $attempt/$max_attempts)" | tee -a $log_pathname | ||
| sleep 10 | ||
| done | ||
|
|
||
| if [ $attempt -ge $max_attempts ]; then | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] ERROR: Database not ready after $max_attempts attempts" | tee -a $log_pathname | ||
| return 1 | ||
| fi | ||
|
|
||
| # Create IAM user | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] Creating IAM user in PostgreSQL..." | tee -a $log_pathname | ||
| PGPASSWORD="$admin_password" psql -h "$db_endpoint" -U "$admin_user" -d "$db_name" -v ON_ERROR_STOP=1 << EOF | ||
| DO \$\$ | ||
| BEGIN | ||
| -- Check if user exists | ||
| IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '$iam_user') THEN | ||
| -- Create the IAM user | ||
| CREATE USER "$iam_user"; | ||
| -- Grant rds_iam role (this role exists automatically in RDS PostgreSQL with IAM auth enabled) | ||
| GRANT rds_iam TO "$iam_user"; | ||
| -- Grant necessary database permissions | ||
| GRANT CONNECT ON DATABASE "$db_name" TO "$iam_user"; | ||
| GRANT USAGE ON SCHEMA public TO "$iam_user"; | ||
| GRANT CREATE ON SCHEMA public TO "$iam_user"; | ||
| -- Grant table permissions | ||
| GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "$iam_user"; | ||
| GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "$iam_user"; | ||
| -- Grant default privileges for future objects | ||
| ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO "$iam_user"; | ||
| ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO "$iam_user"; | ||
| RAISE NOTICE 'Successfully created IAM user: $iam_user'; | ||
| ELSE | ||
| RAISE NOTICE 'IAM user already exists: $iam_user'; | ||
| END IF; | ||
|
Comment on lines
+240
to
+262
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the difference between the things we are doing here and in |
||
| END | ||
| \$\$; | ||
| EOF | ||
|
|
||
| if [ $? -eq 0 ]; then | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] PostgreSQL IAM user setup completed successfully" | tee -a $log_pathname | ||
| else | ||
| echo "[$(date +"%FT%T")] [Terraform Enterprise] ERROR: Failed to create PostgreSQL IAM user" | tee -a $log_pathname | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| # Create the IAM user before starting TFE | ||
| create_postgres_iam_user | ||
| %{ endif ~} | ||
|
|
||
| docker compose -f /etc/tfe/compose.yaml up -d | ||
|
|
||
| %{ if distribution == "rhel" && cloud != "google" ~} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can do it in a separate PR, but I am thinking the variables
database_passwordless_aws_regionands3_regionhave the same values. Does it makes sense to merge them into one?