Skip to content

Commit 16521cc

Browse files
author
mcdonnnj
committed
# Conflicts: # README.md # molecule/default/converge.yml # terraform/backend.tf # terraform/providers.tf # terraform/remote_states.tf # terraform/user.tf
2 parents 4435a21 + 8cc1712 commit 16521cc

File tree

10 files changed

+248
-44
lines changed

10 files changed

+248
-44
lines changed

.github/workflows/build.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ jobs:
170170
uses: mxschmitt/action-tmate@v3
171171
if: env.RUN_TMATE
172172
test:
173+
# TODO: Figure out a plan to test in all environments, not just dev-a.
174+
# See cisagov/skeleton-ansible-role-with-test-user#183 for more details.
175+
environment: dev-a
173176
name: >-
174177
test (${{ matrix.scenario }}) -
175178
${{ matrix.platform }}-${{ matrix.architecture }}
@@ -275,7 +278,12 @@ jobs:
275278
sudo apt-get install apparmor-utils
276279
sudo aa-disable /usr/sbin/unix_chkpwd
277280
if: ${{ startsWith(matrix.platform, 'fedora') }}
278-
- name: Run molecule tests
281+
- # This is an example of how to pass GHA secrets to Molecule
282+
# via an environment variable. See also
283+
# molecule/default/converge.yml in this repository.
284+
# env:
285+
# THIRD_PARTY_BUCKET: ${{ secrets.THIRD_PARTY_BUCKET }}
286+
name: Run molecule tests
279287
run: >-
280288
molecule test
281289
--platform-name ${{ matrix.platform }}-${{ matrix.architecture }}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ __pycache__
1010
## Terraform ##
1111
.terraform
1212
.terraform.lock.hcl
13+
*.tfconfig
14+
*.tfvars

README.md

+99-35
Original file line numberDiff line numberDiff line change
@@ -8,64 +8,128 @@ An Ansible role for installing
88

99
## Pre-requisites (Ignore Until the COOL Migration) ##
1010

