Skip to content
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

Fix AWS cloud formation template #2087

Merged
merged 1 commit into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions src/AzureIoTHub.Portal.sln
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{3CA1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}"
ProjectSection(SolutionItems) = preProject
..\templates\app_insights.bicep = ..\templates\app_insights.bicep
..\templates\app_service.bicep = ..\templates\app_service.bicep
..\templates\app_service_plan.bicep = ..\templates\app_service_plan.bicep
..\templates\azuredeploy.bicep = ..\templates\azuredeploy.bicep
..\templates\azuredeployUI.json = ..\templates\azuredeployUI.json
..\templates\blob_container.bicep = ..\templates\blob_container.bicep
..\templates\database.bicep = ..\templates\database.bicep
..\templates\dps.bicep = ..\templates\dps.bicep
..\templates\iothub.bicep = ..\templates\iothub.bicep
..\templates\iothub_eventhub_consumer_group.bicep = ..\templates\iothub_eventhub_consumer_group.bicep
..\templates\portal_without_lorawan.bicep = ..\templates\portal_without_lorawan.bicep
..\templates\portal_with_lorawan.bicep = ..\templates\portal_with_lorawan.bicep
..\templates\portal_with_lorawan_and_starter_kit.bicep = ..\templates\portal_with_lorawan_and_starter_kit.bicep
..\templates\storage.bicep = ..\templates\storage.bicep
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATES", "ISSUE_TEMPLATES", "{4B89F192-EA33-4121-9809-D99621C40F3B}"
ProjectSection(SolutionItems) = preProject
Expand Down Expand Up @@ -75,6 +59,29 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Postgres
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Tests.E2E", "AzureIoTHub.Portal.Tests.E2E\AzureIoTHub.Portal.Tests.E2E.csproj", "{9C5F753D-B9A3-4E7F-BFF3-37EB8BEBAB80}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "aws", "aws", "{AD6BE5D2-0FFB-4629-8DE1-67D9B4D39577}"
ProjectSection(SolutionItems) = preProject
..\templates\aws\awsdeploy.yml = ..\templates\aws\awsdeploy.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "azure", "azure", "{EB8B706B-11C0-4D53-B5DA-603A4C1668F9}"
ProjectSection(SolutionItems) = preProject
..\templates\app_insights.bicep = ..\templates\app_insights.bicep
..\templates\app_service.bicep = ..\templates\app_service.bicep
..\templates\app_service_plan.bicep = ..\templates\app_service_plan.bicep
..\templates\azuredeploy.bicep = ..\templates\azuredeploy.bicep
..\templates\azuredeployUI.json = ..\templates\azuredeployUI.json
..\templates\blob_container.bicep = ..\templates\blob_container.bicep
..\templates\database.bicep = ..\templates\database.bicep
..\templates\dps.bicep = ..\templates\dps.bicep
..\templates\iothub.bicep = ..\templates\iothub.bicep
..\templates\iothub_eventhub_consumer_group.bicep = ..\templates\iothub_eventhub_consumer_group.bicep
..\templates\portal_without_lorawan.bicep = ..\templates\portal_without_lorawan.bicep
..\templates\portal_with_lorawan.bicep = ..\templates\portal_with_lorawan.bicep
..\templates\portal_with_lorawan_and_starter_kit.bicep = ..\templates\portal_with_lorawan_and_starter_kit.bicep
..\templates\storage.bicep = ..\templates\storage.bicep
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -137,6 +144,8 @@ Global
{3CA153F4-1172-4AF5-B483-94200717AB5C} = {20EC2171-363D-4DDE-827F-F56D4FE9ADF3}
{3F7A2982-4F0B-45F9-9FCA-923D5A7A1511} = {20EC2171-363D-4DDE-827F-F56D4FE9ADF3}
{4B89F192-EA33-4121-9809-D99621C40F3B} = {3CA153F4-1172-4AF5-B483-94200717AB5C}
{AD6BE5D2-0FFB-4629-8DE1-67D9B4D39577} = {3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}
{EB8B706B-11C0-4D53-B5DA-603A4C1668F9} = {3F7A2982-4F0B-45F9-9FCA-923D5A7A1511}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E03F3EEB-7B2B-4849-A581-4150BF29EC2B}
Expand Down
144 changes: 98 additions & 46 deletions templates/aws/awsdeploy.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
AWSTemplateFormatVersion: 2010-09-09
Description: AWS S3 storage template | PostgreSQL database storage template | Application Runner template
Description: IoT Hub portal deployment template

Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Solution"
Parameters:
- UniqueSolutionPrefix
- Label:
default: "Amazon Web Services resources access"
Parameters:
- awsAccess
- awsAccessSecretkey
- Label:
default: "PostgreSQL"
Parameters:
- pgsqlAdminLogin
- pgsqlAdminPassword
- Label:
default: "Open ID"
Parameters:
- openIdApiClientId
- openIdClientId
- openIdAuthority
- openIdMetadataURL
- openIdScopeName
ParameterLabels:
ParameterLabel

Parameters:
UniqueSolutionPrefix:
Expand All @@ -10,22 +38,24 @@ Parameters:
ConstraintDescription: Should be less than 20 letters
AllowedPattern: '^[a-z]+$'
pgsqlAdminLogin:
Type: String
Description: PostgreSQL user
MinLength: '1'
MaxLength: '30'
Type: String
Description: PostgreSQL user
MinLength: '1'
MaxLength: '30'
pgsqlAdminPassword:
Type: String
NoEcho: 'true'
Description: PostgreSQL password
MinLength: '8'
MaxLength: '41'
Type: String
NoEcho: 'true'
Description: PostgreSQL password
MinLength: '8'
MaxLength: '41'
awsAccess:
Type: String
Description: AWS Access Sectet
Description: AWS Access Secret
NoEcho: 'true'
awsAccessSecretkey:
Type: String
Description: AWS Access Secret Key
NoEcho: 'true'
openIdApiClientId:
Type: String
Description: The Open ID API client ID for the B2C tenant
Expand All @@ -46,15 +76,6 @@ Parameters:
Type: String
Description: The Open ID Scope name
Default: iot_access
VPC:
Type: AWS::EC2::VPC::Id
Subnet1:
Type: AWS::EC2::Subnet::Id
Subnet2:
Type: AWS::EC2::Subnet::Id
Subnet3:
Type: AWS::EC2::Subnet::Id


Resources:
#======== S3 Storage ==========
Expand All @@ -71,15 +92,35 @@ Resources:
Rules:
- ObjectOwnership: BucketOwnerPreferred
AccessControl: AwsExecRead
#======== Virtual Private Cloud ==========
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
Subnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.0.0/27
AvailabilityZone: !Join [ "", [!Ref AWS::Region, "a"] ]
Subnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.0.32/27
AvailabilityZone: !Join [ "", [!Ref AWS::Region, "b"] ]

#======== PostgreSQL database ==========
PostgreSQLDB:
Type: AWS::RDS::DBInstance
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
DBInstanceIdentifier: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgdbinstance"] ]
DBInstanceIdentifier: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgdb"] ]
AllocatedStorage: '20'
DBInstanceClass: 'db.t2.micro' # A voir quel instance utilisé : https://instances.vantage.sh/rds/
DBInstanceClass: 'db.t2.micro'
Engine: postgres
EngineVersion: 12
LicenseModel: postgresql-license
Expand All @@ -89,6 +130,7 @@ Resources:
VPCSecurityGroups:
- !Ref PgSQLSecurityGroup
DBSubnetGroupName: !Ref PgSQLSubnetGroup

PgSQLSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
Expand All @@ -99,21 +141,21 @@ Resources:
FromPort: 5432
ToPort: 5432
CidrIp: 0.0.0.0/0

PgSQLSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupName: !Join [ "-", [!Ref UniqueSolutionPrefix, "pgSqlsubnetgroup"] ]
DBSubnetGroupDescription: Subnets available for the database
SubnetIds: # A voir le nombre de subnets qu'on veut dans le groupe
SubnetIds:
- !Ref Subnet1
- !Ref Subnet2
- !Ref Subnet3