11-
In order to execute the Molecule tests for this Ansible role in GitHub
12-
Actions, a build user must exist in AWS. The accompanying Terraform
13-
code will create the user with the appropriate name and
14-
permissions. This only needs to be run once per project, per AWS
15-
account. This user can also be used to run the Molecule tests on your
16-
local machine.
17-
18-
Before the build user can be created, you will need a profile in your
19-
AWS credentials file that allows you to read and write your remote
20-
Terraform state. (You almost certainly do not want to use local
21-
Terraform state for this long-lived build user.) If the build user is
22-
to be created in the CISA COOL environment, for example, then you will
23-
need the `cool-terraform-backend` profile.
24-
25-
The easiest way to set up the Terraform remote state profile is to
26-
make use of our
27-
[`aws-profile-sync`](https://github.com/cisagov/aws-profile-sync)
28-
utility. Follow the usage instructions in that repository before
29-
continuing with the next steps, and note that you will need to know
30-
where your team stores their remote profile data in order to use
11+
In order to execute the Molecule tests for this Ansible role in GitHub Actions,
12+
a test user must exist in AWS. The accompanying Terraform code will create the
13+
user with the appropriate name and permissions. This only needs to be run once
14+
per project, per AWS account. This user can also be used to run the Molecule
15+
tests on your local machine.
16+
17+
Before the test user can be created, you will need a profile in your AWS
18+
credentials file that allows you to read and write your remote Terraform state.
19+
(You almost certainly do not want to use local Terraform state for this
20+
long-lived test user.) If the test user is to be created in the CISA COOL
21+
environment, for example, then you will need the `cool-terraform-backend`
22+
profile.
23+
24+
The easiest way to set up the Terraform remote state profile is to make use of
25+
our [`aws-profile-sync`](https://github.com/cisagov/aws-profile-sync) utility.
26+
Follow the usage instructions in that repository before continuing with the next
27+
steps, and note that you will need to know where your team stores their remote
28+
profile data in order to use
3129
[`aws-profile-sync`](https://github.com/cisagov/aws-profile-sync).
3230

33-
To create the build user, follow these instructions:
31+
### Creating a test user ###
3432

35-
```console
36-
cd terraform
37-
terraform init --upgrade=true
38-
terraform apply
39-
```
33+
You will need to create a test user for each environment that you use. The
34+
following steps show how to create a test user for an environment named "dev".
35+
You will need to repeat this process for any additional environments.
36+
37+
1. Change into the `terraform` directory:
38+
39+
```console
40+
cd terraform
41+
```
42+
43+
1. Create a backend configuration file named `dev.tfconfig` containing the
44+
name of the bucket where "dev" environment Terraform state is stored - this file
45+
is required to initialize the Terraform backend in each environment:
46+
47+
```hcl
48+
bucket = "my-dev-terraform-state-bucket"
49+
```
50+
51+
1. Initialize the Terraform backend for the "dev" environment using your backend
52+
configuration file:
53+
54+
```console
55+
terraform init -backend-config=dev.tfconfig
56+
```
57+
58+
> [!NOTE]
59+
> When performing this step for additional environments (i.e. not your first
60+
> environment), use the `-reconfigure` flag:
61+
>
62+
> ```console
63+
> terraform init -backend-config=other-env.tfconfig -reconfigure
64+
> ```
65+
66+
1. Create a Terraform variables file named `dev.tfvars` containing all
67+
required variables (currently only `terraform_state_bucket`):
4068

41-
Once the user is created you will need to update the [repository's
42-
secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets)
43-
with the new encrypted environment variables. This should be done
44-
using the
69+
```hcl
70+
terraform_state_bucket = "my-dev-terraform-state-bucket"
71+
```
72+
73+
1. Create a Terraform workspace for the "dev" environment:
74+
75+
```console
76+
terraform workspace new dev
77+
```
78+
79+
1. Initialize and upgrade the Terraform workspace, then apply the configuration
80+
to create the test user in the "dev" environment:
81+
82+
```console
83+
terraform init -upgrade=true
84+
terraform apply -var-file=dev.tfvars
85+
```
86+
87+
Once the test user is created you will need to update the
88+
[repository's secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets)
89+
with the new encrypted environment variables. This should be done using the
4590
[`terraform-to-secrets`](https://github.com/cisagov/development-guide/tree/develop/project_setup#terraform-iam-credentials-to-github-secrets-)
46-
tool available in the [development
47-
guide](https://github.com/cisagov/development-guide). Instructions for
48-
how to use this tool can be found in the ["Terraform IAM Credentials
49-
to GitHub Secrets"
50-
section](https://github.com/cisagov/development-guide/tree/develop/project_setup#terraform-iam-credentials-to-github-secrets-).
91+
tool available in the
92+
[development guide](https://github.com/cisagov/development-guide). Instructions
93+
for how to use this tool can be found in the
94+
["Terraform IAM Credentials to GitHub Secrets" section](https://github.com/cisagov/development-guide/tree/develop/project_setup#terraform-iam-credentials-to-github-secrets-).
5195
of the Project Setup README.
5296

97+
<<<<<<< HEAD
5398
If you have appropriate permissions for the repository you can view
5499
existing secrets on the [appropriate
55100
page](https://github.com/cisagov/ansible-role-ncats-webd/settings/secrets) in
56101
the repository's settings.
102+
=======
103+
If you have appropriate permissions for the repository you can view existing
104+
secrets on the
105+
[appropriate page](https://github.com/cisagov/skeleton-ansible-role-with-test-user/settings/secrets)
106+
in the repository's settings.
107+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1
57108

58109
## Requirements ##
59110

60111
None.
61112

62113
## Role Variables ##
63114

115+
<<<<<<< HEAD
64116
| Variable | Description | Default | Required |
65117
|----------|-------------|---------|----------|
66118
| ncats\_webd\_install\_geoipupdate | Whether to install the MaxMind geoipupdate tool. | `false` | No |
67119
| ncats\_webd\_maxmind\_account\_id | The MaxMind account ID for access to a GeoIP2 database subscription. | n/a | Yes |
68120
| ncats\_webd\_maxmind\_license\_key | The MaxMind license key that provided access to a GeoIP2 database subscription. | n/a | Yes |
121+
=======
122+
None.
123+
124+
<!-- markdownlint-disable line-length -->
125+
<!--
126+
| Variable | Description | Default | Required |
127+
|----------|-------------|---------|----------|
128+
| skeleton_with_test_user_bucket_name | The name of the AWS S3 bucket where the third-party files are stored. | None | Yes |
129+
| skeleton_with_test_user_license_object_name | The name of the AWS S3 object that is the third-party license. | `closed_source_tool.license` | No |
130+
-->
131+
<!-- markdownlint-enable line-length -->
132+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1
69133

70134
## Dependencies ##
71135

molecule/default/converge.yml

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
- name: Converge
33
hosts: all
44
tasks:
5+
<<<<<<< HEAD
56
- name: Include ansible-role-ncats-webd
67
# We do prepend the name of the role to the role variables, but
78
# Molecule does its own role discovery with inconsistent naming.
@@ -11,3 +12,14 @@
1112
vars:
1213
ncats_webd_maxmind_account_id: "{{ lookup('aws_ssm', '/cyhy/core/geoip/account_id', region='us-east-1') }}"
1314
ncats_webd_maxmind_license_key: "{{ lookup('aws_ssm', '/cyhy/core/geoip/license_key', region='us-east-1') }}"
15+
=======
16+
- name: Include skeleton-ansible-role-with-test-user
17+
ansible.builtin.include_role:
18+
name: skeleton-ansible-role-with-test-user
19+
# This is an example of how to pass GHA secrets to Molecule via
20+
# an environment variable. See also the "Run molecule tests"
21+
# step from the .github/workflows/build.yml workflow in this
22+
# repository.
23+
# vars:
24+
# skeleton_with_test_user_bucket_name: "{{ lookup('env', 'THIRD_PARTY_BUCKET') }}"
25+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1

terraform/backend.tf

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
terraform {
22
backend "s3" {
3+
<<<<<<< HEAD
34
bucket = "ncats-terraform-state-storage"
5+
=======
6+
# Use a partial configuration to avoid hardcoding the bucket name. This
7+
# allows the bucket name to be set on a per-environment basis via the
8+
# -backend-config command line option or other methods. For details, see:
9+
# https://developer.hashicorp.com/terraform/language/backend#partial-configuration
10+
bucket = ""
11+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1
412
dynamodb_table = "terraform-state-lock"
513
encrypt = true
614
key = "ansible-role-ncats-webd/terraform.tfstate"

terraform/outputs.tf

+3-8
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,9 @@ output "access_key" {
44
sensitive = true
55
}
66

7-
output "production_role" {
8-
value = module.user.production_role
9-
description = "The IAM role that the CI user can assume to read SSM parameters in the production account."
10-
}
11-
12-
output "staging_role" {
13-
value = module.user.staging_role
14-
description = "The IAM role that the CI user can assume to read SSM parameters in the staging account."
7+
output "role" {
8+
value = module.user.role
9+
description = "The IAM role that the CI user can assume to read SSM parameters in the Images account."
1510
}
1611

1712
output "user" {

terraform/providers.tf

+44
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,47 @@ provider "aws" {
88
}
99
region = var.aws_region
1010
}
11+
<<<<<<< HEAD
12+
=======
13+
14+
# The provider used to create the role that can be assumed to do
15+
# everything the CI user needs to do in the Images account.
16+
provider "aws" {
17+
alias = "images_provisionaccount"
18+
assume_role {
19+
role_arn = data.terraform_remote_state.images.outputs.provisionaccount_role.arn
20+
session_name = local.caller_user_name
21+
}
22+
default_tags {
23+
tags = var.tags
24+
}
25+
region = var.aws_region
26+
}
27+
28+
# The provider used to create policies and roles that can read
29+
# parameters from AWS SSM Parameter Store in the Images account.
30+
provider "aws" {
31+
alias = "images_ssm"
32+
assume_role {
33+
role_arn = data.terraform_remote_state.images_ssm.outputs.provisionparameterstorereadroles_role.arn
34+
session_name = local.caller_user_name
35+
}
36+
default_tags {
37+
tags = var.tags
38+
}
39+
region = var.aws_region
40+
}
41+
42+
# The provider used to create the test user
43+
provider "aws" {
44+
alias = "users"
45+
assume_role {
46+
role_arn = data.terraform_remote_state.users.outputs.provisionaccount_role.arn
47+
session_name = local.caller_user_name
48+
}
49+
default_tags {
50+
tags = var.tags
51+
}
52+
region = var.aws_region
53+
}
54+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1

terraform/remote_states.tf

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# ------------------------------------------------------------------------------
2+
# Retrieve state data from a Terraform backend. This allows use of the
3+
# root-level outputs of one or more Terraform configurations as input
4+
# data for this configuration.
5+
# ------------------------------------------------------------------------------
6+
7+
data "terraform_remote_state" "images" {
8+
backend = "s3"
9+
10+
config = {
11+
bucket = var.terraform_state_bucket
12+
dynamodb_table = "terraform-state-lock"
13+
encrypt = true
14+
key = "cool-accounts/images.tfstate"
15+
profile = "cool-terraform-readstate"
16+
region = "us-east-1"
17+
}
18+
19+
workspace = terraform.workspace
20+
}
21+
22+
data "terraform_remote_state" "images_ssm" {
23+
backend = "s3"
24+
25+
config = {
26+
bucket = var.terraform_state_bucket
27+
dynamodb_table = "terraform-state-lock"
28+
encrypt = true
29+
key = "cool-images-parameterstore/terraform.tfstate"
30+
profile = "cool-terraform-readstate"
31+
region = "us-east-1"
32+
}
33+
34+
workspace = terraform.workspace
35+
}
36+
37+
data "terraform_remote_state" "users" {
38+
backend = "s3"
39+
40+
config = {
41+
bucket = var.terraform_state_bucket
42+
dynamodb_table = "terraform-state-lock"
43+
encrypt = true
44+
key = "cool-accounts/users.tfstate"
45+
profile = "cool-terraform-readstate"
46+
region = "us-east-1"
47+
}
48+
49+
workspace = terraform.workspace
50+
}

terraform/user.tf

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module "user" {
33
source = "github.com/cisagov/molecule-iam-user-tf-module"
44

55
providers = {
6+
<<<<<<< HEAD
67
aws = aws
78
aws.images-production-provisionaccount = aws
89
aws.images-staging-provisionaccount = aws
@@ -15,4 +16,13 @@ module "user" {
1516
"/cyhy/core/geoip/account_id",
1617
"/cyhy/core/geoip/license_key",
1718
]
19+
=======
20+
aws = aws.users
21+
aws.images-provisionaccount = aws.images_provisionaccount
22+
aws.images-ssm = aws.images_ssm
23+
}
24+
25+
entity = "skeleton-ansible-role-with-test-user"
26+
ssm_parameters = ["/example/parameter"]
27+
>>>>>>> 8cc1712a5cae219f786b8e03c4ff6941296f89c1
1828
}

terraform/variables.tf

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# ------------------------------------------------------------------------------
2+
# Required parameters
3+
#
4+
# You must provide a value for each of these parameters.
5+
# ------------------------------------------------------------------------------
6+
7+
variable "terraform_state_bucket" {
8+
description = "The name of the S3 bucket where Terraform state is stored."
9+
type = string
10+
}
11+
112
# ------------------------------------------------------------------------------
213
# Optional parameters
314
#

0 commit comments

Comments
 (0)