#InstanceRoleArn
InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSAppRunner"] ]
RoleName: !Join [ "-", [!Ref UniqueSolutionPrefix, "AppRunner"] ]
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
Expand Down Expand Up @@ -191,47 +233,39 @@ Resources:
# AWS Secrets Manager
SMAWSKey:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSKey"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSKey"] ]
SecretString: !Sub '${awsAccess}'
SMAWSSecretKey:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSSecretKey"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "AWSSecretKey"] ]
SecretString: !Sub '${awsAccessSecretkey}'
SMPostgreConnection:
SMPostgreSQLConnectionString:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMPostgreConnection"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "PostgreSQLConnectionString"] ]
SecretString: !Join
- ""
- - 'Server='
- !GetAtt PostgreSQLDB.Endpoint.Address
- !Sub ';Database=${UniqueSolutionPrefix}_cgigeiotdemo;Port=5432;User Id=${pgsqlAdminLogin};Password=${pgsqlAdminPassword};Pooling=true;Connection Lifetime=0;Command Timeout=0;'
SMAWSStorageConnection:
SMS3StorageConnectionString:
Type: AWS::SecretsManager::Secret
DeletionPolicy: Retain # CloudFormation keeps the resource without deleting the resource or its contents when the resource is replaced
UpdateReplacePolicy: Retain # see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatereplacepolicy.html
Properties:
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "SMAWSStorageConnection"] ]
Name: !Join [ "-", [!Ref UniqueSolutionPrefix, "S3StorageConnectionString"] ]
SecretString: !Join
- ""
- - !Sub 'https://s3.${AWS::Region}.amazonaws.com/'
- !Ref UniqueSolutionPrefix
- '-bucket'


#============= App Runner - To Lunch the App ==============
#============= App Runner - To Launch the App ==============
AppRunnerService:
Type: AWS::AppRunner::Service
Properties:
ServiceName: !Join [ "-", [!Ref UniqueSolutionPrefix, "appRunner"] ]
ServiceName: !Join [ "-", [!Ref UniqueSolutionPrefix, "portal"] ]
InstanceConfiguration:
Cpu: 1 vCPU
Memory: 2 GB
Expand All @@ -243,6 +277,10 @@ Resources:
Timeout: 5
HealthyThreshold: 2
UnhealthyThreshold: 5
NetworkConfiguration:
EgressConfiguration:
EgressType: VPC
VpcConnectorArn: !Ref AppRunnerServiceVPCConnector
SourceConfiguration:
AutoDeploymentsEnabled: false
AuthenticationConfiguration:
Expand All @@ -256,10 +294,14 @@ Resources:
- Name: AWS__AccessSecret
Value: !Ref SMAWSSecretKey
- Name: PostgreSQL__ConnectionString
Value: !Ref SMPostgreConnection
Value: !Ref SMPostgreSQLConnectionString
- Name: AWS__S3Storage__ConnectionString
Value: !Ref SMAWSStorageConnection
Value: !Ref SMS3StorageConnectionString
RuntimeEnvironmentVariables:
- Name: AWS__Region
Value: !Ref AWS::Region
- Name: AWS__BucketName
Value: !Join [ "-", [!Ref UniqueSolutionPrefix, "bucket"] ]
- Name: OIDC__ApiClientId
Value: !Sub '${openIdApiClientId}'
- Name: OIDC__ClientId
Expand All @@ -276,6 +318,16 @@ Resources:
Value: IoT Portal DEMO - AWS
ImageIdentifier: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/iot-hub-portal:latest'
ImageRepositoryType: ECR

AppRunnerServiceVPCConnector:
Type: AWS::AppRunner::VpcConnector
Properties:
VpcConnectorName: !Join [ "-", [!Ref UniqueSolutionPrefix, "portal-vpc-connector"] ]
Subnets:
- !Ref Subnet1
- !Ref Subnet2
SecurityGroups:
- !Ref PgSQLSecurityGroup

#GreenGras role script
GreenGrasRole:
Expand Down